Troubleshooting AWS EKS Pod Eviction Due to Node Pressure (DiskPressure)
Troubleshooting AWS EKS Pod Eviction Due to Node Pressure (DiskPressure)
Understanding and resolving pod evictions due to DiskPressure in AWS EKS is crucial for maintaining application stability and performance. This comprehensive guide provides a deep dive into the symptoms, root causes, and a step-by-step resolution process, coupled with best practices to prevent future occurrences. As a Senior Cloud Solution Architect, optimizing resource utilization and ensuring resilient Kubernetes operations is paramount.
Symptom Analysis & Root Causes
DiskPressure is a Kubernetes node condition indicating that the node's disk is running low on available space for either the image filesystem or the node's root filesystem. When this condition is met, the Kubelet will begin evicting pods to reclaim disk space, leading to service disruptions.
Key Symptoms of DiskPressure
- Pod Evictions: Pods on affected nodes transition to
Evictedstatus. - Node Conditions: Executing
kubectl describe node <node-name>will showDiskPressure: Trueunder the Conditions section. - Event Logs: Kubernetes events will report messages like "NodeHasDiskPressure" or "Failed to allocate new cgroup" for containers.
- Application Instability: Unresponsive applications, increased latency, or downtime due to evicted pods.
- Unable to Schedule Pods: New pods may fail to schedule on the affected node due to the
DiskPressuretaint.
Common Root Causes
- Excessive Log Accumulation: Application logs, container runtime logs (e.g., containerd/docker), or system logs (journald) consuming a large portion of the disk.
- Ephemeral Storage Mismanagement: Application pods generating large temporary files, caches, or process data without proper cleanup, exceeding their ephemeral storage limits (if defined) or simply overwhelming the node's disk.
- Large Container Images and Image Caching: Many large container images pulled over time accumulate in the image filesystem, especially without effective garbage collection or aggressive image pruning.
- Under-provisioned Disk Size: The underlying EC2 instance type (or custom AMI) might have a root volume too small for the workload and Kubernetes overhead.
- Kubelet Eviction Thresholds: Default Kubelet configuration for eviction thresholds might be too aggressive or misconfigured, leading to premature evictions.
- Volume Mounts Issues: Misconfigured persistent volumes or a large number of ephemeral emptyDir volumes that grow unbounded.
- Containerd/Docker OverlayFS Bloat: The storage driver's layers can accumulate significant data over time if not managed.
Step-by-Step Resolution Guide
Step 1: Identify Affected Nodes and Pods
First, pinpoint which nodes are experiencing DiskPressure and which pods are being evicted.
Look for DiskPressure: True in the node description and eviction events.
Step 2: SSH into the Affected Node
Obtain the public IP address of the affected node (e.g., from kubectl get nodes -o wide or AWS EC2 console) and SSH into it. For EKS nodes, typically use ec2-user with your EC2 key pair.
Step 3: Analyze Disk Usage on the Node
Once logged in, use standard Linux commands to identify which directories are consuming the most disk space.
Pay close attention to /var/log (system and container logs), /var/lib/kubelet (pods, volumes, image blobs), and /var/lib/containerd or /var/lib/docker (container images and writable layers).
Step 4: Clean Up Unnecessary Files and Data
Based on your findings in Step 3, proceed with targeted cleanup.
Clean Up Logs:
Clear old journald logs and application logs.
Clean Up Container Runtime Data (Caution Required):
Manually cleaning container runtime data should be done with extreme care, especially in production. Kubernetes is designed to handle this, but manual intervention can provide immediate relief.
Important: After manual cleanup, restart kubelet to re-evaluate disk space.
Step 5: Adjust Kubelet Eviction Thresholds (Temporary/Advanced)
While not a permanent solution, you can temporarily adjust Kubelet's eviction thresholds to buy time or tolerate slightly higher disk usage. This involves modifying the Kubelet configuration on the node.
Find the Kubelet configuration file, typically at /etc/kubernetes/kubelet/kubelet-config.json or passed via flags in /etc/systemd/system/kubelet.service.d/10-kubeadm.conf. For EKS optimized AMIs, parameters are often passed via the /etc/eks/bootstrap.sh script.
You would look for and modify parameters like:
Note: Modifying these settings directly on production nodes is risky. It's better to update your EKS node group's launch template or user data to persist these changes across reboots and scale-outs.
Step 6: Scale Up or Vertically Scale Nodes
If the disk pressure is a recurring issue, consider increasing the disk size of your EKS worker nodes or scaling out your node group.
- Increase Disk Size: Modify the launch template used by your EKS node group to provision larger root volumes (e.g., from 20GB to 50GB or 100GB). This often requires rolling out new nodes.
- Add More Nodes: Utilize Kubernetes Cluster Autoscaler or Karpenter to automatically add more nodes to your cluster, distributing the workload and disk consumption.
- Use Larger Instance Types: Some EC2 instance types come with larger default root volumes or NVMe SSD ephemeral storage (though ephemeral storage is generally not for persistence).
Step 7: Monitor and Verify
After applying fixes, continuously monitor the node and cluster status.
Ensure no new eviction events occur and that the node returns to a healthy state.
Best Practices for Prevention & Performance Optimization
Proactive Monitoring
- AWS CloudWatch: Monitor EC2 instance disk utilization metrics (e.g.,
DiskReadBytes,DiskWriteBytes,DiskUsageif agent installed). - Prometheus & Grafana: Deploy a robust monitoring stack to collect Kubelet metrics (
kubelet_node_config_error,node_filesystem_avail_bytes,node_filesystem_size_bytes) and create alerts for low disk space.
Resource Management
- Ephemeral Storage Limits: Define
requestsandlimitsforephemeral-storagein your pod specifications. This prevents a single misbehaving pod from consuming all node disk space.resources: limits: memory: "1Gi" cpu: "500m" ephemeral-storage: "5Gi" # Limit ephemeral storage to 5GB requests: memory: "512Mi" cpu: "250m" ephemeral-storage: "1Gi" # Request 1GB of ephemeral storage - Log Management: Implement centralized logging (e.g., AWS CloudWatch Logs, Fluent Bit to S3/ELK stack) and configure log rotation on nodes to prevent local disk bloat.
- Smaller Container Images: Use minimal base images (e.g., Alpine, distroless) to reduce the overall disk footprint of container images.
- Image Garbage Collection: Ensure Kubelet's image garbage collection is effectively configured (
--image-gc-high-threshold,--image-gc-low-threshold).
Node Group and Autoscaling
- Appropriate Node Size: Select EC2 instance types with sufficient root volume sizes for your workloads and Kubernetes overhead. Consider customizing the root volume size in your EKS node group's launch template.
- Cluster Autoscaler/Karpenter: Leverage these tools to automatically scale your node groups based on resource demand, ensuring sufficient capacity and preventing single-node saturation.
Storage Strategy
- Persistent Volumes: For data that needs to persist across pod restarts or that consumes significant disk space, use Persistent Volumes (PVs) backed by AWS EBS or EFS, rather than relying on ephemeral node storage.
Frequently Asked Questions (FAQs)
Q1: What is the difference between DiskPressure and MemoryPressure?
A: DiskPressure indicates that the node's disk space is critically low, primarily for the image filesystem or node's root filesystem, leading Kubelet to evict pods to free up disk. MemoryPressure, on the other hand, means the node is running low on available memory, which can also trigger Kubelet to evict pods based on their memory usage to reclaim RAM. Both are node conditions that affect pod scheduling and stability.
Q2: Can I disable pod eviction entirely to prevent service disruption?
A: While you can technically set Kubelet's eviction thresholds very high or disable eviction signals (--eviction-hard=""), it's strongly discouraged. Disabling evictions means that if a node runs out of critical resources like disk space or memory, it can become completely unstable, unresponsive, and even crash, leading to much worse service disruptions. Evictions are a protective mechanism to keep the node healthy and allow workloads to be rescheduled elsewhere. The correct approach is to address the root cause of resource exhaustion and manage resources effectively.
Q3: How do I calculate appropriate ephemeral storage limits for my pods?
A: Calculating ephemeral storage limits requires understanding your application's behavior.
- Monitor Usage: Deploy your application without explicit ephemeral storage limits initially (in a testing environment) and monitor its disk usage within the container using tools like
kubectl top pod <pod-name> --containers(though this mainly shows CPU/Mem) or by SSHing into a running container and usingdu -sh /tmp(or wherever it writes temporary data). - Analyze Logs/Caches: Identify how much space application logs, temporary files, and caches consume during peak operations.
- Buffer: Always add a buffer (e.g., 20-30%) above the observed peak usage to account for unforeseen spikes or growth.
- Iterate: Start with a reasonable limit, observe, and adjust as needed. Remember, setting limits too low can lead to pod evictions if the application exceeds them.