Skip to content

one-click: make the CubeProxy admin port configurable - #1256

Closed
Arpit-Ahuja-293 wants to merge 3 commits into
TencentCloud:masterfrom
Arpit-Ahuja-293:feat/cubeproxy-configurable-admin-port
Closed

one-click: make the CubeProxy admin port configurable#1256
Arpit-Ahuja-293 wants to merge 3 commits into
TencentCloud:masterfrom
Arpit-Ahuja-293:feat/cubeproxy-configurable-admin-port

Conversation

@Arpit-Ahuja-293

Copy link
Copy Markdown
Contributor

Problem

CubeProxy's /admin/* listener is pinned to 8082. cube-proxy runs with host networking, so if anything else on the node already holds that port, nginx exits with:

nginx: [emerg] bind() to <node-ip>:8082 failed (98: Address in use)

cube-sandbox-control.target then fails to come up, and install.sh gives no indication of why. The public HTTP/HTTPS/gRPC ports have all been configurable for a while; the admin port was the gap.

Two checks made this worse rather than catching it:

  • The pre-start conflict check in up-cube-proxy.sh covered CUBE_PROXY_HTTP_PORT / HTTPS / GRPC, but not the admin port.
  • cube-proxy-postcheck.sh only probed HTTP and gRPC, so a failed admin bind left the unit looking healthy while every lifecycle operation (pause/resume via cube-lifecycle-manager) was dead.

Fix

Adds CUBE_PROXY_ADMIN_PORT, defaulting to 8082 so existing deployments are unaffected, and threads it through everything that referenced the port:

Layer Change
up-cube-proxy.sh new var; __CUBE_PROXY_ADMIN_PORT__ nginx placeholder; CUBE_PROXY_ID / CUBE_PROXY_ADMIN_URL
up-cube-proxy.sh preflight admin port added to the existing conflict loop
cube-proxy-postcheck.sh probes the admin listener
build-release-bundle.sh emits the new placeholder
create.sh / tke-addons.tf / variables.tf cube_proxy_admin_port variable across 5 sites
env.example, README.md, README_zh.md documented, EN + ZH

The Kubernetes chart already supported CUBE_PROXY_ADMIN_PORT (chart/files/cube-proxy/cube-proxy-entrypoint.sh), so this brings the one-click and Terraform paths in line with naming that was already settled rather than inventing any.

Worth a maintainer's eye

The Terraform cube_proxy_admin_port variable is the only piece here that adds new public surface rather than plumbing an existing value. The issue asked for Terraform coverage, so it is included — happy to drop it into a follow-up if you would rather keep this PR to the one-click path.

Tests

Written test-first in deploy/one-click/tests/test_package_layout.sh (already run in CI by terraform-validate.yml). 8 assertions covering the default, the discovery URLs, the preflight loop, the postcheck, env.example and the bundle placeholder.

Plus a round-trip test that goes beyond static grepping: it renders the generated template with a deliberately non-default port and asserts the result is listen 10.0.0.7:9082;, with no 127.0.0.1:8082 binding left behind. Verified it actually bites by temporarily changing CubeProxy/nginx.conf to listen on 8085 — three assertions failed — then reverting.

Verification

  • test_package_layout.shpackage layout tests OK
  • Full deploy/one-click/tests/ suite → 9/10 pass
  • terraform fmt -check -recursive → clean
  • terraform validateSuccess! The configuration is valid.
  • bash -n clean on every modified script

The one failing suite file is test_runtime_file_safety.sh, which fails identically on unmodified master (an unrelated cube-sandbox-webui.service After= expectation) and is not run by CI. Untouched here.

Closes #945

CubeProxy's /admin/* listener was pinned to 8082. cube-proxy runs with
host networking, so anything else holding that port made nginx exit with
"bind() ... (98: Address in use)" and the whole cube-sandbox-control
target failed to come up, with no indication of the cause.

