Safe Node Drain With a Disruption Budget
Scenario
checkout-api in the shop namespace takes every payment on the storefront. It runs three replicas, and the team's rule is simple: checkout never runs on fewer than two.
node-01 is scheduled for a kernel patch tonight. It currently hosts two of the three replicas:
kubectl get pods -n shop -o wide
Today nothing limits how many checkout-api replicas a drain may evict at once. If node-01 were drained as things stand, two of the three replicas would go down together, and checkout would run on one replica until their replacements became Ready.
Task
- Create a PodDisruptionBudget named
checkout-api-pdbin theshopnamespace that keeps at least2of thecheckout-apireplicas available. - Drain
node-01for maintenance oncecheckout-api-pdbis in place. - Keep
node-01cordoned after the drain, because the maintenance window is still open. The test passes oncecheckout-apihas3available replicas again on the other nodes.
Do not edit, scale, or delete the checkout-api Deployment or its Pods by hand. The drain has to do the work, and the budget has to control its pace.
Hint 1 | The shape of a PodDisruptionBudget
A budget selects Pods by label and states how many must stay up, or how many may be down, during a voluntary disruption.
kubectl get pods -n shop --show-labels
kubectl explain poddisruptionbudget.spec
kubectl create poddisruptionbudget --help
Once it exists, check that it counts the Pods you expect:
kubectl get pdb -n shop
kubectl describe pdb <name> -n shop
Hint 2 | Draining a node
A drain cordons the node first, then evicts its Pods through the Eviction API, which is the API a budget guards. Some system Pods on the node can stop it before any eviction starts. The error names each one and the flag it needs:
kubectl drain --help
kubectl drain <node> <flags>
A drain that stops with an error has still cordoned the node.
Hint 3 | Reading what the drain prints
A refused eviction is not a failure. The drain retries every few seconds until the budget allows the next one. Watch the budget from a second terminal while the drain runs:
kubectl get pdb -n shop -w
kubectl get pods -n shop -o wide -w