Node Draining and Cordoning in Kubernetes: Taking a Machine Out of Service Without Dropping Anyone

Node Draining and Cordoning in Kubernetes: Taking a Machine Out of Service Without Dropping Anyone

A complete, plain-English guide to cordon, drain, and uncordon: what each one really does, how eviction and disruption budgets protect your applications, why drains get stuck, and how to run safe maintenance and upgrades.

Imagine a hotel that needs to repaint the third floor. The manager cannot simply lock the doors and tell the guests to deal with it. First, the front desk stops giving out rooms on that floor, so no new guests arrive. Then staff politely help the existing guests move to rooms on other floors, a few at a time, making sure the hotel never becomes so crowded that service collapses. Only when the floor is empty do the painters come in. When they finish, the floor reopens. Cordoning and draining a Kubernetes node follow almost exactly this routine. Cordoning is the front desk stopping new arrivals. Draining is the careful, respectful relocation of everyone already staying there.

In this guide we will start from the very beginning. We will recall what a node is and how Kubernetes decides where to place work, and then build up the ideas of cordon, drain, eviction, disruption budgets, and graceful shutdown one step at a time. By the end you will know how to perform maintenance without outages, why drains sometimes hang forever, how cloud platforms and autoscalers use the same machinery, and what mistakes to avoid.

1What Are Cordoning and Draining?

Two small operations that let you retire or repair a machine in a controlled way.

A node is a single machine, physical or virtual, that runs your containers in a Kubernetes cluster. Sooner or later every node needs attention. It may need a new operating system patch, a kernel upgrade, a hardware replacement, a new version of the Kubernetes node software, or simply to be removed because you no longer need that much capacity. Doing any of these while the node is full of running applications would interrupt those applications. Cordoning and draining exist to avoid that interruption.

Cordoning a node marks it as unschedulable. The scheduler, which is the part of Kubernetes that decides where new Pods go, will stop placing new Pods on that node. Importantly, cordoning does not touch anything already running there. Existing Pods carry on exactly as before. Think of it as putting up a “No Vacancy” sign.

Draining a node goes a step further. It first cordons the node, and then asks every eligible Pod on that node to leave, politely and gradually. Pods that belong to a controller, such as a Deployment, are recreated on other nodes by that controller. When the drain finishes, the node is empty of ordinary workloads and safe to work on. Uncordoning is the reverse of cordoning: it removes the “No Vacancy” sign and lets new Pods arrive again.

Simple Analogy

A road crew repairing a bridge first puts up signs so that no new cars enter the bridge, which is cordoning. Then they guide the cars already on the bridge to the exits, which is draining. Only once the bridge is clear do the workers begin. When the repair is finished, the signs come down, which is uncordoning.

3
Core actions: cordon, drain, uncordon
0
Pods touched by a plain cordon
1
Safety net that guards drains: the disruption budget

These three operations are the daily bread of anyone who maintains a cluster. Even if you never type the commands yourself, managed upgrades, autoscalers, and automatic repair tools all perform cordon and drain on your behalf. Understanding them helps you design applications that survive these events gracefully.

2Why Nodes Need to Leave Service

Maintenance is not an exception in a cluster. It is a constant, planned part of life.

Nodes do not live forever. Operating systems need security patches. Cloud providers retire underlying hardware. New versions of the node agent bring fixes and features. Teams resize clusters as demand grows and shrinks. Some nodes simply misbehave, with failing disks or flaky networks, and need to be replaced. Because there are so many nodes, these events happen almost every day in a busy organization.

Reason 1

Operating system patching

Security fixes and kernel updates often need a reboot, which would kill every Pod on the machine without preparation.

Reason 2

Kubernetes version upgrades

Upgrading the node agent usually means restarting it and sometimes replacing the whole machine image.

Reason 3

Hardware or instance retirement

Cloud providers and data centers schedule events that will stop or move a machine at a known time.

Reason 4

Scaling the cluster down

When demand falls, extra nodes are removed to save money, and their work must move first.

Reason 5

Troubleshooting a bad node

A node showing odd behavior can be isolated so that no new work lands on it while engineers investigate.

Reason 6

Changing node types or pools

Moving workloads to a different machine size, a different zone, or a newer image requires emptying the old nodes.

i
Key Idea

The question is never whether a node will be removed. The question is whether the removal will be graceful or abrupt. Cordon and drain are how you make it graceful.

If you simply power off a node without draining it, Kubernetes will eventually notice that the node has stopped reporting, mark it as not ready, and then reschedule its Pods elsewhere. But that discovery takes time, often several minutes, during which users may see errors. A drain moves the work proactively and in a controlled order, so the applications keep serving traffic throughout.

3Foundations You Need First

A short refresher on the building blocks that cordon and drain rely on.

Term 1

Node

A machine in the cluster that runs Pods. Each node runs an agent called the kubelet that talks to the control plane.

Term 2

Pod

The smallest deployable unit, holding one or more containers that share a network address and storage.

Term 3

Scheduler

The control plane component that picks a suitable node for each new Pod.

Term 4

Controller

A program that keeps the real state matching the desired state, such as keeping three replicas alive.

Term 5

Taint

A mark on a node that repels Pods unless they carry a matching permission called a toleration.

