You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
#3788 caps the Talos-bootstrapped CoreDNS after a DR rebuild, and #3789/#3793 declared CPU limits on the Flux-delivered kube-system add-ons. Both close their half of #3567. Neither reaches the node autoscaler, which is delivered by a third mechanism nobody enumerated.
Read live against prod kube-system on 2026-09-20T23:07Z:
Deployment/cluster-autoscaler-hetzner-cluster-autoscaler stores requests: {cpu: 50m, memory: 128Mi} and limits: {memory: 256Mi} — no limits.cpu. Its admitted pod carries limits.cpu: 2, which is the kube-system default-limitrange default, not a declared value.
It is the only kube-system Deployment or DaemonSet besides coredns whose stored spec has no CPU limit. Every other one declares its own.
It is not a Flux HelmRelease in this repository. ksail.prod.yaml says so directly: "KSail installs, configures, and reconciles the autoscaler — no Flux manifests needed." Its Helm release name is cluster-autoscaler, and no helm-release.yaml here produces it.
The shipped mitigation does not reach it either. scripts/restart-uncapped-talos-coredns.sh is hard-scoped by its own header — "This touches deployment/coredns and nothing else."
scripts/tests/test-kube-system-addon-cpu-limits.sh pins 16 containers across six HelmReleases. The autoscaler is not among them, so the guard that exists to stop exactly this regressing is blind to it.
Who this affects, and impact
On a fresh prod bring-up — including the DR rebuild path, which runs ksail cluster create on fresh servers — the autoscaler pod runs uncapped. Nothing recreates it: KSail reconciles the release but does not roll a healthy pod, and the DR CoreDNS sweep skips it by design. Today's prod pod is capped only incidentally, because deploy-prod suspends autoscaling to zero replicas for the gated Cilium rollout and restores it, and that restore re-admits the pod under the LimitRange.
An uncapped autoscaler is the worst single candidate in the namespace to leave uncapped: it is the component that reacts to cluster-wide scheduling pressure, so the moment it is busiest is the moment nothing bounds its CPU. It also keeps a real subject under kubescape C-0270 and CKV_K8S_11 in kube-system during the window #3567 set out to close.
Expected behaviour
The autoscaler carries a CPU limit on a fresh cluster without depending on the LimitRange existing first, and a guard fails if that declaration is removed.
Options
Declare the limit in ksail.prod.yaml's autoscaler block, if KSail exposes a resources passthrough. Structural and matches what fix(security): declare CPU limits on the non-datapath kube-system add-ons #3793 did for the Flux-delivered add-ons. Needs KSail support confirmed first; if it is absent, that is a KSail feature request, not a platform change.
Widen the DR sweep from deployment/coredns to the bootstrap-admitted set. The existing script's narrowness was deliberate — a generic "restart whatever is uncapped" would roll Cilium — but the population is separable without that risk: a workload is bootstrap-admitted when it carries neither a kustomize.toolkit.fluxcd.io/name label nor a Flux-owned HelmRelease behind it. Measured against prod today that predicate selects coredns and the autoscaler and nothing else. Also needs the sweep wired into deploy-prod, which only dr-rebuild.yaml runs today.
Option 1 is the honest end state and leaves nothing to a post-hoc restart; option 2 is the fallback if KSail cannot express it. Check option 1 first.
Acceptance criteria
Deployment/cluster-autoscaler-hetzner-cluster-autoscaler declares limits.cpu in its stored spec, read from the cluster rather than inferred from a manifest.
Evidence
#3788 caps the Talos-bootstrapped CoreDNS after a DR rebuild, and #3789/#3793 declared CPU limits on the Flux-delivered kube-system add-ons. Both close their half of #3567. Neither reaches the node autoscaler, which is delivered by a third mechanism nobody enumerated.
Read live against prod kube-system on 2026-09-20T23:07Z:
Deployment/cluster-autoscaler-hetzner-cluster-autoscalerstoresrequests: {cpu: 50m, memory: 128Mi}andlimits: {memory: 256Mi}— nolimits.cpu. Its admitted pod carrieslimits.cpu: 2, which is the kube-systemdefault-limitrangedefault, not a declared value.corednswhose stored spec has no CPU limit. Every other one declares its own.ksail.prod.yamlsays so directly: "KSail installs, configures, and reconciles the autoscaler — no Flux manifests needed." Its Helm release name iscluster-autoscaler, and nohelm-release.yamlhere produces it.ksail cluster create, in the same window as Talos's CoreDNS: before Flux is installed, and long before thebootstrapKustomization creates the LimitRange. security(platform): Talos-bootstrapped CoreDNS on prod is admitted before the kube-system LimitRange and is never rolled by Flux #3567's ordering guarantee does not cover it for the same reason it does not cover CoreDNS.scripts/restart-uncapped-talos-coredns.shis hard-scoped by its own header — "This touchesdeployment/corednsand nothing else."scripts/tests/test-kube-system-addon-cpu-limits.shpins 16 containers across six HelmReleases. The autoscaler is not among them, so the guard that exists to stop exactly this regressing is blind to it.Who this affects, and impact
On a fresh prod bring-up — including the DR rebuild path, which runs
ksail cluster createon fresh servers — the autoscaler pod runs uncapped. Nothing recreates it: KSail reconciles the release but does not roll a healthy pod, and the DR CoreDNS sweep skips it by design. Today's prod pod is capped only incidentally, becausedeploy-prodsuspends autoscaling to zero replicas for the gated Cilium rollout and restores it, and that restore re-admits the pod under the LimitRange.An uncapped autoscaler is the worst single candidate in the namespace to leave uncapped: it is the component that reacts to cluster-wide scheduling pressure, so the moment it is busiest is the moment nothing bounds its CPU. It also keeps a real subject under kubescape C-0270 and CKV_K8S_11 in kube-system during the window #3567 set out to close.
Expected behaviour
The autoscaler carries a CPU limit on a fresh cluster without depending on the LimitRange existing first, and a guard fails if that declaration is removed.
Options
ksail.prod.yaml's autoscaler block, if KSail exposes a resources passthrough. Structural and matches what fix(security): declare CPU limits on the non-datapath kube-system add-ons #3793 did for the Flux-delivered add-ons. Needs KSail support confirmed first; if it is absent, that is a KSail feature request, not a platform change.deployment/corednsto the bootstrap-admitted set. The existing script's narrowness was deliberate — a generic "restart whatever is uncapped" would roll Cilium — but the population is separable without that risk: a workload is bootstrap-admitted when it carries neither akustomize.toolkit.fluxcd.io/namelabel nor a Flux-owned HelmRelease behind it. Measured against prod today that predicate selectscorednsand the autoscaler and nothing else. Also needs the sweep wired intodeploy-prod, which onlydr-rebuild.yamlruns today.Option 1 is the honest end state and leaves nothing to a post-hoc restart; option 2 is the fallback if KSail cannot express it. Check option 1 first.
Acceptance criteria
Deployment/cluster-autoscaler-hetzner-cluster-autoscalerdeclareslimits.cpuin its stored spec, read from the cluster rather than inferred from a manifest.50m, so the admitted50m:2ratio the VPA (InPlaceOrRecreate) holds is unchanged — the same constraint fix(security): declare CPU limits on the non-datapath kube-system add-ons #3793 recorded for the other add-ons.scripts/tests/test-kube-system-addon-cpu-limits.sh, or an equivalent guard, fails when the declaration is removed, with the ablation recorded.Rough size: S (option 1) / M (option 2). Found while verifying #3567's acceptance criteria against
main.