FR
live

Kubernetes 1.37 introduces five Node Lifecycle Conditions to signal drain and maintenance

On September 9, 2026, Kubernetes 1.37 reserved five well-known node conditions — DrainInProgress, Drained, MaintenancePlanned, MaintenanceInProgress, and GracefulNodeShutdownInProgress — giving teams a shared way to say why a node is unavailable. Start publishing them in your maintenance automation now, without waiting for core controllers to consume them.

A row of identical server blades in a rack, one blade pulled slightly out with its status LED glowing amber.

September 9, 2026. Kubernetes 1.37 introduces five well-known node conditions — DrainInProgress, Drained, MaintenancePlanned, MaintenanceInProgress, and GracefulNodeShutdownInProgress — behind an Alpha feature gate named NodeLifecycleConditions. The post is authored by Ryan Hallisey (NVIDIA), and it addresses a blind spot any cluster operator recognizes. Why it matters: today no native signal says why a node is unavailable — so independently correct controllers make contradictory decisions.

The problem: describing unavailability without saying why

Kubernetes already has many ways to describe what is happening to a node. Readiness, taints, Pod state, labels, annotations, and provider-specific APIs each expose part of the picture. What has been missing is a Kubernetes-owned way to say that a node is being drained, undergoing maintenance, or going through a Graceful Node Shutdown.

As a result, every component rebuilds its own understanding from indirect signals. One controller might look at node readiness, another at taints, another at Pods that are terminating or missing. Infrastructure providers bolt on their own labels and annotations. These signals remain useful for their intended purpose, but they do not answer the same question.

The difference is subtle and structural. A taint can influence scheduling or eviction, but it does not attest that a drain is in progress, nor that the administrator’s chosen drain criteria have been met. A NotReady node does not explain whether the cause is an unexpected failure, a graceful shutdown, or planned maintenance.

Five conditions to close the gap

Kubernetes 1.37 reserves five names as well-known NodeConditionType constants and introduces the NodeLifecycleConditions feature gate, disabled by default. The full picture:

ConditionWhat it reports
DrainInProgressThe node is actively being drained according to the administrator’s chosen criteria.
DrainedThe node has reached the drain criteria the administrator selected.
MaintenancePlannedA change is expected on the node in the future.
MaintenanceInProgressThe node is actively undergoing maintenance.
GracefulNodeShutdownInProgressGraceful Node Shutdown is in progress on the node.

Like other node conditions, each uses status to report whether the state is active — True, False, or Unknown — along with a stable, machine-readable reason and a message for human detail. An authorized maintenance controller can publish a state like this:

yaml
# A node's .status excerpt
status:
  conditions:
  - type: MaintenancePlanned
    status: "True"
    reason: MaintenanceWindow
    lastTransitionTime: "2026-12-09T12:00:00Z"
    message: "Hardware maintenance is scheduled for this Node"

A notable design point: in 1.37, the gate is a no-op. It does not restrict who may set these conditions, and no core component reads them yet. It exists so the built-in behavior planned for future releases — controllers that consume these conditions — can be opted into when it arrives. You do not need to enable it to start publishing the conditions today.

Sticking to the standard condition shape is also deliberate. Because these conditions use the same status/reason/message semantics as every other node condition, existing monitoring and alerting that already reads node conditions — from Prometheus exporters to fleet dashboards — can surface them with no new plumbing. The adoption cost is not a new API; it is deciding which automation writes them.

What maintenance and drain now look like

Maintenance covers hardware or software rollout, remediation, decommissioning, or debugging. Whether maintenance requires a drain depends on its impact: a Kubernetes upgrade usually should follow a drain, while a kernel live patch might not need one. The lifecycle conditions provide a common channel to surface that state without imposing a single operational procedure.

The immediate value is operational clarity. Maintenance automation can set MaintenancePlanned when a future window is scheduled, then MaintenanceInProgress when work starts. Drain automation can set DrainInProgress when eviction begins, then Drained once the criteria are met. GracefulNodeShutdownInProgress reports that a graceful shutdown is underway.

The recommended pattern separates responsibilities cleanly: conditions report state, while lifecycle operations remain handled by the existing mechanisms — kubectl cordon, kubectl drain, taints, and workload-specific controls. Conditions are not used to change scheduling or eviction; they make the state of that work visible to people, dashboards, alerts, and automation that choose to consume it.

Why a shared signal changes the outcome

Node lifecycle touches components across the cluster. The kubelet, node lifecycle controller, workload controllers, scheduler, autoscalers, storage operators, and external maintenance systems all need to understand what is happening to a node. Without shared context, individually correct components make contradictory decisions.

One concrete example shows the stakes. A DaemonSet controller can replace a Pod that the kubelet intentionally terminated during graceful shutdown. A Job controller can wait indefinitely for a terminal phase on a node an administrator is removing. A storage operator can learn about maintenance only after the drain has already begun. Each is right according to its own signals — and all of them contradict one another.

The sharpest case is a DaemonSet rolling update. A node that is broken or in maintenance can stay unavailable for reasons unrelated to the new revision. It still consumes the rollout’s availability budget, which can slow or block progress on healthy nodes. The controller knows the Pod is unavailable, but it cannot tell whether the new revision failed or an administrator took the node out of service. The MaintenanceInProgress condition creates a Kubernetes-owned place to publish that context — and future work can define how the controller uses it for ordering, availability accounting, and status reporting.

What platform teams should do

The conditions are publishable today, with no risk of breaking anything — the gate is a no-op and nothing reads them yet. That is exactly what makes them a good practice to adopt early.

  • Decide which component owns each condition — a single owner per condition avoids conflicting writes between automations;
  • Instrument your maintenance windows — set MaintenancePlanned at scheduling, MaintenanceInProgress at start, then flip to False (or remove the condition) when done;
  • Instrument your drains — set DrainInProgress when eviction starts and Drained when your criteria are met;
  • Use stable reason values and clear message text — both humans and automation must understand why the condition changed;
  • Do not change your control mechanisms — keep using kubectl cordon, kubectl drain, and taints for the action, and the conditions for visibility.

The work is tracked under KEP-5683, and the Node Lifecycle Working Group, SIG Node, and SIG Apps are explicitly soliciting feedback from maintainers of maintenance, remediation, drain, autoscaling, and fleet-management tooling.

Verdict

Kubernetes 1.37 does not yet solve the underlying problem — core controllers do not consume these conditions — but it lays the missing foundation: a shared, Kubernetes-owned vocabulary for saying why a node is unavailable. It is a deceptively quiet change whose value shows up at cluster scale, when components stop contradicting each other.

If you run a cluster in production, start publishing these five conditions in your maintenance and drain automation today. The cost is near zero — the gate is a no-op — and you prepare your tooling for the native behavior arriving in later releases, instead of having to catch up.

If you maintain an operator or lifecycle controller, integrate these conditions now and report your use cases to the working groups. This is the moment the API is settling, and your feedback directly shapes the form long-term coordination will take.

References

The cyber brief, every Tuesday

The flaws that matter and the patches to apply, in a ten-minute read.

No spam. One-click unsubscribe.
read next

On the same topic

OpenTofu crosses the tipping point as the default engine for new IaC workspaces

On Scalr’s platform, OpenTofu now runs 63% of Terraform-compatible runs and powers 72% of newly created workspaces — not a snapshot of the global market, but of where new work is heading. Version 1.12 adds dynamic prevent_destroy and full provider checksums. For teams provisioning infrastructure, new projects should default to OpenTofu.

Kubernetes 1.37 graduates gang scheduling to beta and adds CompositePodGroup

Kubernetes 1.37 (Garhwal) graduates the Workload and PodGroup APIs, gang scheduling and workload-aware preemption to beta, and introduces the CompositePodGroup API for scheduling hierarchical groups of Pods aimed at AI/ML and distributed computing. Teams running batch workloads can start evaluating this native foundation.

← Back to the feed

Type at least two characters.

navigate open esc dismiss