Term 6

Eviction

A polite request, made through the API, to terminate a Pod so that it can be rescheduled elsewhere.

Simple Analogy

The cluster is a hotel chain. Nodes are hotel floors, Pods are guests, the scheduler is the front desk assigning rooms, controllers are the travel agents who make sure each group always has the right number of rooms booked, and a taint is a sign on the door saying “staff only unless you have a pass”.

How Pods Are Normally Placed

When you create a workload, the controller creates Pods, and each new Pod waits without a node. The scheduler examines all nodes, filters out those that cannot host the Pod because of resource shortages, rules, or marks like taints, and then ranks the remaining nodes before choosing one. The key point for us is that a node marked unschedulable is filtered out for ordinary new Pods. That single mark is what cordoning sets.

Controllers Bring Pods Back

A Pod managed by a Deployment, StatefulSet, ReplicaSet, or Job is not precious. If it is removed, its controller notices that the count is short and creates a replacement. The replacement is a brand-new Pod and it is placed by the scheduler on any suitable node, which, after a cordon, excludes the cordoned one. This is why draining works so well: it simply removes Pods and lets the controllers do what they always do.

!
Common Misconception

Draining does not “move” a Pod the way a virtual machine can be live-migrated. A Pod is deleted from one node and a new Pod is created on another. Anything that was only in the old Pod’s memory or local disk is gone, so applications must be designed for this.

4Cordon: Stop New Arrivals

Cordoning is the gentlest operation. It changes where future Pods go, not where current ones are.

When you cordon a node, Kubernetes marks that node as unschedulable. In practice, it sets a flag on the node object and also applies a built-in taint that tells the scheduler to avoid it for ordinary workloads. From that moment, no new Pod will be placed there, unless it is a special kind that tolerates the mark, such as certain system components.

1

Administrator cordons the node

A request is sent to the API server to mark the node as unschedulable.

2

Node status shows scheduling disabled

Listing nodes now shows the node as ready but with scheduling disabled.

3

Scheduler skips the node

All future placement decisions exclude this node for normal Pods.

4

Running Pods continue untouched

Nothing already on the node is stopped, moved, or restarted.

Simple Analogy

A restaurant host turns the “reserved” sign on a table. Diners already eating there are not disturbed, but nobody new is seated. The table can be cleared and cleaned once the current diners finish.

When Cordon Alone Is Enough

Investigating a suspicious node

If a node is behaving oddly, cordoning it prevents new work from landing there while you inspect logs and metrics, without disrupting what is already running.

Slow, natural drain-down

For nodes that run short-lived jobs, you can cordon and simply wait. As the jobs finish, the node empties by itself, with no forced eviction at all.

Staging a maintenance window

Cordon several nodes ahead of time so that capacity is already reserved elsewhere, then drain them one by one during the window.

Protecting capacity during an incident

Cordoning prevents a struggling node from being handed even more load while engineers work on the root cause.

i
Practical Advice

Always cordon before you do anything else on a node you plan to touch. Even if you do not intend to drain, cordoning stops the node from collecting new work that you would then have to move.

5Drain: Evict Everyone Politely

Draining is cordoning plus a careful, rule-respecting removal of the Pods.

A drain does two things in sequence. It first cordons the node so that no replacement Pods land there, and then it goes through every Pod on the node and asks each eligible Pod to leave using the eviction mechanism. The word “eviction” here is important, because it is different from simply deleting. An eviction request is checked against the rules you have set for your applications, particularly disruption budgets, and may be refused if granting it would hurt availability. The drain tool keeps retrying until the request is allowed or a time limit is reached.

flowchart TD
    S[Start drain on node] --> C[Cordon the node]
    C --> L[List Pods on the node]
    L --> F{Pod eligible for eviction}
    F -->|No| K[Skip or stop with a message]
    F -->|Yes| E[Send eviction request]
    E --> B{Disruption budget allows it}
    B -->|Yes| T[Pod terminates gracefully]
    B -->|No| R[Wait and retry]
    R --> E
    T --> N[Controller creates replacement on another node]
    N --> D{More Pods left}
    D -->|Yes| F
    D -->|No| Z[Node is empty and ready for work]
        
FIG 1 — The flow of a drain from cordon to an empty node

Which Pods Get Moved and Which Do Not

Not every Pod on a node can or should be evicted. The drain tool applies sensible rules, and stops with an explanation when it meets something it should not touch without your explicit permission.

Kind of PodDefault Drain BehaviorWhy
Managed by a Deployment, ReplicaSet, or StatefulSetEvicted and recreated elsewhereA controller will bring a replacement
Managed by a JobEvicted; the Job may create a new Pod to finish its workThe Job controller tracks completion
Managed by a DaemonSetDrain stops with a warning unless told to ignore DaemonSet PodsA DaemonSet would immediately recreate the Pod on the same node, so evicting it is pointless
Standalone Pod with no controllerDrain refuses unless forcedNothing will recreate it, so it would be lost for good
Pod using local temporary storageDrain refuses unless told that losing that data is acceptableThe data lives only on that node and will be deleted
Static or mirror PodSkippedThese are run directly by the node agent and cannot be removed through the API
!
Common Mistake