Add CUBE_PROXY_ADMIN_PORT, defaulting to 8082 so existing deployments are
unaffected, and thread it through the nginx template, the CLM discovery
URLs (CUBE_PROXY_ID / CUBE_PROXY_ADMIN_URL) and the pre-start port check.

The pre-start check previously covered only the HTTP/HTTPS/gRPC ports and
the systemd postcheck only probed HTTP, so a failed admin bind could
leave the service looking healthy while lifecycle operations were dead.
Both now include the admin port.

Refs TencentCloud#945

Assisted-by: Claude Code:claude-opus-5
Signed-off-by: Arpit Ahuja <iamarpitahuja@gmail.com>
Follow up on the one-click change so the Tencent Cloud deployer does not
reintroduce a hardcoded 8082. Adds a cube_proxy_admin_port variable
(default 8082) and uses it for the rendered nginx ConfigMap, the
container port and the cube-lifecycle-manager discovery env vars.

Refs TencentCloud#945

Assisted-by: Claude Code:claude-opus-5
Signed-off-by: Arpit Ahuja <iamarpitahuja@gmail.com>
Assisted-by: Claude Code:claude-opus-5
Signed-off-by: Arpit Ahuja <iamarpitahuja@gmail.com>
-e 's|^\(\s*set \$host_proxy_port \)8081;|\1__CUBE_PROXY_HTTP_PORT__;|' \
-e 's|^\(\s*set \$host_proxy_port \)8080;|\1__CUBE_PROXY_HTTPS_PORT__;|' \
-e 's|^\(\s*listen \)127\.0\.0\.1:8082;|\1__CUBE_PROXY_ADMIN_LISTEN__:8082;|' \
-e 's|^\(\s*listen \)127\.0\.0\.1:8082;|\1__CUBE_PROXY_ADMIN_LISTEN__:__CUBE_PROXY_ADMIN_PORT__;|' \

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Stale cubeproxy-nginx.conf regeneration check won't pick up the new token (upgrade path)prepare_cubeproxy_nginx_conf (create.sh:616/627) only forces regeneration when __CUBE_PROXY_GRPC_PORT__ is missing. On upgrade, an existing cubeproxy-nginx.conf generated by a pre-PR deploy contains listen __CUBE_PROXY_ADMIN_LISTEN__:8082; and is kept as-is. The new replace("__CUBE_PROXY_ADMIN_LISTEN__:__CUBE_PROXY_ADMIN_PORT__", ...) in tke-addons.tf then never matches, so the deployed nginx.conf keeps the literal __CUBE_PROXY_ADMIN_LISTEN__ placeholder — nginx fails to resolve it at startup and cube-proxy CrashLoops (fresh deploys are fine; this is upgrade-only). Please require __CUBE_PROXY_ADMIN_PORT__ in both staleness checks so stale templates are regenerated.

}
}

variable "cube_proxy_admin_port" {

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

New variable is not plumbed through create.sh / terraform env.example — unlike cube_proxy_replicas (create.sh:908) and cube_proxy_heartbeat_interval_ms (create.sh:915), there is no export TF_VAR_cube_proxy_admin_port="${TENCENTCLOUD_CUBE_PROXY_ADMIN_PORT:-8082}", no TENCENTCLOUD_CUBE_PROXY_ADMIN_PORT entry in the terraform env.example, and no persisted-env / --argjson round-trip (create.sh ~4233 / ~4447). So setting TENCENTCLOUD_CUBE_PROXY_ADMIN_PORT through the standard one-click env path is silently ignored and the variable always stays 8082 (only a manual TF_VAR_cube_proxy_admin_port export or terraform.tfvars would take effect). Since the PR's goal is Terraform coverage for this port, please wire it through the same four sites as the other cube_proxy_* variables, or drop it from this PR.

wait_for_tcp_port "${postcheck_grpc_port}" "${postcheck_retries}" "${postcheck_delay}" || die "cube-proxy gRPC tcp port not ready: ${postcheck_grpc_port}"
# The admin listener is what cube-lifecycle-manager drives for pause/resume.
# Without this check nginx can fail to bind it while the public ports come up
# fine, leaving the service "healthy" but lifecycle operations broken.

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

This probe breaks the existing postcheck behavioral testsrun_cube_proxy_postcheck_case in tests/test_runtime_file_safety.sh stubs ss to report only the HTTP/GRPC ports, so every test_cube_proxy_postcheck_* case will now time out on the admin port and die, aborting the suite (set -euo pipefail). It's currently masked by that suite's pre-existing webui After= failure (test_runtime_file_safety.sh:171), but once that's fixed, the new probe breaks all of them. Please extend the ss stub (and the case env) to also report the admin port, e.g. SS_ADMIN_PORT.

# host before we attempt to start the container; otherwise the failure mode is
# a cryptic "address already in use" from nginx inside the container.
for port in "${CUBE_PROXY_HTTP_PORT}" "${CUBE_PROXY_HTTPS_PORT}" "${CUBE_PROXY_GRPC_PORT}"; do
for port in "${CUBE_PROXY_HTTP_PORT}" "${CUBE_PROXY_HTTPS_PORT}" "${CUBE_PROXY_GRPC_PORT}" "${CUBE_PROXY_ADMIN_PORT}"; do

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Preflight conflict check is over-broad for the admin listener — the admin server binds to CUBE_PROXY_ADMIN_LISTEN (the node IP), not 0.0.0.0, but ss -lnt "( sport = :8082 )" matches any address. A loopback-only listener on 8082 (which wouldn't conflict with a node-IP bind, e.g. a local agent on 127.0.0.1:8082) now aborts the install where it previously succeeded. Conservative direction (no false negatives), so non-blocking — but consider scoping the check to the actual listen address or noting in a comment that it is address-agnostic.

@cubesandboxbot

cubesandboxbot Bot commented Aug 1, 2026

Copy link
Copy Markdown

Review: one-click — make the CubeProxy admin port configurable (#1256)

AI-generated review — no human maintainer sign-off.

Verdict

Request changes. The one-click (docker) path is clean and well-tested: the default 8082 keeps existing deployments unchanged, the new CUBE_PROXY_ADMIN_PORT is threaded through the env file, the nginx template, the discovery URLs, the preflight, and the postcheck, and the round-trip test is a genuine improvement over the existing static greps. The remaining issues are concentrated in the Terraform path, which the PR itself flags for a maintainer's eye — and where the plumbing is incomplete in ways that produce silent misbehavior rather than a loud error.

What's good

  • Backward-compatible default. CUBE_PROXY_ADMIN_PORT defaults to 8082, so existing one-click deployments are unaffected.
  • Test-first, with a real round-trip. test_package_layout.sh renders the template with a non-default port and asserts listen 10.0.0.7:9082; with no leftover 127.0.0.1:8082 binding — much stronger than the surrounding static greps.
  • Naming aligns with the existing chart. CUBE_PROXY_ADMIN_PORT is already consumed by deploy/kubernetes/chart/files/cube-proxy/cube-proxy-entrypoint.sh (I verified this in the base tree), so no new naming is invented.
  • EN + ZH docs and env.example updated consistently; terraform fmt/validate are clean per the PR description.

Findings (in severity order)

1. Medium — Terraform upgrade path leaves a literal placeholder in the deployed nginx.conf

deploy/one-click/terraform/tencentcloud/create.sh:651 and tke-addons.tf:125

prepare_cubeproxy_nginx_conf only forces regeneration when __CUBE_PROXY_GRPC_PORT__ is missing. An operator upgrading from a pre-PR Terraform deploy already has cubeproxy-nginx.conf containing listen __CUBE_PROXY_ADMIN_LISTEN__:8082;; the freshness check keeps it, and the new replace("__CUBE_PROXY_ADMIN_LISTEN__:__CUBE_PROXY_ADMIN_PORT__", "0.0.0.0:${var.cube_proxy_admin_port}") never matches. The mounted nginx.conf then retains the literal __CUBE_PROXY_ADMIN_LISTEN__ placeholder, which nginx cannot resolve at startup → cube-proxy CrashLoop. Fresh deploys are unaffected. Fix: require __CUBE_PROXY_ADMIN_PORT__ in both staleness checks (the existing-file check and the post-copy check).

2. Medium — cube_proxy_admin_port is not plumbed through create.sh / terraform env.example

deploy/one-click/terraform/tencentcloud/variables.tf:380

The variable is added to variables.tf, but unlike every other cube_proxy_* variable it has no export TF_VAR_cube_proxy_admin_port in create.sh (cf. TF_VAR_cube_proxy_replicas at create.sh:908), no TENCENTCLOUD_CUBE_PROXY_ADMIN_PORT in the terraform env.example, and no persisted-env / --argjson round-trip (create.sh ~4233, ~4447). A user following the documented path (env.examplecreate.sh) will have the value silently ignored — the var always stays 8082. Only a manual TF_VAR_cube_proxy_admin_port export or terraform.tfvars works, and even that isn't preserved across runs. Either wire it through the same four sites as cube_proxy_replicas, or drop the Terraform surface from this PR.

3. Low — New postcheck probe breaks the existing postcheck test harness

deploy/one-click/scripts/systemd/cube-proxy-postcheck.sh:23

run_cube_proxy_postcheck_case in tests/test_runtime_file_safety.sh stubs ss to report only the HTTP/GRPC ports, so every test_cube_proxy_postcheck_* case now times out on the admin port and dies (the suite runs set -euo pipefail). This is currently masked by that suite's pre-existing webui After= failure (test_runtime_file_safety.sh:171) — the PR's "fails identically on master" claim is accurate for now — but the moment that unrelated failure is fixed, this PR breaks the postcheck cases. The new behavior should be covered in the behavioral harness (extend the ss stub with an SS_ADMIN_PORT), not only via the static grep in test_package_layout.sh.

4. Low — Preflight conflict check is over-broad for the admin listener

deploy/one-click/scripts/one-click/up-cube-proxy.sh:218

The admin server binds to CUBE_PROXY_ADMIN_LISTEN (default: node IP), not 0.0.0.0, but ss -lnt "( sport = :8082 )" matches any address. A loopback-only listener on 127.0.0.1:8082 — which does not conflict with a node-IP bind — now aborts an install that previously succeeded. Conservative direction (no false negatives), so non-blocking, but worth scoping the check to the actual listen address or documenting that it's address-agnostic.

Nits

  • The static greps in test_cubeproxy_admin_port_configurable match entire lines byte-for-byte (e.g. the CUBE_PROXY_ID/CUBE_PROXY_ADMIN_URL defaults), so any cosmetic reformatting of up-cube-proxy.sh breaks the test. Consistent with the file's existing style, so purely informational.
  • CUBE_PROXY_ADMIN_PORT gets no numeric validation in the one-click path (matching the existing HTTP/HTTPS/gRPC ports); the Terraform variable does validate. Fine to leave as-is for consistency.

Test coverage

The new test_package_layout.sh assertions cover the default, discovery URLs, preflight loop, postcheck, env.example, and bundle placeholder — plus the round-trip render. What's missing is behavioral coverage of the new postcheck probe in test_runtime_file_safety.sh (finding 3). The PR's stated verification (9/10 in the suite, test_runtime_file_safety.sh failing pre-existing) is consistent with what I see in the base tree.

@zhouxianping

Copy link
Copy Markdown
Collaborator

#955 Thank you for your contribution, Does this meet your requirements? It has already been scheduled for the next release.

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.

[Feature Request] Make the CubeProxy admin port configurable and detect port conflicts during one-click installation

4 participants