Skip to content

feat(CubeProxy): make admin port configurable and detect port conflicts - #955

Merged
fslongjin merged 2 commits into
TencentCloud:masterfrom
yingjun8:feat/configurable-cube-proxy-admin-port
Aug 19, 2026
Merged

feat(CubeProxy): make admin port configurable and detect port conflicts#955
fslongjin merged 2 commits into
TencentCloud:masterfrom
yingjun8:feat/configurable-cube-proxy-admin-port

Conversation

@yingjun8

@yingjun8 yingjun8 commented Jul 14, 2026

Copy link
Copy Markdown
Contributor

Summary

CubeProxy runs with host networking and its /admin/* server was hard-coded to port 8082. When another process on the node already holds that port, nginx aborts at startup with bind() to <node-ip>:8082 failed (98: Address already in use) and the container crash-loops — while the one-click installer stalls at cube-sandbox-control.target without ever surfacing the real cause (#945).

This PR fixes both halves of the problem:

  1. The port is now configurable via CUBE_PROXY_ADMIN_PORT (default 8082, fully backward-compatible), threaded through the entire stack — systemd one-click path, nginx templating, and the Terraform/TKE deployment.
  2. Conflicts now fail fast with a clear message instead of a silent hang: the pre-start conflict check, the post-start readiness loop, and the systemd postcheck all cover the admin port.

Root cause

Two independent defects:

  • Admin port not configurable. A prior change parametrized the admin listen address (CUBE_PROXY_ADMIN_LISTEN) but left the port 8082 hard-coded — in the nginx template transforms, in the derived CUBE_PROXY_ID / CUBE_PROXY_ADMIN_URL, and in the Terraform deployment — unlike HTTP/HTTPS/gRPC, which already have CUBE_PROXY_HTTP_PORT / CUBE_PROXY_HTTPS_PORT / CUBE_PROXY_GRPC_PORT.
  • Silent failure. The pre-start conflict check and all readiness/postcheck probes only covered HTTP/HTTPS/gRPC. An admin-bind failure kills the whole nginx master, so the container crash-loops and the installer just waits.

Changes

1. Admin port configurable — systemd one-click path

  • up-cube-proxy.sh: new CUBE_PROXY_ADMIN_PORT (default 8082); validates it is a TCP port in 1–65535 and distinct from the HTTP/HTTPS/gRPC ports; derives CUBE_PROXY_ID / CUBE_PROXY_ADMIN_URL from it; renders the new __CUBE_PROXY_ADMIN_PORT__ nginx template placeholder.
  • env.example: documents the new variable.

2. Fail-fast conflict & readiness detection

  • up-cube-proxy.sh pre-start check now covers the admin port, and the error names the specific override variable for whichever port collided (e.g. port 80 occupied → suggests CUBE_PROXY_HTTP_PORT, not the admin port).
  • The post-start readiness loop also waits on the admin port; on timeout it names each missing port with its override variable and points at docker logs cube-proxy for the bind() failure.
  • cube-proxy-postcheck.sh (systemd ExecStartPost) probes the admin port as well, so a bind failure marks the unit failed with a clear message.
  • quickcheck.sh: check_unit_active now dies immediately if the unit is already in failed state (with systemctl status output) instead of polling until the 120s readiness budget expires — relevant because control.target only Wants= its children, so a failed child never fails enable --now.

3. nginx template placeholder

  • build-release-bundle.sh, terraform/tencentcloud/create.sh, tests/test_package_layout.sh: the sed transforms now emit __CUBE_PROXY_ADMIN_LISTEN__:__CUBE_PROXY_ADMIN_PORT__ (previously :8082), and the placeholder-validation loops require the new token. create.sh regenerates a stale template that lacks it.

4. Terraform / TKE

  • variables.tf: new cube_proxy_admin_port variable (number, validated 1–65535, default 8082).
  • create.sh / destroy.sh: TENCENTCLOUD_CUBE_PROXY_ADMIN_PORTTF_VAR_cube_proxy_admin_port, persisted to .env and resolved.auto.tfvars.json (destroy keeps parity).
  • tke-addons.tf: the admin-port replace() is folded into the main token chain (tostring(var.cube_proxy_admin_port)); containerPort and the CUBE_PROXY_ADMIN_URL / CUBE_PROXY_RESUME_URL env values follow the variable.
  • terraform/tencentcloud/env.example: documents the new variable.

5. Docs

  • docs/guide/lifecycle.md + docs/zh/guide/lifecycle.md: note that the admin port defaults to 8082 and can be overridden with CUBE_PROXY_ADMIN_PORT when the port is taken (EN/ZH in sync).

6. Tests

  • test_runtime_file_safety.sh: the postcheck harness now stubs the admin port (the ss stub appends across the three probes); new case test_quickcheck_check_unit_active_dies_fast_on_failed_unit verifying the failed-unit fail-fast (dies immediately, prints systemctl status, never sleeps).
  • test_package_layout.sh: covers the new template placeholder (and picks up the gRPC placeholder it was missing).

Scope note

Earlier revisions of this PR also added an installer-level port preflight and a full systemd state machine in quickcheck.sh. Per review feedback these were removed as out of scope / redundant with the service-level checks above; general fail-fast behavior for the installer under Wants= units will be handled in a follow-up. What remains here is scoped to the admin port: configurability plus service-level conflict/readiness detection.

Testing

  • deploy/one-click/tests/test_runtime_file_safety.sh — OK
  • deploy/one-click/tests/test_package_layout.sh — OK

Closes #945

for port in "${CUBE_PROXY_HTTP_PORT}" "${CUBE_PROXY_HTTPS_PORT}" "${CUBE_PROXY_ADMIN_PORT}"; do
if command_output_contains_fixed_string "LISTEN" ss -lnt "( sport = :${port} )"; then
die "port ${port} is already in use; cube-proxy uses host networking and requires it to be free"
die "port ${port} is already in use; cube-proxy uses host networking and requires it to be free (override the admin port with CUBE_PROXY_ADMIN_PORT if 8082 is taken)"

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

The die message unconditionally advises "override the admin port with CUBE_PROXY_ADMIN_PORT" even when the conflicting port is HTTP or HTTPS. It also hard-codes 8082 instead of referencing $CUBE_PROXY_ADMIN_PORT, so if the admin port was customized to e.g. 9090 and that specific port is the one in use, the error points to the wrong default.

Consider:

admin_advice=""
if [[ "${port}" == "${CUBE_PROXY_ADMIN_PORT}" ]]; then
  admin_advice=" (override the admin port with CUBE_PROXY_ADMIN_PORT)"
fi
die "port ${port} is already in use; cube-proxy uses host networking and requires it to be free${admin_advice}"

)
# Pods run with per-pod networking, so the admin server binds 0.0.0.0 and the
# port is parametrized independently for consistency with the systemd path.
cubeproxy_nginx_conf_rendered = replace(

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

__CUBE_PROXY_ADMIN_PORT__ is substituted in a separate replace() call (lines 120-124) outside the main nested replace() chain (lines 103-117). This is inconsistent with how all other tokens are handled: a future developer adding or removing a template token must know to check both paths. Consider including __CUBE_PROXY_ADMIN_PORT__ in the main chain with tostring() inline (e.g. tostring(var.cube_proxy_admin_port)) so the rendering is fully self-contained.

source "${SCRIPT_DIR}/common.sh"

postcheck_port="${CUBE_PROXY_HTTP_PORT:-80}"
admin_port="${CUBE_PROXY_ADMIN_PORT:-8082}"

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

The admin port defaults to 8082 here, but the systemd unit may not propagate the CUBE_PROXY_ADMIN_PORT env var. If the admin port was customized but the env var isn't forwarded to this postcheck, the script probes port 8082 (the wrong port). If some other service happens to listen on 8082, this produces a false-positive success. Consider reading from a systemd environment file or noting this dependency upstream where the unit file is defined.

@cubesandboxbot

cubesandboxbot Bot commented Jul 14, 2026

Copy link
Copy Markdown

Review: feat(CubeProxy): make admin port configurable and detect port conflicts (#955)

AI-generated review — not a human approval.

Overall assessment

This is a well-scoped, well-tested change. It makes the CubeProxy admin port configurable (CUBE_PROXY_ADMIN_PORT / cube_proxy_admin_port, default 8082, backward-compatible) and adds fail-fast detection for port conflicts, closing #945. The admin-port placeholder is threaded consistently through every path that renders the nginx template (build-release-bundle.sh, up-cube-proxy.sh, create.sh, tke-addons.tf), and the placeholder-validation loops in the template generators were updated in lockstep — so a drift in upstream CubeProxy/nginx.conf fails loudly instead of silently.

I verified the tke-addons.tf replace() chain is balanced (7 wraps / 7 closes) and that the shell-path stale-template regeneration check (prepare_cubeproxy_nginx_conf) now requires __CUBE_PROXY_ADMIN_PORT__, closing the pre-existing stale-file hole that the split placeholder would otherwise create. The new tests are sound: the postcheck ss stub appends args across the three probes, and the new quickcheck test correctly asserts no sleep happens before a failed unit dies.

The findings below are low-severity robustness gaps, not blockers. None of them affect the default-8082 path (which behaves identically to before).

Inline findings

  1. tke-addons.tf:128 (low) — The split replace() for __CUBE_PROXY_ADMIN_LISTEN__ / __CUBE_PROXY_ADMIN_PORT__ silently ignores var.cube_proxy_admin_port if the template file still uses the old combined format (__CUBE_PROXY_ADMIN_LISTEN__:8082). That can happen when terraform apply is run directly with a cubeproxy-nginx.conf from a pre-PR release (bypassing create.sh's regeneration). The result is nginx binding 8082 while containerPort / CUBE_PROXY_ADMIN_URL advertise the new port — breaking CLM's admin discovery. Suggest also replacing the legacy combined pattern so a stale file cannot silently drop the override.

  2. quickcheck.sh:137 (low) — Fast-failing on ActiveState=failed is the right behavior for the crash-looping-proxy case this PR targets, but every unit this probe checks is Restart=on-failure/RestartSec=2s, so a single transient failure during the readiness window (e.g. a dependency race) can now abort the install where the old wait_until loop would have waited for the auto-restart. Consider confirming failed persists across two probe intervals, or scoping the fast-fail to the cube-proxy unit.

  3. variables.tf:453 (low) — The port validation > 0 && < 65536 allows non-integer values (8082.5), which then fail late at the Kubernetes API / nginx parse. The adjacent cube_proxy_heartbeat_interval_ms already enforces integers via floor(...) == ...; mirror that. The shell-path _validate_host_port likewise doesn't force base-10 (10#${port}) like validate_host_port does, so leading-zero / oversized values behave inconsistently.

Minor notes

  • reloading case is dead code in check_unit_active: systemctl show -p ActiveState --value returns active during a reload (SubState is reloading), so the reloading branch is unreachable. Harmless.
  • Test coverage: the postcheck helper now asserts the admin port appears in ss.args, but there's no test case exercising a non-default CUBE_PROXY_ADMIN_PORT (or TENCENTCLOUD_CUBE_PROXY_ADMIN_PORT) through the postcheck / conflict-check / tfvars pipeline. Given the whole point of the PR is the override path, one such case would harden it.
  • The K8s/Helm path already supported cubeProxy.adminPort (via CUBE_PROXY_ADMIN_PORT and the entrypoint rewrite), so this PR correctly brings the one-click and Terraform paths in line with it. The one-click container mounts a fully-rendered nginx.conf, so not adding CUBE_PROXY_ADMIN_PORT to the compose env is fine.

Verification performed

  • Confirmed the tke-addons.tf replace() nesting is balanced and preserves the original substitution order (HTTP → HTTPS → gRPC → SSL cert/key → admin listen → admin port).
  • Confirmed all hard-coded 8082 sites in tke-addons.tf / create.sh are updated by this PR (no stale references remain in the base tree).
  • Confirmed CUBE_PROXY_ADMIN_PORT is defined before CUBE_PROXY_ID/CUBE_PROXY_ADMIN_URL reference it in up-cube-proxy.sh, and that port validation runs before the template render and the ss conflict check.
  • Confirmed unit_is_active has no other references (safe to remove) and no existing test stubs systemctl is-active.
  • Confirmed the new quickcheck test's stubs (systemctl show/status, no-op sleep) produce the asserted output without sleeping, and that test_cube_proxy_postcheck_fails_when_grpc_port_not_ready still passes because the gRPC probe fails before the admin probe runs.

@mon3stera

Copy link
Copy Markdown

When I ran install.sh, I encounter a problem of silent failure: install.sh calls: systemctl enable --now "${target}" and does not print the failed service's status or recent journal entries. Therefore the installer may still stop around this command without directly showing the actionable port 8082 is already in use message.

@yingjun8
yingjun8 force-pushed the feat/configurable-cube-proxy-admin-port branch from 67229ba to 9bc711a Compare July 14, 2026 11:29
@yingjun8

Copy link
Copy Markdown
Contributor Author

@mon3stera Fixed in 9bc711a. install.sh ran a bare systemctl enable --now, so when cube-proxy failed on the 8082 conflict, set -e aborted before quickcheck and systemd swallowed the child's logs. Now it dumps status + journal for failed cube-sandbox-* units and dies with an actionable hint.

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
@mon3stera

Copy link
Copy Markdown

The CubeProxy preflight itself works. However, I found that the new installer diagnostic path is not triggered with the current target dependencies.

cube-sandbox-control.target has an empty Requires= and pulls cube-sandbox-cube-proxy.service in through Wants=. Therefore, when cube-proxy fails, systemctl enable --now "${target}" can still return 0, so this branch doesn't work:

if !systemctl enable --now "${target}"; then
  dump_failed_cube_units "${target}"
fi

The installer then proceeds to quickcheck, while the actionable port-conflict message remains only in the service journal.

Other issues:

  1. test_runtime_fail_safety.sh fails because the existing CubeProxy postcheck test stub only simulates the HTTP listener, while the postcheck now also waits for port 8082.

@yingjun8
yingjun8 force-pushed the feat/configurable-cube-proxy-admin-port branch from 9bc711a to 9262837 Compare July 15, 2026 06:29
@yingjun8

Copy link
Copy Markdown
Contributor Author

The CubeProxy preflight itself works. However, I found that the new installer diagnostic path is not triggered with the current target dependencies.

cube-sandbox-control.target has an empty Requires= and pulls cube-sandbox-cube-proxy.service in through Wants=. Therefore, when cube-proxy fails, systemctl enable --now "${target}" can still return 0, so this branch doesn't work:

if !systemctl enable --now "${target}"; then
  dump_failed_cube_units "${target}"
fi

The installer then proceeds to quickcheck, while the actionable port-conflict message remains only in the service journal.

Other issues:

  1. test_runtime_fail_safety.sh fails because the existing CubeProxy postcheck test stub only simulates the HTTP listener, while the postcheck now also waits for port 8082.

Thanks, fixed in 9262837:

  1. I moved detection into quickcheck's check_unit_active — it now dumps systemctl status + journalctl -n 40 on timeout, surfacing the actionable port-8082 message.
  2. Test stub now models the admin listener too and asserts on both ports.

Please test it when you have a chance.

@chenhengqi chenhengqi moved this from Todo to In progress in CubeSandbox Jul 15, 2026
Comment thread deploy/one-click/scripts/one-click/quickcheck.sh Outdated
Comment thread deploy/one-click/terraform/tencentcloud/create.sh
@yingjun8
yingjun8 force-pushed the feat/configurable-cube-proxy-admin-port branch from 9262837 to d1c26cc Compare July 17, 2026 10:18
Comment thread deploy/one-click/scripts/one-click/quickcheck.sh Outdated
Comment thread deploy/one-click/terraform/tencentcloud/create.sh
Comment thread deploy/one-click/scripts/one-click/quickcheck.sh Outdated
@yingjun8
yingjun8 force-pushed the feat/configurable-cube-proxy-admin-port branch from d1c26cc to f447f75 Compare July 20, 2026 09:48
Comment thread deploy/one-click/scripts/one-click/up-cube-proxy.sh Outdated
Comment thread deploy/one-click/install.sh Outdated
Comment thread deploy/one-click/scripts/one-click/up-cube-proxy.sh Outdated
@yingjun8
yingjun8 force-pushed the feat/configurable-cube-proxy-admin-port branch from f447f75 to 7dbb6d8 Compare July 20, 2026 10:02
Comment thread deploy/one-click/install.sh Outdated
Comment thread deploy/one-click/install.sh Outdated
Comment thread deploy/one-click/scripts/one-click/quickcheck.sh Outdated
Comment thread deploy/one-click/tests/test_runtime_file_safety.sh
@chenhengqi
chenhengqi requested a review from mon3stera July 22, 2026 01:54
@chenhengqi

Copy link
Copy Markdown
Collaborator

@mon3stera There is a requested change from your previous review. I would like to get an explicit approve from you on this PR. Thanks.

@chenhengqi chenhengqi moved this from In progress to Delay in CubeSandbox Jul 22, 2026
@chenhengqi chenhengqi moved this from Delay to In progress in CubeSandbox Jul 22, 2026
@mon3stera

mon3stera commented Jul 23, 2026

Copy link
Copy Markdown

Overall, the changes look good. Please address the remaining suggestions left by the bot

@yingjun8
yingjun8 force-pushed the feat/configurable-cube-proxy-admin-port branch from 7dbb6d8 to f48d5e5 Compare July 24, 2026 03:16
Comment thread deploy/one-click/scripts/one-click/up-cube-proxy.sh
@yingjun8
yingjun8 force-pushed the feat/configurable-cube-proxy-admin-port branch from f48d5e5 to eff0b8d Compare July 24, 2026 03:25
Comment thread deploy/one-click/install.sh Outdated
# free on the host before we start the unit. The failure mode when they are not
# is nginx aborting inside the container with a cryptic "address already in use"
# that crash-loops and -- because the control target only Wants= its members --
# never surfaces as a non-zero exit, leaving quickcheck to burn the whole

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

No port validation before ss conflict check

check_cube_proxy_port_conflict_preflight uses CUBE_PROXY_ADMIN_PORT (and the HTTP/HTTPS ports) directly in an ss invocation without validating they are valid TCP port numbers. If an operator sets CUBE_PROXY_ADMIN_PORT=abc (a typo), the ss error is swallowed by 2>/dev/null || true, the grep finds no LISTEN on the empty result, and the preflight passes silently.

The invalid value is eventually caught by _validate_host_port in up-cube-proxy.sh, but only after start_systemd_target has already been called, wasting the install attempt.

Suggestion: Add a _validate_host_port call (or inline equivalent) for the three ports before the ss loop, matching the validation already present in up-cube-proxy.sh. This could be achieved by sourcing the shared validation function, or by duplicating the simple [[ "${port}" =~ ^[0-9]+$ ]] && (( port >= 1 && port <= 65535 )) check.

@chenhengqi

Copy link
Copy Markdown
Collaborator

@yingjun8 @mon3stera Thanks. Will take this in our next release.

Comment on lines +115 to +118
"__CUBE_PROXY_ADMIN_LISTEN__",
"0.0.0.0"
)
# Pods run with per-pod networking, so the admin server binds 0.0.0.0 and the

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

@tinklone Hi, could you please take a look and see if this change is correct?

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.

LGTM

@fslongjin fslongjin left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Scope review

The core change (CUBE_PROXY_ADMIN_PORT threaded through templates / IDs / URLs / TF, plus admin in the service-level conflict/readiness checks) looks necessary and focused.

However, roughly ~2/3 of the diff is a broader installer/quickcheck diagnostics rewrite that is only loosely related to making the admin port configurable. Suggest splitting into:

  1. This PR: admin port config + service/postcheck conflict detection
  2. Follow-up: installer UX / check_unit_active fail-fast rewrite

If kept together, please at least address the P1 dead-path issue on dump_failed_cube_units, and call out the installer UX work explicitly in the PR summary.

Comment thread deploy/one-click/install.sh Outdated
# `enable --now` returns non-zero as soon as a required child unit fails to
# start. Without this guard `set -e` would abort the installer right here --
# before the quickcheck below ever runs -- leaving no diagnostics on screen.
if ! systemctl enable --now "${target}"; then

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

[P1] dump_failed_cube_units likely never runs on the #945 failure path

This diagnostics dump is gated on if ! systemctl enable --now "${target}". But this PR (and the new quickcheck.sh comments) already document that cube-sandbox-control.target only Wants= its members — so a failed child unit (including cube-proxy) typically still leaves enable --now returning 0.

That means the actual #945 path — "8082 taken → cube-proxy crash-loops → installer appears to succeed / stalls silently" — almost never enters this branch. The helper covers a Requires=/hard-dependency failure mode, not the Wants= silent-failure mode this PR claims to fix.

Please either:

  1. Drop this from the PR and move it to a separate installer-UX change; or
  2. Run the scan after a successful enable --now, looking for non-active cube-sandbox-*.service units (so Wants= failures are actually covered).

As written, ~45 lines of new code don't help close #945 but do add maintenance surface.

Comment thread deploy/one-click/install.sh Outdated
cube-sandbox-control.target \
cube-sandbox-compute.target >/dev/null 2>&1 || true
systemctl enable --now "${target}"
# `enable --now` returns non-zero as soon as a required child unit fails to

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

[P1] Internal contradiction with the Wants= narrative

This comment says enable --now returns non-zero as soon as a required child fails.

But lines 258–260 in this file, and quickcheck.sh lines 135–137, emphasize that the control target only uses Wants=, so a member failure does not make enable --now fail.

Please reconcile: if Wants= is the real model, this guard does not cover #945; if some path really fails enable --now, cite the concrete dependency graph. As written, future readers will wrongly assume "installer dump covers port conflicts".

Comment thread deploy/one-click/install.sh Outdated
# deployment legitimately holds these ports, so probing before the stop would
# always false-positive. After the stop our own services have released the
# ports and a remaining listener means a genuine external conflict.
check_cube_proxy_port_conflict_preflight() {

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

[P2] Duplicate of the up-cube-proxy.sh conflict check — not required for the feature loop

up-cube-proxy.sh already checks HTTP/HTTPS/admin conflicts and (per the comments here) remains the source of truth for systemctl restart cube-proxy. This copies the same logic again and explicitly admits a TOCTOU window.

For closing #945, service-level detection + postcheck probing the admin port is sufficient. An install-time preflight only buys "fail before starting unrelated units" UX — it is not part of making the admin port configurable.

Suggest splitting to a follow-up, or at least sharing one implementation so the two paths cannot drift (e.g. install still lacks the same port-format validation as up-cube-proxy.sh).

# was legitimately still coming up.
# We therefore fetch every category in a single `systemctl show` call and branch
# exactly once per iteration on the snapshot, so the verdict is consistent.
check_unit_active() {

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

[P2] Related, but scope-creep — consider a separate PR

This grew from "don't burn the readiness budget on a already-failed unit" into a full systemd state machine (Load/Active/Sub/Result/Job/NRestarts + journal dumps + three new tests). That is a general fix for silent failures under Wants=, not "add CUBE_PROXY_ADMIN_PORT".

Helpful for #945, but the volume (~+120 implementation, ~+110 tests) already dwarfs the core feature. Prefer a dedicated PR (e.g. fail-fast systemd readiness). Keep this PR to admin-port wiring + service/postcheck probing.

If it must stay: please say so explicitly in the title/summary so reviewers don't evaluate this as a small config knob.

# pre-check only catches an *external* listener, not this self-conflict, so an
# equal pair would otherwise crash-loop the container with a cryptic
# "address already in use" from nginx.
if [[ "${CUBE_PROXY_HTTP_PORT}" == "${CUBE_PROXY_HTTPS_PORT}" ]]; then

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

[P3] HTTP≠HTTPS check is orthogonal to admin-port configurability

Validating admin ≠ HTTP/HTTPS belongs with this feature. Requiring HTTP ≠ HTTPS is sensible hardening, but it is unrelated to making the admin port configurable (likely review/bot follow-on).

Non-blocking — just further amplifies the "rewriting the whole port subsystem" feel. Fine as a follow-up if we want a tighter PR.

Comment thread deploy/one-click/install.sh Outdated
:
}

# cube-proxy runs with network_mode: host, so its HTTP/HTTPS/admin ports must be

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

[P3] Comment essay is too long for an install script

~20 lines here re-litigate TOCTOU, Wants=, and why this must run after stop — better suited to the PR description / a short design note than inline in install.sh.

Same pattern shows up in quickcheck.sh / up-cube-proxy.sh in this PR. Please compress to ~3–5 lines: what it does, why it must run after stop, and that the service-level check remains source of truth.

)
# Pods run with per-pod networking, so the admin server binds 0.0.0.0 and the
# port is parametrized independently for consistency with the systemd path.
cubeproxy_nginx_conf_rendered = replace(

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

[P3] Admin-port replace() is inconsistent with the main token chain

__CUBE_PROXY_ADMIN_PORT__ is substituted in a separate replace() while other tokens live in the nested chain. Functionally fine, but easy to miss when adding/removing tokens later.

Consider folding it into the main chain with tostring(var.cube_proxy_admin_port) for consistency. Non-blocking.

yingjun8 and others added 2 commits August 19, 2026 11:55
…nflicts

CubeProxy runs with host networking and hard-coded its admin server to
8082, so a pre-existing listener on that port crash-looped the container
while the installer stalled at cube-sandbox-control.target without
surfacing the bind() failure.

Add CUBE_PROXY_ADMIN_PORT (default 8082, backward-compatible) threaded
through up-cube-proxy.sh, the nginx template transforms, and the
Terraform/K8s deployment. Also add the admin port to the pre-start
conflict check, the post-start readiness loop, and the systemd
post-start check so a conflict fails early with a clear message.

Closes TencentCloud#945

Signed-off-by: yingjun <yingjun.yc@antgroup.com>
Drop the installer port preflight and dump_failed_cube_units dead path,
and replace the systemd state machine with a small failed-unit fail-fast.
Admin-port configurability and cube-proxy conflict/readiness checks stay.

Signed-off-by: jinlong <jinlong@tencent.com>
@fslongjin
fslongjin force-pushed the feat/configurable-cube-proxy-admin-port branch from eff0b8d to 0e8cb41 Compare August 19, 2026 06:52
@fslongjin
fslongjin merged commit 767f497 into TencentCloud:master Aug 19, 2026
4 of 5 checks passed
@github-project-automation github-project-automation Bot moved this from In progress to Done in CubeSandbox Aug 19, 2026
"cube.app+3-key.pem"
"__CUBE_PROXY_ADMIN_LISTEN__",
"0.0.0.0"
),

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Split replace silently drops the port override for old-format templates. The previous code replaced the combined literal __CUBE_PROXY_ADMIN_LISTEN__:8082; this splits it into two independent replaces. If the file consumed by file() still uses the old placeholder format (i.e. a cubeproxy-nginx.conf generated by a pre-PR release, when terraform apply is run directly and prepare_cubeproxy_nginx_conf's regeneration is bypassed), the __CUBE_PROXY_ADMIN_LISTEN__ replace renders 0.0.0.0:8082 and the __CUBE_PROXY_ADMIN_PORT__ replace finds nothing to substitute — so nginx binds 8082 regardless of var.cube_proxy_admin_port, while container_port and CUBE_PROXY_ADMIN_URL/CUBE_PROXY_RESUME_URL advertise the new port. That mismatch breaks cube-lifecycle-manager's discovery of the proxy admin endpoint. create.sh regenerates stale files in the normal flow, but the HCL itself has no guard. Consider also replacing the legacy combined pattern (e.g. __CUBE_PROXY_ADMIN_LISTEN__:80820.0.0.0:<port>) so a stale file cannot silently ignore the variable.

active|reloading)
return 0
;;
failed)

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Fast-failing on ActiveState=failed can trip on a transient restart. Every unit probed by check_unit_active is Restart=on-failure with RestartSec=2s (see deploy/one-click/systemd/*.service). When such a unit crashes once during cold start — e.g. a dependency race — it passes through failed before systemd schedules the auto-restart; the old wait_until + systemctl is-active loop would keep polling until the restart succeeded, but this new code calls die on the first failed observation. For the target scenario (a permanently crash-looping cube-proxy whose bind conflict trips the start limit) this is exactly right, but it narrows the tolerance for a one-off failure inside the 120s readiness window. Worth confirming a unit stays failed across at least two probe intervals before dying, or scoping the fast-fail to the cube-proxy unit only.

default = 8082

validation {
condition = var.cube_proxy_admin_port > 0 && var.cube_proxy_admin_port < 65536

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Validation permits non-integer ports. 8082.5 satisfies > 0 && < 65536 and then fails late — at the Kubernetes API for container_port, or in nginx parsing the rendered listen. The adjacent cube_proxy_heartbeat_interval_ms validation enforces an integer with floor(...) == ...; apply the same here (e.g. floor(var.cube_proxy_admin_port) == var.cube_proxy_admin_port). The shell-path _validate_host_port in up-cube-proxy.sh also relies on bare (( port >= 1 && port <= 65535 )), which parses leading-zero values as octal and can wrap huge digit strings, unlike the codebase's validate_host_port (10#${port}); forcing base-10 there too would keep the two paths consistent.

@chenhengqi chenhengqi moved this from Done to Merged in CubeSandbox Aug 19, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

Status: Merged

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

6 participants