- kubectl configured to talk to the target cluster.
- Basic familiarity with Pods, Deployments, DaemonSets, and node taints.
- Optional: set a short alias for kubectl to speed commands.
- Check nodes:
- Check deployments:
- Inspect pods and their node assignments:
- To prepare node01 for maintenance, use
kubectl drain. The first attempt may fail when DaemonSets are present becausekubectl draindoes not delete DaemonSet-managed pods by default:
- Re-run drain with
--ignore-daemonsetsto evict normal pods while leaving DaemonSet-managed pods running on the node:
- Verify the pods were rescheduled (in this environment, they move to the control plane node):
- The node is cordoned (marked
SchedulingDisabled):
- When maintenance is complete, make the node schedulable again:
- Verify node status:
SchedulingDisabled for node01.
Why pods did not move back to node01 automatically
- Kubernetes will not migrate already-running pods back to their original node after you uncordon it. The scheduler only places new pods; existing pods remain where they are until they are deleted or evicted and recreated.
- Example: after uncordon, pods may continue to run on the control plane:
- Control plane (master) nodes are commonly tainted to prevent scheduling of regular workloads. In this environment the control plane node has no taints, so regular pods were allowed to be scheduled there.
- Example excerpt from
kubectl describe node controlplane:
- If a Pod on the node is not managed by a controller (for example, it was created via
kubectl runor a plain Pod manifest),kubectl drainwill refuse to delete it because deleting an unmanaged Pod can result in permanent loss of local state:
- Inspect the pods on the node to find the unmanaged pod:
kubectl drainrefuses to delete pods not managed by a controller to avoid accidental deletion of stateful or locally-stored data. Controller-managed Pods (ReplicaSet, Deployment, StatefulSet, Job, DaemonSet) can safely be evicted because the controller will recreate them elsewhere.- You can override this behavior with
--force, but this will delete the unmanaged pod and may cause permanent data loss:
- Best practice: deploy critical applications using controllers (Deployment, StatefulSet, etc.) so they can be safely evicted and rescheduled elsewhere during maintenance.
- After converting
hr-appto a Deployment, verify controllers and pods:
- If you want to keep the existing critical
hr-apprunning on node01 but prevent any new pods from being scheduled there, usecordon(do not drain). Cordon marks the node unschedulable without evicting running pods:
- Confirm the node is cordoned:
Why convert single pods to controller-managed workloads?
- Controller-managed workloads (Deployments, ReplicaSets, StatefulSets) are recreated automatically if evicted or deleted. This enables safer maintenance and avoids manual intervention.
- If your workload stores local state that cannot be replicated, consider alternatives: StatefulSets with persistent volumes, relocating state to networked storage, or planning maintenance windows with careful backups.
- Use
kubectl drainto prepare a node for maintenance. Add--ignore-daemonsetsto skip DaemonSet-managed pods. kubectl drainwill refuse to delete Pods not managed by a controller;--forcewill override but is risky.- Convert critical single Pods into controller-managed workloads so they can be safely evicted and recreated.
- Use
kubectl cordonto prevent scheduling of new pods on a node while leaving existing pods running; usekubectl uncordonto restore scheduling.
- Kubernetes: kubectl drain docs
- Kubernetes: Managing pods and controllers
- Kubernetes: Taints and Tolerations
Always prefer controller-managed workloads for production-critical applications. This enables safe node maintenance without risking permanent loss of pods or local data.