Forcing a drain of standalone Pods without checking what they are. If a Pod was created by hand and nothing manages it, a forced drain permanently deletes it. Always inspect what is on the node first.

6Uncordon: Reopen for Business

Once maintenance is complete, the node needs to be told it may receive work again.

Uncordoning removes the unschedulable mark and the built-in taint. The scheduler then considers the node again for new Pods. It is easy to forget this step, and a forgotten cordon is a classic cause of mysterious capacity problems: the cluster looks as if it has the right number of nodes, yet some are silently refusing work.

!
Common Mistake

Expecting Pods to automatically flow back to a freshly uncordoned node. They will not. Pods that were moved stay where they are. Only new Pods, created later, will consider the node. If you want to rebalance, you must use a rebalancing tool or restart workloads deliberately.

stateDiagram-v2
    [*] --> Schedulable: Node is healthy and open
    Schedulable --> Cordoned: Cordon applied
    Cordoned --> Draining: Drain begins
    Draining --> Empty: Pods evicted
    Empty --> Maintenance: Patch or upgrade
    Maintenance --> Cordoned: Node returns and is checked
    Cordoned --> Schedulable: Uncordon applied
    Empty --> Removed: Node deleted
    Removed --> [*]
        
FIG 2 — The lifecycle of a node during maintenance

Verify Before You Reopen

Before uncordoning, confirm that the node is truly healthy: that its status is ready, that the node agent is running the expected version, that networking and storage plugins are working, and that system Pods on it are healthy. Reopening a node that is only half fixed can cause a new wave of failing Pods. A good habit is to uncordon, watch the first few Pods that arrive, and be ready to cordon again if something looks wrong.

“Cordon early, drain carefully, verify thoroughly, uncordon deliberately.”

7The Eviction API and How a Drain Really Works

Let us open the hood and follow what happens to a single Pod during a drain.

Kubernetes offers two ways to remove a Pod. Plain deletion removes it immediately, regardless of consequences. The eviction API is a more careful way: it creates an eviction request for the Pod, and the API server checks whether granting it would violate any disruption budget that covers the Pod. If it would not, the Pod is deleted gracefully. If it would, the API server refuses with a “too many requests” style response, which tells the caller to try again later. The drain tool uses eviction for every Pod, which is why drains respect your availability rules.

sequenceDiagram
    participant Admin as Administrator
    participant Drain as Drain tool
    participant API as API Server
    participant Kubelet as Kubelet on node
    participant Ctrl as Controller
    Admin->>Drain: Request drain of node
    Drain->>API: Mark node unschedulable
    Drain->>API: Evict Pod A
    API->>API: Check disruption budget
    API-->>Drain: Allowed
    API->>Kubelet: Pod A marked for deletion
    Kubelet->>Kubelet: Run pre-stop hook and send termination signal
    Kubelet->>API: Pod A is gone
    Ctrl->>API: Create replacement Pod
    Drain->>API: Evict Pod B
    API-->>Drain: Refused for now, budget exhausted
    Drain->>Drain: Wait and retry
        
FIG 3 — Sequence of events when a drain evicts Pods

The Life of a Terminating Pod

1

Marked for deletion

The Pod receives a deletion timestamp and is removed from the lists of ready endpoints so that new traffic stops reaching it.

2

Pre-stop hook runs

If the Pod defines one, a small action runs first, such as waiting a few seconds for traffic to drain or telling a peer to take over.

3

Termination signal sent

Each container receives a polite request to shut down, giving the application a chance to finish in-flight work and close connections.

4

Grace period waits

Kubernetes waits for a configured number of seconds, thirty by default, for the containers to exit on their own.

5

Forced kill if needed

If a container is still running when the grace period ends, it is stopped forcefully, and any unfinished work is lost.

Simple Analogy

It is like a shop closing at the end of the day. First the sign flips to “closed” so new customers stop coming in. Then the staff finish serving the people already at the counter. They are given a fixed time to wrap up. Only if someone is still lingering when the time is up does security gently escort them out.

i
Design Tip

Make your applications listen for the termination signal and shut down cleanly: stop accepting new work, finish current requests, flush buffers, and exit. An application that ignores the signal will always be killed at the end of the grace period, with unpredictable results.

8Pod Disruption Budgets: The Safety Net

A disruption budget tells Kubernetes how much voluntary loss an application can tolerate at one time.

Kubernetes distinguishes two kinds of disruption. Involuntary disruptions are accidents, such as a machine crashing or a network failure. Voluntary disruptions are deliberate actions by an administrator or a tool, such as draining a node for an upgrade. A Pod Disruption Budget, usually shortened to PDB, applies only to voluntary disruptions that go through the eviction API. It says either “at least this many Pods must always be available” or “at most this many Pods may be unavailable at once”.

Simple Analogy

A hospital must always keep a minimum number of nurses on each ward. Managers can send nurses on training courses, but only if the ward stays above the minimum. A disruption budget is that minimum, enforced automatically.

Setting 1

Minimum available

Specifies how many Pods, as a number or percentage, must remain running and ready during voluntary disruptions.

Setting 2

Maximum unavailable

Specifies how many Pods may be down at once. Often easier to reason about as the application scales.

Setting 3

Selector

Chooses which Pods the budget protects, normally by matching the labels of one application.

