Skip to content

[1.36.1] Count booting nodes as upcoming after CA restart to prevent duplicate scale-ups - #94

Merged
Maximiliano Uribe Falcon (MaximilianoUribe) merged 3 commits into
cluster-autoscaler-release-1.36.1-aksfrom
muribefalcon/cherry-pick-csr182-1.36.1
Oct 23, 2026
Merged

Maximiliano Uribe Falcon (MaximilianoUribe) merged 3 commits into
cluster-autoscaler-release-1.36.1-aksfrom
muribefalcon/cherry-pick-csr182-1.36.1

Conversation

@MaximilianoUribe

Copy link
Copy Markdown

What type of PR is this? (bug, cleanup, documentation, feature)

bug

What this PR does / why we need it?:

The 1.36.1 release includes kubernetes#9360, which stops GetUpcomingNodes() from counting upcoming nodes for node groups that have no active scale-up request or are backed off. Scale-up requests and backoff are held only in memory, so after a cluster-autoscaler restart or leader failover, nodes that are already booting (NotStarted) or created but not yet registered (Unregistered) are no longer counted as upcoming. The pending pods that triggered the original scale-up then look unschedulable, and CA scales the node group up again. NotStarted nodes can also be treated as scale-down candidates.

This backports the upstream fix, kubernetes-sigs/cluster-autoscaler#182. It splits upcoming nodes into:

We observed the duplicate scale-up with the 1.36.1 build: the CA pod restarted while a scale-up node was still provisioning, the new pod logged 1 unregistered nodes present, and it then scaled the same node group from 3 to 4. The 1.33.6, 1.34.5 and 1.35.2 branches don't include kubernetes#9360 and are unaffected.

Commits:

  1. Upstream regression tests (TestGetUpcomingNodesBackedVsUnbacked, TestGetUpcomingNodesAfterRestart, and a CA-restart case in TestStaticAutoscalerUpcomingScaleDownCandidates).
  2. The upstream fix in clusterstate.go.
  3. A fork-only test covering a deallocate-policy node group after a restart. NotStarted nodes count as upcoming. Deallocated nodes being started stay in the unbacked delta, which is unchanged behavior.

Commits 1 and 2 are adapted from the upstream commits to this branch's klog logging, pre-context ClusterStateRegistry API and cluster-autoscaler/ module layout. The logic is unchanged.

Does this PR introduce a user-facing change?

fix: cluster-autoscaler no longer triggers duplicate scale-ups, or treats booting nodes as scale-down candidates, after a restart or leader failover during a scale-up

WorkItem

N/A

Testing

  • Unit tests: go test ./clusterstate/... ./core/... ./processors/customresources/... pass, and go test -race ./clusterstate/... ./core/ ./core/scaleup/... pass. The new regression tests fail on the current branch tip without the fix: all CA-restart cases of TestGetUpcomingNodesBackedVsUnbacked, TestGetUpcomingNodesAfterRestart, the CA-restart case of TestStaticAutoscalerUpcomingScaleDownCandidates, and the restart case of the new deallocate test. They pass with the fix.
  • E2E tests (we can custom branches on standalone env only)
  • Other tests (eg. manual testing).
Cherry-pick details

Is this a cherry-picked PR?

  • Yes. Include original PR.
https://github.com/kubernetes-sigs/cluster-autoscaler/pull/182
  • No. On which internal versions / branches is this PR getting cherry-picked ?

Is this PR getting merged on upstream ?

  • Yes. Which branches / versions including master?
Merged to kubernetes-sigs/cluster-autoscaler main (https://github.com/kubernetes-sigs/cluster-autoscaler/pull/182) and release-1.37 (https://github.com/kubernetes-sigs/cluster-autoscaler/pull/234). There is no upstream release-1.36 cherry-pick yet.
  • No. Why?

Special notes for your reviewer:

Only cluster-autoscaler-release-1.36.1-aks needs this. The older AKS release branches don't contain kubernetes#9360. Original commits are attributed to the upstream author.

Additional Documentation: kubernetes#9360, kubernetes#9813

(cherry picked from commit e2dc4aad7148eb79e56901724ec9b45a0c2a2719 in
kubernetes-sigs/cluster-autoscaler, adapted to the pre-context
ClusterStateRegistry API and cluster-autoscaler/ module layout)
…ve scale-up request

GetUpcomingNodes() previously skipped node groups without active scale-up
requests or in backoff. However, because scaleUpRequests is in-memory only,
real booting nodes (NotStarted) and healthy instances (Unregistered) were
skipped after CA restart/failover, triggering duplicate scale-ups and
premature scale-down.

Partition upcoming nodes into backed instances (NotStarted + Unregistered)
and the unbacked TargetSize delta. Always count backed instances, while
continuing to gate the unbacked delta on having an active scale-up request
and not being backed off.

(cherry picked from commit 3b3e98c7ff386dc3941ea089068a44556fe58a0f in
kubernetes-sigs/cluster-autoscaler, adapted to klog and the pre-context
ClusterStateRegistry API)
Verify that after a CA restart a deallocate-policy node group still counts
NotStarted nodes as upcoming, while deallocated nodes being started stay
part of the unbacked delta gated on an active scale-up request.
@MaximilianoUribe
Maximiliano Uribe Falcon (MaximilianoUribe) marked this pull request as ready for review October 23, 2026 05:59
@MaximilianoUribe
Maximiliano Uribe Falcon (MaximilianoUribe) merged commit a95ad12 into cluster-autoscaler-release-1.36.1-aks Oct 23, 2026
9 checks passed
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