🎉 DevOps Interview Prep Bundle is live — 1000+ Q&A across 20 topicsGet it →
All Articles

Kubernetes Pod Evicted Due to Disk Pressure — Fix

Your pods are getting evicted with 'The node was low on resource: ephemeral-storage'. Here's why disk pressure evictions happen and exactly how to fix them.

DevOpsBoysJun 9, 20263 min read
Share:Tweet

Kubernetes evicts pods when a node is running low on disk space. The pod disappears with Evicted status and an event saying The node was low on resource: ephemeral-storage.


Understand What's Happening

Kubernetes has two disk-related eviction thresholds:

  • nodefs — the node's root filesystem (/var/lib/kubelet)
  • imagefs — where container images are stored (usually /var/lib/docker or /var/lib/containerd)

When either goes above the eviction threshold (default: 85% full), kubelet starts evicting pods — lowest priority first.


Step 1: Diagnose

bash
# Check node disk pressure condition
kubectl get nodes
# Look for: DiskPressure=True
 
kubectl describe node <node-name> | grep -A5 "Conditions:"
# Look for: DiskPressure True
 
# See which pods got evicted
kubectl get pods --all-namespaces | grep Evicted
 
# Check disk usage on the node
kubectl debug node/<node-name> -it --image=ubuntu -- df -h
# Or SSH into the node if you have access

Case 1: Container Logs Filling Disk

The most common cause. Containers writing massive logs fill /var/log/containers/.

bash
# Check log sizes on node
kubectl debug node/<node-name> -it --image=ubuntu -- \
  du -sh /host/var/log/containers/* | sort -rh | head -20
 
# Check if a specific pod is logging excessively
kubectl logs <pod-name> --tail=10 | wc -c

Fix 1: Add log rotation to container runtime

bash
# For containerd, edit /etc/containerd/config.toml on each node:
[plugins."io.containerd.grpc.v1.cri".containerd]
  [plugins."io.containerd.grpc.v1.cri".containerd.runtimes.runc]
    # Log rotation is handled by docker/containerd log driver
 
# For dockerd (older setups), /etc/docker/daemon.json:
{
  "log-driver": "json-file",
  "log-opts": {
    "max-size": "100m",
    "max-file": "3"
  }
}

Fix 2: Set log limits in pod spec

yaml
# Doesn't directly limit log size but limits resources:
resources:
  limits:
    ephemeral-storage: 2Gi   # Limits total ephemeral storage for pod

Case 2: Container Images Filling Disk

Old, unused images accumulate and fill the imagefs.

bash
# Check image disk usage
kubectl debug node/<node-name> -it --image=ubuntu -- \
  crictl images | head -30
 
# Auto-garbage collection is enabled by default in kubelet
# Check if it's working:
kubectl describe node <node-name> | grep -i "image"

Fix: Lower image GC thresholds in kubelet config

yaml
# /var/lib/kubelet/config.yaml on each node
imageGCHighThresholdPercent: 75   # Start GC at 75% (default 85%)
imageGCLowThresholdPercent: 60    # GC down to 60% (default 80%)

Or force immediate cleanup:

bash
# SSH to node
crictl rmi --prune   # Remove unused images

Case 3: emptyDir Volumes Filling Up

Pods using emptyDir volumes write data to node disk.

bash
# Check emptyDir sizes
kubectl debug node/<node-name> -it --image=ubuntu -- \
  du -sh /host/var/lib/kubelet/pods/*/volumes/kubernetes.io~empty-dir/* 2>/dev/null | sort -rh | head -20

Fix: Set size limit on emptyDir

yaml
volumes:
- name: temp-data
  emptyDir:
    sizeLimit: 500Mi   # Pod evicted if it exceeds this

Case 4: Node Root Filesystem Full

Not container-related — the node OS itself is running out of disk.

bash
# Check root filesystem
df -h /
# If / is > 80% full, it's OS-level disk usage
 
# Common culprits:
du -sh /var/log/* | sort -rh | head -10
du -sh /tmp/*
journalctl --disk-usage

Fix:

bash
# Clean journal logs
journalctl --vacuum-size=500M
 
# Clean apt/yum cache (on nodes you can access)
apt clean   # Ubuntu/Debian
yum clean all   # RHEL/CentOS

Long-Term Fix: Set Ephemeral Storage Requests/Limits

yaml
# In every pod spec — prevent runaway disk usage
resources:
  requests:
    ephemeral-storage: "500Mi"
  limits:
    ephemeral-storage: "2Gi"

When a pod exceeds its ephemeral-storage limit, it gets evicted — but only that pod, not everything on the node.


Prevent It: Monitoring

yaml
# Prometheus alert for node disk pressure
- alert: NodeDiskPressure
  expr: kube_node_status_condition{condition="DiskPressure",status="true"} == 1
  for: 5m
  annotations:
    summary: "Node {{ $labels.node }} has disk pressure"
 
# Alert before it gets critical
- alert: NodeFilesystemSpaceFilling
  expr: predict_linear(node_filesystem_free_bytes[6h], 24*3600) < 0
  annotations:
    summary: "Node filesystem will fill up in 24h"

Learn Kubernetes storage and resource management at KodeKloud.

🔧

Today I Fixed

Short real fixes from production — posted daily

Browse fixes
Newsletter

Stay ahead of the curve

Get the latest DevOps, Kubernetes, AWS, and AI/ML guides delivered straight to your inbox. No spam — just practical engineering content.

Related Articles

Comments