Skip to content

fix(cubeproxy): configure resolver for Redis hostnames#714

Open
zyl1121 wants to merge 1 commit into
TencentCloud:masterfrom
zyl1121:fix/cubeproxy-external-redis-resolver
Open

fix(cubeproxy): configure resolver for Redis hostnames#714
zyl1121 wants to merge 1 commit into
TencentCloud:masterfrom
zyl1121:fix/cubeproxy-external-redis-resolver

Conversation

@zyl1121

@zyl1121 zyl1121 commented Jul 2, 2026

Copy link
Copy Markdown
Contributor

Motivation

When CubeProxy connects to Redis by hostname, OpenResty Lua can fail with:

no resolver defined to resolve "<redis-hostname>"

NGINX/OpenResty requires an explicit resolver directive for Lua cosocket hostname resolution. Reading /etc/resolv.conf is not enough by itself, because nginx expects concrete resolver addresses in nginx.conf.

Following the review feedback, this PR keeps the fix focused on the resolver path itself. CubeProxy now derives a small nginx resolver include from the container runtime environment, instead of relying on a one-click-specific host-side resolver workaround or rendering the full nginx config inside the container.

What Changed

This PR makes CubeProxy prepare only the resolver include at container startup:

  • adds a dedicated conf/includes/resolver.inc include hook to CubeProxy/nginx.conf
  • updates CubeProxy/start.sh to:
    • read the effective Redis target from CUBE_PROXY_REDIS_IP or the mounted global.conf
    • discover usable IPv4 nameservers from the container's /etc/resolv.conf when Redis is configured by hostname
    • render resolver ... ipv6=off valid=30s; and resolver_timeout 5s; into resolver.inc
    • fail fast when Redis is configured by hostname but no usable IPv4 resolver can be derived
    • keep Redis IP literals on a no-op resolver include path
  • adds focused coverage for the new startup helper behavior in deploy/one-click/tests/test_install_mode.sh

The one-click test update is limited to the existing path that supplies CubeProxy runtime config. This PR does not rework the broader one-click nginx rendering flow.

Validation

  • Ran the focused one-click shell test with bash tests/test_install_mode.sh.
  • Verified the CubeProxy startup helper across the relevant resolver branches:
    • hostname Redis renders resolver ...; resolver_timeout 5s;
    • IP-literal Redis keeps the resolver include as a no-op
    • hostname Redis without any usable IPv4 resolver fails fast with a clear error
  • Verified the one-click render path produces the expected hostname Redis runtime config.
  • Verified the container-side startup path in a temporary container: start.sh renders conf/includes/resolver.inc correctly and nginx -t succeeds.

Scope

This PR fixes Redis hostname resolution through CubeProxy's nginx/OpenResty resolver configuration.

It intentionally does not change:

  • CubeProxy's Lua Redis access logic
  • non-resolver CubeProxy routing behavior
  • the wider one-click nginx rendering flow

@zyl1121 zyl1121 force-pushed the fix/cubeproxy-external-redis-resolver branch from 50c0b7d to 77d4ae3 Compare July 2, 2026 11:51
Comment thread deploy/one-click/scripts/common/validation.sh Outdated
Comment thread deploy/one-click/scripts/common/validation.sh Outdated
Comment thread deploy/one-click/scripts/common/validation.sh Outdated
Comment thread deploy/one-click/scripts/common/validation.sh Outdated
Comment thread deploy/one-click/scripts/common/validation.sh Outdated
Comment thread deploy/one-click/scripts/common/validation.sh Outdated
Comment thread deploy/one-click/scripts/common/validation.sh Outdated
Comment thread deploy/one-click/scripts/common/validation.sh Outdated
@zyl1121 zyl1121 force-pushed the fix/cubeproxy-external-redis-resolver branch from 77d4ae3 to e2b7687 Compare July 2, 2026 12:26
Comment thread deploy/one-click/scripts/one-click/up-cube-proxy.sh Outdated
Comment thread deploy/one-click/scripts/common/validation.sh Outdated
Comment thread deploy/one-click/scripts/common/validation.sh Outdated
@fslongjin

Copy link
Copy Markdown
Member

Since CubeProxy is a container using the host network, I was wondering whether configuring the resolver inside this container to point to its own /etc/resolv.conf would solve the problem.

@zyl1121

zyl1121 commented Jul 3, 2026

Copy link
Copy Markdown
Contributor Author

Since CubeProxy is a container using the host network, I was wondering whether configuring the resolver inside this container to point to its own /etc/resolv.conf would solve the problem.

