KubernetesXXXII · Node Pressure and EvictionNode pressure and eviction
Disk pressure eviction — imagefs, logs, and the node filesystem
What you'll learn
- Trace the kubelet's disk eviction loop
- Distinguish imagefs from nodefs
- Configure the thresholds for the workload
- Diagnose a node that is in DiskPressure
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
Disk pressure eviction is the kubelet’s response to filesystem exhaustion. The kubelet distinguishes the node’s root filesystem (nodefs) from the runtime’s image filesystem (imagefs); the eviction is based on the worst signal. This lesson walks the detection, the eviction loop, and the operational patterns.
The two filesystems
The kubelet distinguishes two filesystems:
- nodefs: the node’s root filesystem. Default
/. Contains the kubelet’s data, the runtime’s mountpoints, and the logs. - imagefs: the runtime’s image filesystem. Default
/var/lib/containerdfor containerd. Contains the image cache.
The two may be on the same filesystem or on separate filesystems. The production pattern is to mount the two on separate volumes; the isolation prevents the image cache from filling the node’s root filesystem.
# /etc/fstab
UUID=abc /var/lib/containerd ext4 defaults 0 0
The kubelet’s configuration file can specify the imagefs path:
imagefs:
- path: /var/lib/containerd
The default is /var/lib/containerd for containerd.
The disk pressure thresholds
The kubelet’s disk pressure thresholds:
| Threshold | Default | Meaning |
|---|---|---|
nodefs.available | < 10% | Node filesystem is below 10% free |
nodefs.inodesFree | < 5% | Node filesystem is below 5% inodes free |
imagefs.available | < 15% | Image filesystem is below 15% free |
imagefs.inodesFree | < 5% | Image filesystem is below 5% inodes free |
The thresholds are the kubelet’s detection limits. The production rule is to set the thresholds to values that give the operator time to react.
The kubelet’s configuration:
# The `<` is part of the threshold expression, not a redirection,
# so each value has to be quoted.
kubelet \
--eviction-hard='nodefs.available<10%' \
--eviction-hard='imagefs.available<15%'
The thresholds are the bytes and inodes free. The percentages are converted to bytes by the kubelet.
The disk eviction loop
The kubelet’s disk eviction loop:
flowchart TD
A[Eviction loop] --> B[Check nodefs]
B --> C{Below threshold?}
C -->|Yes| D[Evict Pods by disk usage]
D --> E[Reclaim nodefs]
C -->|No| F[Check imagefs]
F --> G{Below threshold?}
G -->|Yes| H[Garbage collect images]
H --> I[Reclaim imagefs]
G -->|No| J[Done]
The loop distinguishes the two filesystems. The nodefs eviction is based on the Pod’s disk usage; the imagefs eviction is based on the runtime’s image cache.
The nodefs eviction
The nodefs eviction is based on the Pod’s disk usage. The kubelet tracks the Pod’s disk usage through the container’s writable layer and the Pod’s volumes.
The kubelet’s eviction order for the nodefs:
- BestEffort Pods: evicted first.
- Burstable Pods: evicted next.
- Guaranteed Pods: evicted last.
The eviction is the same as the memory eviction. The kubelet evicts the Pods based on the QoS class and the resource usage.
The imagefs eviction
The imagefs eviction is based on the runtime’s image cache. The kubelet’s image GC removes the least-recently-used images until the imagefs is below the threshold.
kubelet --image-gc-high-threshold=85
The image GC is the kubelet’s image cache management.
The kubelet’s --image-gc-high-threshold is the
upper bound; the kubelet’s --image-gc-low-threshold
is the lower bound.
The image GC is independent of the eviction loop. The image GC runs every 5 minutes; the eviction loop runs every 10 seconds.
The combined eviction
The kubelet’s eviction loop combines the nodefs and imagefs pressures. The eviction is based on the worst signal:
flowchart TD
A[Eviction loop] --> B[Read nodefs and imagefs]
B --> C[Calculate the worst signal]
C --> D{Below threshold?}
D -->|Yes| E[Evict Pods]
D -->|No| F[Done]
The worst signal is the filesystem that is the most constrained. The kubelet evicts the Pods based on the worst signal.
The log eviction
The kubelet’s log rotation is the disk pressure’s
front-line defence. The kubelet rotates the container’s
log file when the size exceeds the --log-file-max-size
(default 100Mi). The kubelet keeps at most
--log-file-max-count (default 5) log files.
A noisy container that fills the log file is rotated automatically. The kubelet’s log rotation is the safety net.
The volume eviction
The kubelet’s volume cleanup is the orphaned volume’s protection. The kubelet removes the orphaned volume directories after the Pod is evicted.
The volume cleanup is the kubelet’s last defence against orphaned volumes. A CSI driver that fails to clean up the volume is a volume that fills the node’s filesystem.
The disk pressure scenario
A node with 100Gi of nodefs is running 100 Pods with
1Gi of ephemeral-storage each. The kubelet’s
nodefs.available is 0. The node is in disk pressure.
flowchart TD
A[Node filesystem: 100Gi] --> B[100 Pods with 1Gi each]
B --> C[nodefs.available: 0]
C --> D[DiskPressure=True]
D --> E[Eviction loop]
E --> F[Evict Pods by disk usage]
F --> G[nodefs.available: 10Gi]
G --> H{Above threshold?}
H -->|No| I[Evict more Pods]
H -->|Yes| J[Done]
The eviction loop evicts the Pods based on the disk usage. The BestEffort Pods are evicted first; the Burstable Pods are next; the Guaranteed Pods are last.
The disk pressure’s diagnostic
A node in disk pressure has the DiskPressure=True
condition:
# Substitute your own node name:
NODE=node-18
kubectl describe node "$NODE" | grep -A 5 "Conditions"
Conditions:
Type Status Reason
---- ------ ------
DiskPressure True KubeletHasNoDiskSpace
The diagnostic:
journalctl -u kubelet | grep -i "disk"
df -h / /var/lib/containerd
The kubelet logs the eviction. The fix is to:
- Identify the workload. The kubelet’s logs show the evicted Pods.
- Investigate the workload. The Pod’s disk usage is the cause.
- Clean up the image cache. The runtime’s image cache may be filling the filesystem.
- Clean up the container logs. The container logs may be filling the filesystem.
- Add disk capacity. The cluster may need more disk.
The disk pressure’s metrics
The kubelet’s metrics expose the disk pressure:
# The kubelet's address; substitute your own node's IP:
NODE_IP=192.0.2.18
curl -k "https://$NODE_IP:10250/metrics" | grep disk
The relevant metrics:
kubelet_disk_evictions_totalkubelet_image_filesystem_available_byteskubelet_image_filesystem_capacity_byteskubelet_node_filesystem_available_byteskubelet_node_filesystem_capacity_bytes
The operator should monitor the metrics and alert on the eviction rate. A rising eviction rate is a cluster that is losing disk.
Quiz
Knowledge check · 4 questions
Q1. What does the kubelet do first when the image filesystem crosses its eviction threshold?
Q2. A node under DiskPressure evicts Pods before attempting to reclaim disk space by other means.
Q3. Explain a `DiskPressure` condition on a node whose filesystem is only 58% full, and clear it.
`node-18` reports `DiskPressure True` with reason `KubeletHasDiskPressure` and is evicting Pods. `df -h /` shows `412G 239G 173G 58% /`. `df -i /` shows `IUse% 100%`. The node runs a mail-processing Deployment whose Pods write one small file per message into an emptyDir; `find /var/lib/kubelet/pods -type f | wc -l` on the node returns over 19 million. `/` and `/var/lib/containerd` are on the same volume.
Q4. Name the four disk eviction signals, and say which filesystem the kubelet reclaims by garbage-collecting images rather than by evicting Pods.
Passing score: 75%. Answers are checked in this browser.
Production discipline
- Disk pressure is the cluster’s signal. The
kubelet’s
DiskPressure=Trueis the cluster’s signal that the node is exhausting disk. - The two filesystems are distinct. The node’s root filesystem and the image filesystem are separate. The production rule is to mount them on separate volumes.
- Tune the thresholds for the workload. The defaults are conservative; a production cluster may want to lower the thresholds.
- Monitor the eviction metrics. The cluster’s alerts should fire on the eviction rate. A rising rate is a cluster that is losing disk.
- Audit the disk usage at every release. A new workload that is using more disk than expected is a workload that needs investigation.
- Test the eviction in non-production. A staging cluster that mirrors production is the right place to test the eviction logic.