Setting 4

Unhealthy Pod policy

Decides whether Pods that are already unhealthy can be evicted freely, which prevents a broken application from blocking maintenance forever.

flowchart LR
    A[Eviction request arrives] --> B{Is Pod covered by a budget}
    B -->|No| C[Allow eviction]
    B -->|Yes| D{Would available count drop below minimum}
    D -->|No| C
    D -->|Yes| E[Refuse and ask caller to retry]
    C --> F[Pod terminates gracefully]
    E --> G[Wait for replacement to become ready]
    G --> A
        
FIG 4 — How a disruption budget decides whether an eviction is allowed

Choosing Good Budget Values

The best value depends on how many replicas you have and how much capacity the application needs. For an application with five replicas that can run on three, a budget allowing two unavailable gives drains room to work without risking the service. For a single-replica application, any budget that requires that replica to stay available makes it impossible to drain its node at all, because the one Pod can never leave without breaking the rule. This leads to one of the most common reasons for stuck drains, covered later.

Good Budget Habits

  • Run at least two or three replicas of anything that matters.
  • Set the budget to leave a little room, so one Pod can always move.
  • Prefer the maximum unavailable form, which scales with replica count.
  • Match the budget selector exactly to the application’s Pods.
  • Combine budgets with readiness checks so replacements count only when truly ready.

Budget Mistakes

  • Requiring every replica to stay available, which blocks all drains.
  • Applying a budget to a single-replica workload.
  • Two overlapping budgets covering the same Pods, which Kubernetes refuses to honor.
  • Forgetting that budgets do not protect against crashes, only voluntary actions.

9Taints, Tolerations, and the Unschedulable Mark

Cordoning is built on the same mechanism that Kubernetes uses to repel Pods from nodes in many other situations.

A taint is a label on a node with an effect that discourages Pods. A toleration is a permission slip on a Pod that says “I am allowed on nodes with this taint”. There are three effects. The first prevents new Pods from being scheduled onto the node unless they tolerate it. The second prefers to avoid the node but does not forbid it. The third not only prevents new Pods but also removes existing Pods that do not tolerate the taint.

EffectNew PodsExisting PodsTypical Use
No scheduleBlocked unless toleratedUnaffectedCordoning a node, reserving nodes for special work
Prefer no scheduleAvoided if possibleUnaffectedSoft reservations
No executeBlocked unless toleratedEvicted unless tolerated, possibly after a delayNode failures, forced removal of workloads

Where Cordon Fits

When a node is cordoned, Kubernetes sets its unschedulable flag and adds a built-in no-schedule taint for unschedulable nodes. Ordinary Pods lack a toleration for it, so they stay away. Certain system Pods, such as those from DaemonSets, carry tolerations for this taint so they can still run on cordoned nodes, which is why per-node agents continue working during maintenance.

Cordon Versus a Custom Taint

Option 1

Cordon

The simple, standard way to stop new work from landing on a node, understood by every tool in the ecosystem.

Option 2

No-schedule custom taint

Lets certain Pods still land on the node if they tolerate your taint. Useful for partial maintenance or dedicated nodes.

Option 3

No-execute custom taint

Forces non-tolerating Pods off the node without going through the eviction API, so disruption budgets are not consulted. Use with great care.

!
Danger Zone

Taints with the no-execute effect remove Pods outside the disruption budget safety net. If you use them to empty a node, you can take down every replica of an application at once. Prefer a drain whenever availability matters.

10Drain Options Explained in Plain Words

The drain tool has a few important switches. Knowing what each does protects you from both surprises and stuck drains.

OptionWhat It DoesWhen to Use ItRisk
Ignore DaemonSetsLets the drain proceed even though DaemonSet Pods are present, and leaves them runningAlmost every drain, since DaemonSet Pods are meant to stayLow, because those Pods are node-level helpers
Delete temporary local dataAllows eviction of Pods that use local temporary storage, deleting that dataWhen the data is only a cache or scratch spaceData loss if the data mattered
ForceAlso removes standalone Pods that no controller managesOnly after you have confirmed those Pods are disposableHigh, as those Pods are never recreated
Grace period overrideOverrides each Pod’s own shutdown wait timeWhen Pods need more or less time than they ask forToo short a value kills Pods mid-work
TimeoutGives up if the drain has not finished in a set timeIn automation, to avoid waiting foreverLeaves the node partly drained
Pod selectorLimits the drain to Pods matching certain labelsFor partial, targeted evacuationNode is not fully emptied
Dry runShows what would happen without doing itBefore every important drainNone
Disable evictionUses plain deletion that ignores disruption budgetsOnly as a last resort in emergenciesVery high, can break availability
i
Practical Advice

Always preview with a dry run first. It lists the Pods that would be evicted and flags anything that would block the drain, giving you a chance to fix problems before they affect users.

A Careful Manual Routine

1

Check capacity

Make sure the rest of the cluster has enough free resources to absorb the Pods that will move.

2

Review what is on the node

List the Pods, noting standalone ones, those with local data, single-replica workloads, and stateful applications.

3

Cordon and preview

Cordon the node and run a dry run drain to catch problems early.

4

Drain with sensible options

Run the real drain with a timeout, watching that replacement Pods become ready on other nodes.