I do not think CubeProxy can rely on /etc/resolv.conf directly here.

For OpenResty cosocket hostname resolution, nginx still needs an explicit resolver directive with concrete nameserver addresses. It cannot point resolver at /etc/resolv.conf as a file path.

References:

So I think there are two viable ways to provide the resolver addresses:

  1. the current approach: discover nameservers during one-click rendering and write them into nginx.conf
  2. an alternative container-local approach: read the container's /etc/resolv.conf at startup, extract the nameserver IPs, and then render those IPs into nginx.conf

I kept the current one-click render-time approach because it is narrower and fails earlier/clearer when Redis is configured by hostname but no usable resolver can be found.

@fslongjin

Copy link
Copy Markdown
Member

Since CubeProxy is a container using the host network, I was wondering whether configuring the resolver inside this container to point to its own /etc/resolv.conf would solve the problem.

I do not think CubeProxy can rely on /etc/resolv.conf directly here.

For OpenResty cosocket hostname resolution, nginx still needs an explicit resolver directive with concrete nameserver addresses. It cannot point resolver at /etc/resolv.conf as a file path.

References:

So I think there are two viable ways to provide the resolver addresses:

  1. the current approach: discover nameservers during one-click rendering and write them into nginx.conf
  2. an alternative container-local approach: read the container's /etc/resolv.conf at startup, extract the nameserver IPs, and then render those IPs into nginx.conf

I kept the current one-click render-time approach because it is narrower and fails earlier/clearer when Redis is configured by hostname but no usable resolver can be found.

I consider it is better for the cube proxy to use the container's resolv.conf. because in production deployment, cube proxy usually runs on k8s, which do not use the one-click deploy.sh

@zyl1121

zyl1121 commented Jul 3, 2026

Copy link
Copy Markdown
Contributor Author

I consider it is better for the cube proxy to use the container's resolv.conf. because in production deployment, cube proxy usually runs on k8s, which do not use the one-click deploy.sh

That makes sense to me. I'll rework this PR toward the container-based approach.

@zyl1121 zyl1121 marked this pull request as draft July 3, 2026 12:00
@zyl1121 zyl1121 force-pushed the fix/cubeproxy-external-redis-resolver branch from 005058d to e2b7687 Compare July 3, 2026 12:07
@cubesandboxbot

cubesandboxbot Bot commented Jul 3, 2026

Copy link
Copy Markdown

Review: PR #714 — fix(cubeproxy): configure resolver for Redis hostnames

Overall: Well-structured PR with thorough test coverage. The resolver discovery logic is correctly scoped, input validation is strict (IPv4-only nameservers, atomic file writes), and error messages are actionable. A few areas for improvement below.


Inline Comments Posted

  1. resolver.inc L1 — Comment is slightly imprecise: the file is always regenerated, not just when Redis uses a hostname.
  2. start.sh L58discover_resolver_nameservers silently returns empty on a missing resolv.conf. A warning when the file is absent would help operators diagnose hostname resolution failures faster.
  3. start.sh L86–116resolve_redis_host and resolve_redis_host_source duplicate the same three-tier priority chain (env → global.conf → 127.0.0.1). A unified function returning both value and source would eliminate the maintenance trap.
  4. start.sh L124valid=30s is fine as a default but worth documenting as tunable for stable Redis backends.

Additional Observations

Code Quality:

  • The source-based test approach (source start.sh from subshells) works but is fragile — if a future change adds set -e or trap to start.sh, six+ tests will break silently.

Test Coverage:

  • Strong coverage of the resolver discovery flow, but several utility functions (read_redis_host_from_global_conf, resolve_redis_host, ipv6_literal_is_valid) lack direct unit tests.

Security:

  • No concerns. Input validation is thorough, file writes are atomic, resolver output is constrained to validated IPv4 addresses.

Performance:

  • valid=30s generates ~12 DNS queries/30s per container. Operators with stable backends could increase to 300s.

Documentation:

  • Error messages are clear and actionable. The resolver.inc comment could be more precise.

Summary

Priority Issue
Medium resolve_redis_host / resolve_redis_host_source duplicates the priority chain
Medium Silent skip on missing resolv.conf
Medium Fragile test dependency on start.sh being safely sourceable
Medium Several utility functions lack direct unit tests
Low valid=30s could be documented as tunable
Low resolver.inc comment imprecision

