kubectl drain: Evict Pods Before Node Work
kubectl drain marks a node unschedulable and evicts its pods so the node can be upgraded or removed safely.
Before patching or terminating a node, drain moves the workloads off it, honoring PodDisruptionBudgets so availability is preserved.
What it does
kubectl drain first cordons the node (no new pods schedule there), then evicts the running pods via the Eviction API, which respects PodDisruptionBudgets. DaemonSet pods and bare (unmanaged) pods need explicit flags because drain refuses to evict them by default.
Common usage
kubectl drain node-1 --ignore-daemonsets --delete-emptydir-data
# include unmanaged pods and set a timeout
kubectl drain node-1 --ignore-daemonsets --force --timeout=120s
# put it back in service afterward
kubectl uncordon node-1Options
| Flag | What it does |
|---|---|
| --ignore-daemonsets | Proceed even though DaemonSet pods stay |
| --delete-emptydir-data | Allow evicting pods that use emptyDir volumes |
| --force | Evict pods not managed by a controller |
| --grace-period=<s> | Override pod termination grace period |
| --timeout=<dur> | Give up if eviction is not done in time |
| --disable-eviction | Delete pods directly, bypassing the Eviction API/PDBs |
In CI
Use --timeout so an undrainable node fails the automation instead of hanging forever. Avoid --disable-eviction in shared clusters; it ignores PodDisruptionBudgets and can take a service below its minimum. Always pair drain with kubectl uncordon on success or rollback.
Common errors in CI
"error: cannot delete DaemonSet-managed Pods (use --ignore-daemonsets to ignore)" is the most common; add the flag. "Cannot evict pod as it would violate the pod\'s disruption budget" means a PDB has no allowed disruptions right now; wait, scale up first, or rethink the budget. "cannot delete Pods with local storage (use --delete-emptydir-data ...)" means emptyDir pods need that flag.