5

Perform the maintenance

Patch, reboot, upgrade, or replace the node.

6

Verify and uncordon

Confirm the node is healthy, then uncordon it and watch the first Pods that arrive.

11Why Drains Get Stuck

A drain that hangs is one of the most common maintenance frustrations. Almost every case falls into a handful of causes.

STUCK-01 Very Common
Problem

The drain keeps reporting that it cannot evict a Pod because doing so would violate a disruption budget.

Why It Happens

The budget demands that all or nearly all replicas stay available, or the application has only one replica, or other replicas are not yet ready so no capacity can be spared.

Correct Approach

Add replicas, relax the budget to allow one Pod to be unavailable, and confirm that replacement Pods can actually start and become ready on other nodes.

STUCK-02 Common
Problem

The evicted Pod stays in a terminating state for a long time and never disappears.

Why It Happens

The application ignores the termination signal and waits for the full grace period, or a finalizer on the Pod is waiting for something that never completes, or the node agent is unhealthy and cannot report that the Pod is gone.

Correct Approach

Handle the termination signal properly, shorten excessive grace periods, investigate any finalizers, and check the health of the node agent.

STUCK-03 Common
Problem

Replacement Pods stay pending, so the budget never frees up and the drain waits forever.

Why It Happens

The rest of the cluster lacks free resources, or strict placement rules prevent the Pod from running anywhere else, or a volume is tied to a zone that has no other suitable node.

Correct Approach

Add capacity before draining, review placement rules and zone constraints, and make sure every zone you depend on has enough spare nodes.

STUCK-04 Common
Problem

The drain refuses to start, complaining about standalone Pods, DaemonSet Pods, or local storage.

Why It Happens

These are safety checks that protect you from accidental data loss or from evicting Pods that would simply come back.

Correct Approach

Read the message, decide for each case whether the Pod is disposable, and use the matching option deliberately instead of reaching for force by habit.

STUCK-05 Occasional
Problem

The drain is blocked because the application is already unhealthy.

Why It Happens

A broken application has fewer ready Pods than its budget requires, so the budget refuses every eviction, and the broken Pods can never leave.

Correct Approach

Fix the application first, or use the unhealthy Pod policy that allows already unhealthy Pods to be evicted so they do not block maintenance.

i
Debugging Tip

When a drain stalls, read its output carefully. It names the Pod it is waiting on and the reason. Then look at that Pod’s budget, its controller, and its events. The cause is almost always visible within a minute or two.

12Special Workloads: Stateful, Single-Replica, and Batch

Not every Pod is a simple stateless web server. Some need extra thought during a drain.

StatefulSets and databases

Pods in a StatefulSet have stable identities and usually their own persistent volumes. During a drain, the Pod is removed, its volume detaches from the old node, attaches to the new node, and the Pod starts again with the same name. This takes longer than for stateless Pods, and the application must be able to rejoin its cluster safely. Disruption budgets are essential here so that a quorum is never lost.

Single-replica applications

An application with only one Pod will have downtime whenever that Pod is evicted, no matter how careful the drain. Accept short downtime, schedule it deliberately, or better, run at least two replicas for anything that must stay available.

Batch jobs and long-running tasks

Evicting a Pod in the middle of a long computation can waste hours of work. Options include cordoning the node and waiting for jobs to finish, designing jobs to save checkpoints, or scheduling maintenance when jobs are idle.

Workloads with persistent volumes tied to a zone

Many storage systems bind a volume to a single availability zone. A Pod using such a volume can only restart in the same zone, so each zone needs spare capacity to host the moved Pod.

Workloads using local disks

Pods that rely on disks physically attached to the node lose that data when moved. They need replication at the application level so another copy exists elsewhere.

Simple Analogy

Moving a stateless web Pod is like moving a cashier to another till, since any cashier can serve any customer. Moving a database Pod is like moving a surgeon mid-operation: it needs planning, backup staff, and a clear handover.

!
Common Mistake

Draining several nodes at the same time that each hold a replica of the same database. Even with a budget, rapid parallel drains can leave a stateful application without a healthy quorum. Drain nodes one at a time and wait for the application to recover between each.

13Designing Applications That Survive Drains

The best drain is one nobody notices. That depends mostly on how your applications are built.

Practice 1

Run multiple replicas

Two or more replicas mean one can leave while another keeps serving.

Practice 2

Spread across nodes and zones

Use anti-affinity or topology spread rules so replicas do not all sit on the same node, which would make a single drain take out everything.

Practice 3

Set a sensible disruption budget

Allow at least one Pod to be unavailable so drains can make progress, while protecting minimum capacity.

Practice 4

Use accurate readiness checks

A new Pod must only receive traffic once it is truly ready, or users will hit half-started replicas.

Practice 5

Handle the termination signal

Stop accepting new requests, finish existing ones, and exit within the grace period.

Practice 6

Add a short pre-stop delay

A brief wait lets load balancers and routing tables notice that the Pod is leaving before it stops accepting connections.

The Race Between Routing and Shutdown

There is a subtle timing issue. When a Pod is marked for deletion, the system begins removing it from the lists that route traffic to it, but that update takes a moment to reach every proxy and load balancer. If the Pod shuts down instantly, a few requests may still arrive at a Pod that is no longer listening, causing errors. A short delay before shutdown, often a few seconds, gives the network time to catch up so those stragglers are still served.

