Skip to content

Gate LB target admission on NodeReady for first admission - #961

Open
skumarc-do wants to merge 1 commit into
masterfrom
skumarc/gate-node-readiness
Open

skumarc-do wants to merge 1 commit into
masterfrom
skumarc/gate-node-readiness

Conversation

@skumarc-do

Copy link
Copy Markdown

Customer saw bursts of HTTP 503 (No server is available to handle this request) from the DO LB during node scale-ups.

Root cause: Kubernetes service controller admits nodes to EnsureLoadBalancer under stableNodeSetPredicates, which does not require NodeReady=True (kubernetes/kubernetes#90823). DO CCM's node filters (filterAndClassifyNodes, prepareNodesForLBSync) only gate on IP presence, so a NotReady droplet still gets written into lb.DropletIDs.

For externalTrafficPolicy: Cluster the LB then health-checks :10256/healthz (kube-proxy generic), which can answer 200 while the node is still NotReady the droplet is promoted to UP and traffic lands on a node that cannot serve, producing 503s. (Local policy incidentally hides this because its LB probe gates on local Ready pod presence)

Reproduced on a 2-node DOKS cluster, new droplet appeared in lb.DropletIDs 10-33s before Ready=True on every scale-up. 503s did not surface on this quiet cluster because the LB's healthy threshold (5 × 3s = 15s) often expires after Ready=True, the premature admission ordering, however, is unambiguous and matches the customer timeline.

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🟡 Changes recommended

Backend reconciliation can leave newly Ready nodes excluded and remove previously admitted nodes without ProviderIDs.

2 open findings
What changed in this PR

Updates DigitalOcean load balancer reconciliation to require NodeReady=True before first admission, aiming to prevent scale-up 503s.

Changes:

  • Adds readiness filtering and existing-backend admission tracking.
  • Adds readiness tests and an unreleased changelog entry.
File Description
cloud-controller-manager/​do/​loadbalancers.go Adds first-admission readiness checks.
cloud-controller-manager/​do/​loadbalancers_test.go Updates callers and tests readiness filtering.
CHANGELOG.md Documents the admission change.

🧠 Review effort: Balanced


Give feedback about Copilot approvals in this survey to enter a drawing for a $150 gift card.


func filterByReadiness(nodes []*v1.Node, admittedIDs map[int]bool) (admit, pending []*v1.Node) {
for _, node := range nodes {
if id, err := dropletIDFromProviderID(node.Spec.ProviderID); err == nil && admittedIDs[id] {
service.Namespace, service.Name, len(pendingNotReady), formatNodeNames(pendingNotReady, 5))
}

if len(admit) == 0 && len(pendingNotReady) > 0 {
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.

2 participants