# kubectl cordon & drain: Command Reference for CI/CD

> Reference for kubectl cordon and drain: stop new pods on a node and safely evict running ones, the DaemonSet and PDB flags, and a node-rotation example.

Source: https://latchkey.dev/learn/command-reference/kubectl-cordon-drain-command-cli-reference  
Updated: 2026-06-26

Stop scheduling on a node, then safely evict its pods.

kubectl cordon marks a node unschedulable; drain cordons and then evicts pods honouring PodDisruptionBudgets; uncordon reverses cordon. Together they bracket node maintenance in automation. This reference covers the flags that keep a drain from hanging.

## Common flags and usage

- cordon <node>: stop new pods landing (running pods stay)
- drain <node>: cordon then evict pods via the eviction API
- --ignore-daemonsets: required; DaemonSet pods are not evicted
- --delete-emptydir-data: allow evicting pods with emptyDir data
- --timeout=5m: cap the drain so a PDB block fails the step
- uncordon <node>: make the node schedulable again

## Example

```shell
kubectl cordon ip-10-0-1-5
kubectl drain ip-10-0-1-5 --ignore-daemonsets \
  --delete-emptydir-data --timeout=5m
# ... node maintenance ...
kubectl uncordon ip-10-0-1-5
```

## In CI

A drain blocks on a PodDisruptionBudget ("Cannot evict pod ... violates the disruption budget") until another replica is Ready, so pass --timeout to fail instead of hanging. Always uncordon in a trap/finally block; a forgotten uncordon leaves the node piling up Pending pods.

## Using this in CI

A runner has no kubeconfig, no cached context, and no interactive auth. Every kubectl invocation in CI needs the context supplied explicitly, and most confusing CI failures here are the command running against the wrong cluster or no cluster at all.

```Terminal
# never rely on the ambient context on a runner
kubectl --context "$KUBE_CONTEXT" -n "$NAMESPACE" get pods

# confirm what you are actually connected to before mutating anything
kubectl config current-context
kubectl cluster-info

# fail fast instead of hanging on an unreachable API server
kubectl --request-timeout=30s get nodes
```

> Always set `--request-timeout` in CI. Without it an unreachable API server hangs until the job times out, which turns a thirty-second failure into a twenty-minute one.

## FAQ

### kubectl cordon & drain: Command Reference for CI/CD?

kubectl cordon marks a node unschedulable; drain cordons and then evicts pods honouring PodDisruptionBudgets; uncordon reverses cordon. Together they bracket node maintenance in automation. This reference covers the flags that keep a drain from hanging.

### In CI?

A drain blocks on a PodDisruptionBudget ("Cannot evict pod ... violates the disruption budget") until another replica is Ready, so pass --timeout to fail instead of hanging. Always uncordon in a trap/finally block; a forgotten uncordon leaves the node piling up Pending pods.

---

Latchkey runs CI/CD that repairs its own failures. Agent entry points: https://latchkey.dev/agent.txt, https://latchkey.dev/openapi.json, https://latchkey.dev/llms.txt