“Graceful shutdown is not about stopping fast. It is about stopping only when nobody still needs you.”
i
Design Tip

Pick a grace period longer than your slowest normal request plus the pre-stop delay. Too short and in-flight work is cut off. Too long and drains and rollouts crawl.

14Rolling Upgrades and Managed Platforms

Whenever a cloud platform upgrades your nodes, it is performing cordon and drain behind the scenes.

Managed Kubernetes services and node-management tools automate the routine you just learned. To upgrade a pool of nodes, they typically bring up new nodes with the new version, then cordon and drain old nodes one at a time or in small batches, wait for Pods to settle, and finally delete the empty old nodes. Because they use the eviction mechanism, your disruption budgets are respected, which is why well-defined budgets matter even if you never drain a node by hand.

flowchart TD
    A[Start upgrade of node pool] --> B[Add new node with new version]
    B --> C[Cordon one old node]
    C --> D[Drain the old node]
    D --> E{Drain succeeded within time limit}
    E -->|Yes| F[Delete old node]
    E -->|No| G[Pause or fail upgrade and alert]
    F --> H{More old nodes}
    H -->|Yes| B
    H -->|No| I[Upgrade complete]
        
FIG 5 — A typical surge-style rolling node upgrade
StrategyHow It WorksStrengthWatch Out For
Surge upgradeAdd extra new nodes first, then drain old onesCapacity never drops, so drains rarely starve the clusterTemporary extra cost
In-place rollingDrain one node, upgrade it, return it, repeatNo extra machines neededCapacity dips while each node is out
Blue-green node poolsCreate a whole new pool, move workloads, remove the old poolEasy to roll back by keeping the old pool for a whileDoubles capacity during the switch
Immutable replacementNever patch nodes; replace them with fresh imagesClean, repeatable, no configuration driftRequires strong automation
!
Platform Time Limits

Managed platforms often limit how long they will wait for a drain before forcing the node away, or failing the upgrade. A budget that blocks eviction for too long can therefore turn into a forced eviction or a failed upgrade. Check how your platform behaves and make sure your applications can always make progress.

15Autoscalers, Automation, and Reboot Tools

Many tools drain nodes on your behalf. Knowing them helps you predict what will happen to your Pods.

Cluster autoscalers

When demand falls, an autoscaler picks underused nodes, checks that their Pods can fit elsewhere, and removes them after draining. It respects disruption budgets, and it generally avoids nodes holding Pods that cannot be moved, such as standalone Pods or Pods with local storage, unless told otherwise.

Modern node provisioners

Newer provisioning tools continuously look for chances to consolidate workloads onto fewer or cheaper nodes, or to replace old nodes. They cordon and drain nodes as part of this, and they honor disruption budgets and annotations that mark Pods as not to be disrupted.

Automatic reboot daemons

Tools exist that watch for a signal that a node needs a reboot after patching, then safely cordon and drain it, reboot it, and uncordon it, limiting how many nodes are rebooted at once so the cluster stays healthy.

Maintenance operators

Operators can model maintenance as a resource. You declare “this node needs maintenance” and the operator cordons, drains, waits, and later uncordons, recording the progress in status.

Auto-repair features

Cloud platforms can detect unhealthy nodes and replace them automatically, draining first when the node is still responsive and forcing removal when it is not.

i
Protecting Special Pods

Most autoscaling and consolidation tools support a marker, usually an annotation on the Pod, saying “do not remove the node I am on”. Use it sparingly for work that truly cannot be interrupted, because overuse prevents the cluster from ever shrinking.

Controlling the Pace

Automation can drain many nodes quickly. To avoid harm, limit how many nodes can be disrupted at once, add delays between nodes, and run changes in maintenance windows for critical systems. Combining a sensible pace with disruption budgets keeps availability high even during large, fully automatic upgrades.

16Node Shutdown and Failure: When It Is Not Planned

Drain is for planned work. Here is what happens when a node goes away without warning, and how Kubernetes tries to help.

If a node crashes or loses its network, the control plane eventually notices that it has stopped reporting and marks it as not ready. After a waiting period, which is five minutes by default, Pods without a suitable toleration are evicted from the failed node by the node lifecycle controller and recreated elsewhere. This process is slower and rougher than a drain, because the node cannot cooperate: the Pods on it are not given a graceful shutdown.

Feature 1

Graceful node shutdown

When a node is shut down in an orderly way, the node agent can detect it and terminate Pods gracefully, giving ordinary Pods time first and important system Pods a bit more.

Feature 2

Non-graceful shutdown handling

If a node is truly dead but its Pods appear stuck, an administrator can apply a special out-of-service taint so that stateful Pods are force-removed and their volumes released.

Feature 3

Pod priority

During shutdown, critical system Pods are stopped last so that networking and storage remain available as long as possible.

Feature 4

Tolerations for not-ready nodes

Pods can set how long they tolerate a failing node before leaving, trading faster recovery against the risk of reacting to brief hiccups.

Simple Analogy

A planned drain is like an orderly fire drill where everyone walks out calmly in groups. A node crash is a real fire alarm with the power cut: people eventually get out, but it is slower, noisier, and some belongings are left behind.

!
Danger Zone

Never apply the out-of-service marker to a node that might still be running. If both the old and the new copy of a stateful Pod write to the same data at once, you risk corruption. Use it only when you are certain the node is powered off or isolated.

17Security and Access Control

The power to drain a node is the power to disrupt many applications at once. It deserves careful control.

Cordoning requires permission to update node objects. Draining additionally requires permission to list and evict Pods across namespaces. Anyone who holds these rights can take capacity away from the whole cluster or cause an outage for applications they do not own. In shared clusters, these permissions should be restricted to platform administrators and trusted automation.

Control 1

Limit who can modify nodes

Reserve node update rights for a small group and for the automation that needs them.

Control 2

Limit who can evict Pods

Eviction rights in other teams’ namespaces should not be broadly granted.

Control 3

Audit node operations

Record who cordoned, drained, or uncordoned which node, and when, using the cluster’s audit logs.

Control 4

Protect critical namespaces

Use admission policies to stop accidental or unauthorized disruption of essential system components.

Control 5

Use least-privilege automation

Give maintenance tools only the specific rights they need rather than full cluster administrator access.

Control 6

Review emergency overrides

Options that bypass disruption budgets should be rare, justified, and recorded.

!
Privilege Risk

Because Pods can be evicted and then rescheduled anywhere, a malicious or careless user with node control could force sensitive workloads onto nodes they influence. Treat node-level control as a highly privileged capability.

18Monitoring, Logging, and Metrics

You should always be able to see which nodes are cordoned, how a drain is progressing, and how applications are coping.

Signal 1

Cordoned node count

How many nodes are currently unschedulable. A node left cordoned for days is usually a forgotten step.

Signal 2

Pending Pods

A spike during a drain means the cluster lacks capacity to absorb evicted Pods.

Signal 3

Disruptions allowed

For each budget, how many more Pods may be evicted right now. Zero for long periods warns of future stuck drains.

Signal 4

Eviction events and errors

Records of evictions granted and refused, which reveal budget conflicts.

Signal 5

Application health during drains

Error rates, latency, and ready replica counts for applications while nodes are being emptied.

Signal 6

Terminating Pods

Pods that stay terminating for a long time indicate shutdown problems or node trouble.

Alerts Worth Having

Useful alerts include nodes that stay cordoned beyond an expected maintenance window, budgets that allow zero disruptions for an extended time, Pods stuck terminating, pending Pods after a node goes away, and sudden drops in ready replicas of important applications. These alerts catch both forgotten cleanup and hidden design problems before they turn a routine upgrade into an incident.

i
Observability Tip

Add maintenance events to your dashboards as markers on graphs. When latency shifts during an upgrade, you can immediately see which node was being drained and which Pods moved.

19Advantages, Disadvantages, and Trade-offs

Cordon and drain are powerful and safe when used well, yet they come with real constraints.

Advantages

  • Maintenance without visible downtime for well-designed applications.
  • Respects disruption budgets and graceful shutdown rules.
  • Works the same way across clouds, tools, and platforms.
  • Allows careful, reversible, step-by-step operations.
  • Forms the foundation for automated upgrades and scaling.
  • Gives engineers a safe way to isolate a misbehaving node.

Disadvantages and Trade-offs

  • Requires spare capacity elsewhere to absorb moved Pods.
  • Single-replica and stateful workloads still suffer interruptions.
  • Badly designed budgets can stall drains and upgrades.
  • Pods lose local data and in-memory state when moved.
  • Forgotten cordons silently waste capacity.

Cordon, Drain, and Their Neighbors

ActionStops New Pods?Moves Existing Pods?Respects Disruption Budgets?Typical Use
CordonYesNoNot applicableIsolating a node or preparing for maintenance
DrainYes, it cordons firstYes, through evictionYesSafe preparation for maintenance or removal
No-execute taintYesYes, after any delayNoForced removal of workloads
Delete node objectNode disappears from the clusterPods are cleaned up by the control planeNoRemoving a node that is already gone
Power off the machineNot directlyEventually, after failure detectionNoNot recommended for planned work
i
Rule of Thumb

If the node is alive and the work matters, drain it. If the node is already dead, there is nothing to drain, and you let the control plane recover the Pods or remove the node object.

20Best Practices, Anti-Patterns, and Common Mistakes

Habits that make maintenance boring, and traps that make it painful.

Best Practices

  • Cordon first, preview with a dry run, then drain.
  • Drain one node at a time and let applications recover in between.
  • Keep spare capacity so evicted Pods can land immediately.
  • Give every important application two or more replicas and a sensible budget.
  • Spread replicas across nodes and zones.
  • Make applications handle termination signals gracefully.
  • Verify node health before uncordoning, and always uncordon.
  • Use timeouts in automation so nothing waits forever.

Common Mistakes

  • Forcing drains out of habit and deleting standalone Pods.
  • Setting budgets that forbid any disruption.
  • Draining many nodes at once without checking capacity.
  • Forgetting to uncordon after maintenance.
  • Assuming Pods return to the node on their own.
  • Ignoring local data that will be lost.
  • Bypassing eviction to “make it faster” during an upgrade.
ANTI-PATTERN-01 Avoid
Problem

Teams routinely run drains with every override enabled, including force and disabling eviction, so that they never get stuck.

Why It’s Harmful

It removes every safety check, so budgets are ignored, standalone Pods vanish, and applications can lose all replicas at once.

Correct Approach

Use the safest options by default and add an override only after understanding exactly why the drain is blocked and what the override will remove.

ANTI-PATTERN-02 Avoid
Problem

Important applications run as a single replica, protected by a budget that requires it to be always available.

Why It’s Harmful

Every maintenance operation is blocked, so upgrades stall, engineers bypass safety checks, and the node pool slowly falls behind on patches.

Correct Approach

Run multiple replicas, or accept short planned downtime and remove the blocking budget for that workload.

ANTI-PATTERN-03 Avoid
Problem

All replicas of an application are scheduled onto the same node or the same zone.

Why It’s Harmful

One drain or one failure takes out the entire application, and budgets cannot prevent it because the Pods are all on the node being removed.

Correct Approach

Use spread rules and anti-affinity so replicas live on different nodes and zones.

ANTI-PATTERN-04 Avoid
Problem

Applications ignore the termination signal and rely on being killed at the end of the grace period.

Why It’s Harmful

Every drain takes the full grace period per Pod, in-flight requests are dropped, and data may be left half written.

Correct Approach

Handle the signal, finish current work, and exit promptly, with a suitably sized grace period and a short pre-stop delay.

21Frequently Asked Questions

Q1What is the difference between cordon and drain?

Cordon only stops new Pods from being placed on the node and leaves running Pods alone. Drain cordons the node and then evicts the Pods so they run elsewhere. Cordon is the first half of drain.

Q2Will draining a node cause downtime?

Not for applications with multiple replicas, good readiness checks, graceful shutdown, and sensible budgets. Single-replica applications will have a short interruption while their Pod restarts elsewhere.

Q3Do Pods come back to the node after uncordoning?

No. Uncordoning only allows new Pods to be placed there. Existing Pods stay on their new nodes until they are restarted or rebalanced by some other mechanism.

Q4Why does my drain say it cannot evict a Pod?

Usually because a disruption budget would be violated. The budget may demand too many available replicas, the application may have too few replicas, or replacement Pods may not be ready yet. Fix the budget, add replicas, or resolve what blocks the replacements.

Q5Are DaemonSet Pods drained?

By default the drain refuses to proceed because of them, since a DaemonSet would just recreate them on the same node. You tell the drain to ignore them, and they remain running, which is normally what you want.

Q6What happens to data stored on the node?

Temporary local storage is deleted when the Pod leaves, so the drain asks for your explicit permission. Data on persistent volumes survives, because the volume is detached and reattached to the new location, subject to zone and storage-system rules.

Q7Does a disruption budget protect against node crashes?

No. Budgets apply only to voluntary disruptions that go through the eviction mechanism. For crashes, you rely on replicas, spreading across nodes and zones, and fast recovery.

Q8Is it safe to drain several nodes in parallel?

It can be, if the cluster has plenty of spare capacity and applications are well spread, but it is safer to go one at a time, especially for stateful systems. Parallel drains multiply the chance of exhausting capacity or breaking quorum.

Q9Should I delete a node after draining it?

Only if you are permanently removing it. For maintenance, keep the node, perform the work, and uncordon it. If your platform replaces nodes rather than patching them, deleting the drained node is the normal final step.

Q10How long should a drain take?

It depends on the number of Pods and their grace periods. Many drains finish in a minute or two. Long drains point to large grace periods, stateful workloads, slow volume movement, or budgets that force waiting. Always set a timeout in automation.

22Summary and Key Takeaways

Cordoning and draining are how you take a node out of service without letting anyone down. Cordoning closes the door to new arrivals. Draining then walks the existing residents out, politely and in order, respecting the rules that keep your applications available. Uncordoning reopens the door when the work is done. Behind the scenes, the same machinery powers managed upgrades, autoscaling, node consolidation, and automatic repair, so understanding it makes you better at designing for the realities of a living cluster.

The safest clusters are not those that avoid maintenance but those whose applications expect it. Run several replicas, spread them out, give them sensible disruption budgets, make them shut down gracefully, keep spare capacity, and monitor the process. With those habits in place, draining a node becomes a calm, routine, almost invisible event rather than a nervous midnight gamble.

Key Takeaways

  • Cordon stops new Pods; drain also moves existing ones — cordon alone never touches running Pods, while drain cordons first and then evicts.
  • Eviction respects your rules — drains use the eviction mechanism, so disruption budgets and graceful shutdown periods are honored.
  • Budgets are a safety net, not a wall — set them to protect minimum capacity while always allowing at least one Pod to move.
  • Most stuck drains have a handful of causes — over-strict budgets, single replicas, pending replacements, slow shutdowns, and unmanaged Pods.
  • Design for movement — multiple replicas, spreading across nodes and zones, accurate readiness checks, and clean handling of the termination signal.
  • Pods do not return after uncordon — and a forgotten cordon quietly wastes capacity, so verify, uncordon, and monitor.
  • Treat node control as privileged — restrict who can cordon, drain, and evict, audit the actions, and avoid overrides that bypass safety checks.