Comment thread deploy/one-click/scripts/common/validation.sh Outdated
Comment thread deploy/one-click/scripts/common/validation.sh Outdated
Comment thread deploy/one-click/scripts/one-click/up-cube-proxy.sh Outdated
Comment thread deploy/one-click/scripts/one-click/up-cube-proxy.sh Outdated
Comment thread deploy/one-click/scripts/common/validation.sh Outdated
Comment thread deploy/one-click/scripts/common/validation.sh Outdated
Comment thread deploy/one-click/scripts/one-click/up-cube-proxy.sh Outdated
Comment thread deploy/one-click/lib/common.sh Outdated
Comment thread deploy/one-click/scripts/one-click/up-cube-proxy.sh Outdated
@zyl1121 zyl1121 force-pushed the fix/cubeproxy-external-redis-resolver branch from e2b7687 to a81f0c2 Compare July 4, 2026 03:09
@zyl1121

zyl1121 commented Jul 4, 2026

Copy link
Copy Markdown
Contributor Author

@fslongjin I've reworked the PR to use the container-side approach.

CubeProxy now ships nginx.conf as a template and renders the final config in start.sh before nginx starts. The resolver is derived from the container's own /etc/resolv.conf, with CUBE_PROXY_NGINX_RESOLVER available as an explicit override.

This removes the one-click-only host rendering path, so the same CubeProxy startup behavior applies to one-click, k8s-style, and manual Docker deployments. The fail-fast behavior is still kept when Redis is configured by hostname but no usable resolver can be found.

I also validated the container-side rendering path and updated the one-click tests for the new flow.

@zyl1121 zyl1121 marked this pull request as ready for review July 4, 2026 03:12
Comment thread CubeProxy/start.sh Outdated
Comment thread CubeProxy/start.sh Outdated
Comment thread CubeProxy/start.sh Outdated
@zyl1121 zyl1121 force-pushed the fix/cubeproxy-external-redis-resolver branch from a81f0c2 to 1d8c520 Compare July 4, 2026 03:59

@chenhengqi chenhengqi left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's focus on the resolver-related change and keep the diff minimal. Please drop other changes, they can be in a separate PR.

@zyl1121 zyl1121 force-pushed the fix/cubeproxy-external-redis-resolver branch from 1d8c520 to 73eb271 Compare July 6, 2026 12:16
@zyl1121 zyl1121 changed the title fix(one-click): configure CubeProxy resolver for Redis hostnames fix(cubeproxy): configure resolver for Redis hostnames Jul 6, 2026
@zyl1121

zyl1121 commented Jul 6, 2026

Copy link
Copy Markdown
Contributor Author

@chenhengqi I re-scoped the PR to focus only on the resolver-related change.

The updated version keeps the container-side /etc/resolv.conf based resolver discovery, but only writes conf/includes/resolver.inc at CubeProxy startup. It no longer renders the full nginx config in the container or reworks the broader one-click flow.

I also dropped the unrelated helper cleanup, docs, and shell hardening changes. Those can be handled separately if still needed.

Comment thread CubeProxy/start.sh
Comment thread CubeProxy/start.sh Outdated
@zyl1121 zyl1121 force-pushed the fix/cubeproxy-external-redis-resolver branch from 73eb271 to 9da4847 Compare July 7, 2026 02:06
Comment thread CubeProxy/start.sh
Comment thread CubeProxy/start.sh Outdated
Comment thread CubeProxy/start.sh
@zyl1121 zyl1121 force-pushed the fix/cubeproxy-external-redis-resolver branch from 9da4847 to 876d283 Compare July 7, 2026 02:59
Comment thread CubeProxy/conf/includes/resolver.inc
Comment thread CubeProxy/start.sh
Comment thread CubeProxy/start.sh
Comment thread CubeProxy/start.sh
Add a CubeProxy nginx resolver include generated at container startup.

OpenResty Lua cosocket hostname resolution requires an explicit nginx
resolver directive, so reading /etc/resolv.conf alone is not enough when
CubeProxy connects to Redis by hostname.

start.sh updates conf/includes/resolver.inc based on the Redis target. If
Redis is configured by hostname, it derives IPv4 nameservers from the
container's /etc/resolv.conf and writes nginx resolver directives. If no
usable resolver can be derived for that hostname, startup fails fast with a
clear error. Redis IP literals leave the include as a no-op.

Keep the change focused on Redis hostname resolution without reworking the
wider one-click nginx rendering flow.

Signed-off-by: zhengyilei <zheng_yilei@qq.com>
@zyl1121 zyl1121 force-pushed the fix/cubeproxy-external-redis-resolver branch from 876d283 to e91c8f2 Compare July 11, 2026 05:55
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants