Skip to content

Cordoning and draining nodes

Cordoning patches spec.unschedulable and nothing else, so it reads the same to every other tool.

A drain writes for minutes and reports as it goes, so it is a stream rather than a single call: one line per pod, as each one leaves.

Before anything happens, the app answers what a drain would do for the options you have chosen. When you start it, the drain re-derives that same plan itself — so the screen can never promise one thing and the app carry out another.

The drain dialog, naming how many pods would be evicted and how many are left alone.The drain dialog, naming how many pods would be evicted and how many are left alone.
The drain re-derives this same plan itself, so the screen cannot promise something else.

Pods are removed through the eviction API, which is what makes PodDisruptionBudgets matter. A 429 from the API server means “not now”, not “failed”, so the loop waits and retries against its own two-minute deadline per pod.

That loop deliberately runs outside the ordinary read timeout: a ceiling meant for a single read is the wrong ceiling for something whose job is to keep asking.

Stopping ends the stream at once and leaves the node cordoned. Undoing that is your decision, not the app’s — a drain you interrupted is rarely one you wanted fully reversed.

Budgets are listed as their own kind. A budget that allows no disruption reads Blocked, because a drain stops on it and no count says so on its own.

A node’s screen lists the pods actually on it, selected by spec.nodeName, along with its conditions, capacity and allocatable resources, and its usage charts.

A node detail page with its conditions, capacity, usage and the pods scheduled on it.A node detail page with its conditions, capacity, usage and the pods scheduled on it.
The pods listed are selected by spec.nodeName, not by a cluster-wide read.