Skip to content

[Backport release-1.6] fix(kubernetes): bring up a replacement worker before draining the old one - #5154

Open
mattia-eleuteri wants to merge 3 commits into
cozystack:release-1.6from
mattia-eleuteri:backport/kubernetes-surge-before-drain-1.6
Open

mattia-eleuteri wants to merge 3 commits into
cozystack:release-1.6from
mattia-eleuteri:backport/kubernetes-surge-before-drain-1.6

Conversation

@mattia-eleuteri

@mattia-eleuteri mattia-eleuteri commented Oct 29, 2026 •

Copy link
Copy Markdown
Collaborator

What this PR does

Backport of #5153 to release-1.6. The commit is cherry-picked and keeps its cherry-pick reference. Worker pool MachineDeployments switch from maxUnavailable: 1 to maxUnavailable: 0, with maxSurge at the pool ceiling and a floor of 1, so a rollout brings each replacement node up before draining the old one instead of leaving a one-node pool empty for several minutes.

Two differences from main. On this branch the Kubernetes app still renders its own nodeGroups MachineDeployments in packages/apps/kubernetes/templates/cluster.yaml with the same strategy, so that template gets the same change and a test suite of its own (tests/nodegroup_rollout_strategy_test.yaml); the kubernetes-nodes render snapshot, which was the cherry-pick conflict, does not exist here and is dropped.

On this branch helm unittest packages/apps/kubernetes packages/apps/kubernetes-nodes passes 211 of 211. With the release-1.6 templates the new non-GPU cases of each suite fail.

Exception: a pool with gpus keeps maxUnavailable: 1. Its replacement VM may need the very passed-through GPU the old node holds, and with maxUnavailable: 0 it would stay Pending and the rollout would never finish. A Proxmox pool that passes GPUs through its template carries no gpus value, so it is not recognised and gets maxUnavailable: 0.

Trade-off, as on main: a rollout needs room for one extra VM, and a tenant at its quota stalls the rollout instead of temporarily shrinking the pool.

Screenshots

Downstream repositories

Release note

fix(kubernetes): backport to 1.6. Worker pool rollouts (instance type, image or version changes) now bring each replacement node up before draining the old one, for both the Kubernetes app node groups and kubernetes-nodes pools. A rollout needs room for one extra VM.

…d one

A worker pool rollout (instance type, image or version change) ran with
maxUnavailable 1, so CAPI drained and deleted an old Machine as soon as
its replacement had been created rather than once it had joined. A
one-node pool was left with no node for the few minutes the new VM
took to boot and register, and every pool lost one node of capacity
for each step of the rollout.

With maxUnavailable 0 a node is only drained once its replacement is
up. The surge stays at the pool ceiling, with a floor of 1 because
CAPI refuses a rolling update where both values are 0 and maxReplicas
may be 0.

On this branch the in-chart nodeGroups of the kubernetes app render
the same MachineDeployment strategy, so it gets the same change and a
test of its own; the kubernetes-nodes render snapshot does not exist
here.

Assisted-by: LLM
Signed-off-by: Mattia Eleuteri <[email protected]>
(cherry picked from commit 55066b9)
@coderabbitai

coderabbitai Bot commented Oct 29, 2026 •

Copy link
Copy Markdown
Contributor

Important

Review skipped

Auto reviews are disabled on base/target branches other than the default branch.

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

Run configuration

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • Trigger review
  • Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

Share

@github-actions github-actions Bot added area/kubernetes Issues or PRs related to the tenant Kubernetes app area/release Issues or PRs related to release tooling (changelog, backport, release pipeline) kind/bug Categorizes issue or PR as related to a bug size/L This PR changes 100-499 lines, ignoring generated files labels Oct 29, 2026
mattia-eleuteri and others added 2 commits October 29, 2026 10:45
A replacement VM in a pool with passed-through GPUs may need the very
GPU the old node holds. With maxUnavailable 0 it would stay Pending
and the rollout would never finish, so those pools keep removing a
node first.

Assisted-by: LLM

(cherry picked from commit 392bbb3)
Signed-off-by: Mattia Eleuteri <[email protected]>
@mattia-eleuteri

Copy link
Copy Markdown
Collaborator Author

CI note: the remaining red checks come from this PR being opened from a fork, not from its content. Build Talos (and Build packages/apps/kubernetes on #5154) fail when pushing the PR image to iad.ocir.io/.../cozystack: denied: Anonymous users are only allowed read access, as fork PRs get no registry credentials. E2E Tests depend on those images. Unit & controller tests pass since the branch was updated with release-1.6 (they failed before on an unrelated tenant chart test). A maintainer re-run from a branch of this repository, or pushing the backport branch here, would give the full signal.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area/kubernetes Issues or PRs related to the tenant Kubernetes app area/release Issues or PRs related to release tooling (changelog, backport, release pipeline) kind/bug Categorizes issue or PR as related to a bug size/L This PR changes 100-499 lines, ignoring generated files

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant