Skip to main content
RunBook Academy

KubernetesXXXI · Node LifecycleNode lifecycle

Node conditions — Ready, MemoryPressure, DiskPressure, PIDPressure

Advanced⏱ ~17 minkubectl

What you'll learn

  • Identify the five canonical Node conditions
  • Trace the kubelet's role and the node controller's role in setting conditions
  • Apply the operational patterns for alerting on conditions
  • Diagnose a node in a non-Ready state

Prerequisites

Verified against Kubernetes 1.34.x · kubeadm 1.34.x · kubectl 1.34.x · etcd 3.6.x · CoreDNS 1.11.x · containerd 1.7.x / 2.x · 2026-08-16

Not yet marked complete on this device.

The Node object’s Status.Conditions is the cluster’s view of a node’s health. There are five canonical conditions: Ready, MemoryPressure, DiskPressure, PIDPressure, and NetworkUnavailable. Each has a status (True, False, or Unknown), a reason, and a message. This lesson walks the conditions, the observers that set them, and the operational patterns.

The five canonical conditions

stateDiagram-v2
    [*] --> Ready: kubelet registered
    Ready --> NotReady: kubelet fails
    NotReady --> Ready: kubelet recovers
    Ready --> Unknown: lease stale
    Unknown --> Ready: lease renewed
    Note right of Ready: MemoryPressure = False
    Note right of NotReady: MemoryPressure = False
    Note right of Unknown: conditions unclear

The conditions:

# Substitute your own value before running:
NODE=worker-03

kubectl describe node "$NODE" | grep -A 10 "Conditions"
Conditions:
  Type                 Status  LastHeartbeatTime                 Reason
  ----                 ------  -----------------                 ------
  Ready                True    2026-08-16T10:00:00Z              KubeletReady
  MemoryPressure       False   2026-08-16T10:00:00Z              KubeletHasInsufficientMemory
  DiskPressure         False   2026-08-16T10:00:00Z              KubeletHasNoDiskSpace
  PIDPressure          False   2026-08-16T10:00:00Z              KubeletHasInsufficientPID
  NetworkUnavailable   False   2026-08-16T10:00:00Z              KubeletReady

The conditions:

ConditionTrue meansFalse means
ReadyNode is healthy and servingNode is unhealthy or unreachable
MemoryPressureMemory is under pressureMemory is fine
DiskPressureDisk is under pressureDisk is fine
PIDPressurePIDs are under pressurePIDs are fine
NetworkUnavailableNetwork is not configuredNetwork is configured

The Ready condition is the primary signal. The other four are negative signals: True means there is a problem; False means there is no problem.

The Ready condition

The Ready condition is set by the kubelet (when the kubelet is healthy) and by the node controller (when the kubelet is unreachable).

The kubelet’s Ready:

NodeCondition {
  type: "Ready",
  status: "True",
  reason: "KubeletReady",
  message: "kubelet is posting ready status"
}

The kubelet updates the Ready condition every 10 seconds. The kubelet reports True when the runtime, the CNI, and the local services are healthy.

The node controller’s Ready:

NodeCondition {
  type: "Ready",
  status: "False",
  reason: "NodeStatusNeverUpdated",
  message: "kubelet has not reported ready status for 5m"
}

The node controller sets Ready=False when the kubelet’s lease is not renewed for the configured grace period. The controller’s Ready overrides the kubelet’s.

The cluster’s view of Ready is the most recent update. A kubelet that is healthy but whose lease is stale is Ready=False according to the node controller.

The MemoryPressure condition

The MemoryPressure condition is set by the kubelet. The kubelet checks the memory pressure periodically; if the kernel reports memory pressure (via the memory pressure threshold or the PSI metrics), the kubelet sets MemoryPressure=True.

The kubelet’s MemoryPressure:

NodeCondition {
  type: "MemoryPressure",
  status: "True",
  reason: "KubeletHasInsufficientMemory",
  message: "kubelet has memory pressure"
}

MemoryPressure=True triggers the kubelet’s memory eviction loop. The kubelet evicts Pods based on the Pod’s QoS class and the resource requests.

The MemoryPressure condition is a signal that the node is under memory pressure. The fix is to:

  • Add capacity.
  • Reduce the Pod’s memory requests.
  • Investigate the memory leak.

The DiskPressure condition

The DiskPressure condition is set by the kubelet. The kubelet checks the disk usage; if the usage exceeds the threshold (default 85% of the filesystem), the kubelet sets DiskPressure=True.

The kubelet’s DiskPressure:

NodeCondition {
  type: "DiskPressure",
  status: "True",
  reason: "KubeletHasNoDiskSpace",
  message: "kubelet has disk pressure"
}

DiskPressure=True triggers the kubelet’s disk eviction loop. The kubelet evicts Pods based on the Pod’s ephemeral-storage usage.

The DiskPressure condition is a signal that the node’s filesystem is filling. The fix is to:

  • Clean up the image cache.
  • Clean up the container logs.
  • Add disk capacity.

The PIDPressure condition

The PIDPressure condition is set by the kubelet. The kubelet checks the PID usage; if the ratio exceeds the threshold (default 0.5 of pid_max), the kubelet sets PIDPressure=True.

The kubelet’s PIDPressure:

NodeCondition {
  type: "PIDPressure",
  status: "True",
  reason: "KubeletHasInsufficientPID",
  message: "kubelet has insufficient PID"
}

PIDPressure=True triggers the kubelet’s PID eviction loop. The kubelet evicts Pods based on the Pod’s PID usage.

The PIDPressure condition is a signal that the node is exhausting the PID space. The fix is to:

  • Investigate the process that is consuming the PIDs.
  • Increase the kernel’s pid_max.
  • Reduce the Pod’s process count.

The NetworkUnavailable condition

The NetworkUnavailable condition is set by the node controller. The condition is True when the CNI has not yet configured the node.

The node controller’s NetworkUnavailable:

NodeCondition {
  type: "NetworkUnavailable",
  status: "True",
  reason: "NoRouteCreated",
  message: "node has no routes to Pods"
}

The condition is set to False when the CNI agent reports ready via the node-status update. The NetworkUnavailable=True is rare in production; it indicates a CNI failure.

The NetworkUnavailable condition is a signal that the node has no network connectivity. The fix is to:

  • Investigate the CNI plugin.
  • Investigate the network on the node.
  • Restart the CNI agent.

The condition transitions

The kubelet transitions the conditions based on the local state. The transition is recorded in the lastTransitionTime field:

NodeCondition {
  type: "Ready",
  status: "True",
  lastTransitionTime: "2026-08-16T09:00:00Z",
  reason: "KubeletReady"
}

The cluster’s kube_node_status_condition metric records the condition’s status. The lastTransitionTime is the time of the most recent transition.

The cluster’s controllers react to the transitions:

  • Ready=False → node controller adds the not-ready NoExecute taint.
  • MemoryPressure=True → kubelet evicts Pods.
  • DiskPressure=True → kubelet evicts Pods.
  • PIDPressure=True → kubelet evicts Pods.
  • NetworkUnavailable=False → node controller removes the NetworkUnavailable taint.

The condition’s reason field

The reason field is a short string that explains the condition. The standard reasons:

ConditionReason (kubelet)Reason (node controller)
ReadyKubeletReadyNodeStatusNeverUpdated, NodeStatusUpdated
MemoryPressureKubeletHasInsufficientMemory(not set)
DiskPressureKubeletHasNoDiskSpace(not set)
PIDPressureKubeletHasInsufficientPID(not set)
NetworkUnavailable(not set)NoRouteCreated, RouteCreated

The reason is the operator’s quick way to identify the cause. The cluster’s events complement the reason with the full message.

The alert thresholds

The cluster’s alerts should be based on the conditions:

# Alert: node is not Ready for more than 5 minutes
- alert: NodeNotReady
  expr: kube_node_status_condition{condition="Ready",status="true"} == 0
  for: 5m
  labels:
    severity: critical

# Alert: node memory pressure
- alert: NodeMemoryPressure
  expr: kube_node_status_condition{condition="MemoryPressure",status="true"} == 1
  for: 5m
  labels:
    severity: warning

# Alert: node disk pressure
- alert: NodeDiskPressure
  expr: kube_node_status_condition{condition="DiskPressure",status="true"} == 1
  for: 5m
  labels:
    severity: warning

# Alert: node PID pressure
- alert: NodePIDPressure
  expr: kube_node_status_condition{condition="PIDPressure",status="true"} == 1
  for: 5m
  labels:
    severity: warning

The for duration gives the cluster time to recover the node. The 5-minute threshold is a balance; lower thresholds produce more false positives, higher thresholds delay the alert.

Quiz

Knowledge check · 4 questions

  1. Q1. Which Node condition does the node controller own rather than the kubelet?

  2. Q2. `Ready=False` and `Ready=Unknown` describe the same situation from different components.

  3. Q3. Identify which component owns a node condition that is blocking Pod startup after a networking change.

    After rolling a new CNI DaemonSet version, 3 of 40 nodes show `NetworkUnavailable True` with reason `NoRouteCreated` while `Ready` is still `True` on all three. Pods scheduled to those nodes sit in `ContainerCreating`. `kubectl describe node node-17` shows `MemoryPressure False`, `DiskPressure False`, `PIDPressure False`, and a `node.kubernetes.io/network-unavailable:NoSchedule` taint. The CNI Pod on each of the three nodes is `Running` but its readiness probe is failing.

  4. Q4. Of the five canonical Node conditions, which does the kubelet set and which does the node controller set, and what does `status: "False"` mean on the four non-Ready conditions?

Passing score: 75%. Answers are checked in this browser.

Production discipline

  • The Ready condition is the primary signal. The cluster’s controllers react to Ready=False. The operator should alert on Ready=False for more than 5 minutes.
  • The pressure conditions are warnings. The MemoryPressure, DiskPressure, and PIDPressure conditions are warnings that the node is under pressure. The operator should investigate the cause.
  • The NetworkUnavailable condition is a signal of CNI failure. The condition is set by the node controller; the fix is to investigate the CNI.
  • Audit the conditions at every node repave. A new node that joins the cluster with a Ready=False condition is a node that is failing silently. The audit catches the failure.
  • The reason field is the cause. The reason identifies the condition’s cause. The operator should read the reason first.
  • The lastTransitionTime is the timing. The transition time is the time of the most recent change. The operator should review the transition history.