Cordon, Drain, and Uncordon Nodes
Safely remove workloads from OpenShift and Kubernetes nodes for maintenance. Cordon to prevent scheduling, drain to evict pods, uncordon to restore.
π‘ Quick Answer:
kubectl cordon <node>marks a node unschedulable (no new pods).kubectl drain <node> --ignore-daemonsets --delete-emptydir-dataevicts all pods.kubectl uncordon <node>restores scheduling. Always drain before hardware maintenance or OS updates.
The Problem
You need to take a Kubernetes node offline for maintenance (hardware repair, OS upgrade, kernel update, storage expansion) without disrupting running workloads. Simply powering off the node would kill pods ungracefully, potentially losing data and causing service outages.
The Solution
The Three-Step Process
# Step 1: Cordon β prevent new pods from scheduling on this node
kubectl cordon worker-3
# node/worker-3 cordoned
# Step 2: Drain β gracefully evict all pods to other nodes
kubectl drain worker-3 \
--ignore-daemonsets \
--delete-emptydir-data \
--force \
--timeout=300s
# Step 3: Perform maintenance...
# (hardware repair, OS update, reboot, etc.)
# Step 4: Uncordon β allow scheduling again
kubectl uncordon worker-3
# node/worker-3 uncordonedUnderstanding Each Flag
kubectl drain worker-3 \
--ignore-daemonsets \ # Skip DaemonSet pods (they belong to every node)
--delete-emptydir-data \ # Delete pods using emptyDir volumes (data will be lost)
--force \ # Delete pods not managed by a controller (bare pods)
--grace-period=30 \ # Seconds to wait for graceful termination
--timeout=600s \ # Abort drain if it takes longer than 10 minutes
--pod-selector='app!=critical' \ # Only drain pods matching selector
--dry-run=client # Preview what would happen (no actual eviction)Verify Node Status
# Check scheduling status
kubectl get nodes
# NAME STATUS ROLES AGE VERSION
# worker-1 Ready worker 30d v1.28.6
# worker-2 Ready worker 30d v1.28.6
# worker-3 Ready,SchedulingDisabled worker 30d v1.28.6 β cordoned
# Check what's still running on the drained node
kubectl get pods -A -o wide --field-selector spec.nodeName=worker-3
# Only DaemonSet pods should remaingraph LR
A[Normal Node] -->|kubectl cordon| B[Cordoned Node<br>SchedulingDisabled]
B -->|kubectl drain| C[Drained Node<br>No user pods]
C -->|Maintenance| D[Updated Node]
D -->|kubectl uncordon| E[Normal Node]
style B fill:#fef3c7
style C fill:#fee2e2
style D fill:#dbeafeOpenShift-Specific: oc adm drain
# OpenShift uses the same commands via oc
oc adm cordon worker-3
oc adm drain worker-3 --ignore-daemonsets --delete-emptydir-data --force --timeout=30m
oc adm uncordon worker-3Common Issues
Drain Blocked by PDB
error: Cannot evict pod as it would violate the pod's disruption budgetSee MCP Drain PDB Workaround for the fix.
Pods with Local Storage
error: cannot delete Pods with local storageAdd --delete-emptydir-data to allow eviction of pods using emptyDir.
Bare Pods (No Controller)
error: cannot delete Pods not managed by ReplicationController, ReplicaSet, Job, DaemonSet or StatefulSetAdd --force to delete bare pods (they wonβt be rescheduled anywhere).
DaemonSet Pods Remaining
DaemonSet pods are expected to stay β they run on every node by design. --ignore-daemonsets tells drain to skip them.
Best Practices
- Always do
--dry-run=clientfirst to see what will happen - Drain one node at a time in production β maintain capacity
- Set
--timeoutto avoid infinite hangs on PDB-blocked drains - Check PDBs before draining β
kubectl get pdb -Ashows allowed disruptions - Verify pods rescheduled after drain β check the other nodes
Key Takeaways
- Cordon prevents new scheduling; drain evicts existing pods
- Always use
--ignore-daemonsetsβ DaemonSet pods belong on every node - PodDisruptionBudgets are the #1 cause of stuck drains
- Use
--dry-run=clientto preview before committing - Uncordon after maintenance to restore the node to the scheduling pool

Recommended
Kubernetes Recipes β The Complete Book100+ production-ready patterns with detailed explanations, best practices, and copy-paste YAML. Everything in one place.
Get the Book βLearn by Doing
CopyPasteLearn β Hands-on Cloud & DevOps CoursesMaster Kubernetes, Ansible, Terraform, and MLOps with interactive, copy-paste-run lessons. Start free.
Browse Courses βπ Deepen Your Skills β Hands-on Courses
Courses by CopyPasteLearn.com β Learn IT by Doing
