Pod驱逐问题定位:从eviction事件入手
Kubernetes集群中Pod被驱逐(Evicted)是运维高频故障之一。驱逐的直接原因是节点资源压力触发了kubelet的eviction机制,但根因可能涉及内存限制配置、磁盘压力、PID耗尽等多种场景。排查Pod驱逐,第一步是拿到eviction事件的完整上下文。
# 查看集群中所有被驱逐的Pod
kubectl get pods -A --field-selector="status.phase=Failed" \
-o json | jq '.items[] | select(.status.reason=="Evicted") |
{name: .metadata.name, ns: .metadata.namespace, reason: .status.message}'
# 查看特定Pod的驱逐详情
kubectl describe pod <pod-name> -n <namespace> | grep -A 20 "Events"
# 检查节点资源压力状态
kubectl describe node <node-name> | grep -A 30 "Conditions"
驱逐事件通常包含一段message,指明触发驱逐的资源类型和阈值。
五大常见驱逐原因与修复方案
1. 内存压力(Memory Pressure)
最常见场景。当节点可用内存低于kubelet设定的阈值(默认硬阈值约100Mi),kubelet按QoS等级驱逐Pod:BestEffort先被驱逐,然后是Burstable,最后才是Guaranteed。
# 检查Pod内存限制是否合理
kubectl top pod -n <namespace> --sort-by=memory
# 查看Pod的requests/limits配置
kubectl get pod <pod-name> -n <namespace> -o json | \
jq '.spec.containers[] | {name: .name, resources: .resources}'
如果Pod的memory limit设置过低,容器内进程OOM后被kubelet判定为异常触发驱逐。反之,limit过高则挤占其他Pod空间。调优方法:通过Prometheus监控过去7天的P95内存用量,limit设为P95的1.2倍,request设为P95的0.8倍。
2. 磁盘压力(Disk Pressure)
节点文件系统空间不足时触发。常见于日志未轮转、容器镜像堆积、emptyDir大量写入等场景。
# 检查节点磁盘使用
kubectl describe node <node-name> | grep -A 5 "Allocated resources"
# 清理未使用的镜像和已退出容器
kubectl debug node/<node-name> -it --image=busybox -- \
sh -c "crictl rmp $(crictl ps -a -q --state Exited) 2>/dev/null"
3. PID耗尽
节点PID资源达到上限,新进程无法fork。多见于Sidecar注入过多、短生命周期进程频繁创建销毁。
# 检查节点PID使用
cat /proc/sys/kernel/pid_max
ps -e | wc -l
# 限制Pod的PID数量(Kubernetes 1.22+)
spec:
containers:
- name: app
resources:
limits:
example.com/pids: "1000"
4. Node NotReady导致的大面积驱逐
节点失联超过pod-eviction-timeout(默认5分钟)后,Controller Manager批量驱逐该节点上的所有Pod。这种情况根因通常在网络或kubelet进程异常。
5. 抢占式驱逐(Preemption)
高优先级Pod调度时,调度器主动驱逐低优先级Pod腾出资源。通过Pod Disruption Budget可以限制驱逐速率:
apiVersion: policy/v1
kind: PodDisruptionBudget
metadata:
name: app-pdb
spec:
minAvailable: 2
selector:
matchLabels:
app: my-app
监控告警体系:驱逐事件的提前预警
被动的驱逐后排查不如主动的告警预防。以下Prometheus规则覆盖了驱逐前的关键信号:
# 节点内存压力预警
- alert: NodeMemoryPressure
expr: |
(1 - node_memory_MemAvailable_bytes / node_memory_MemTotal_bytes) > 0.85
for: 3m
labels:
severity: warning
# 节点磁盘压力预警
- alert: NodeDiskPressure
expr: |
(1 - node_filesystem_avail_bytes{mountpoint="/"} / node_filesystem_size_bytes{mountpoint="/"}) > 0.85
for: 5m
labels:
severity: warning
# Pod驱逐事件监控
- alert: PodEvicted
expr: |
increase(kube_pod_container_status_restarts_total[30m]) > 3
labels:
severity: critical
资源限制调优的量化方法
资源限制调优不能凭感觉,需要基于真实负载数据做量化决策。一套可落地的流程:
1. 数据采集:在Prometheus中保留7天的容器资源指标,重点关注container_memory_working_set_bytes(实际使用内存)和container_cpu_usage_seconds_total(CPU累计使用)。
2. 分位数计算:对每个工作负载计算P50、P90、P95资源用量。
3. 限制设置公式:request等于P90值,limit等于max(P95乘以1.2, request乘以1.5)。这个公式在资源利用率和稳定性之间取得了较好的平衡——request保证调度时资源充足,limit允许突发但不会无限制挤占。
4. 定期复查:业务规模变化后,每月复查一次limit/request比例,避免配置漂移。
Pod驱逐不是随机事件,每一次驱逐都有明确的资源触发条件。从eviction事件定位资源类型,量化调整limit/request配置,再配合监控告警体系提前预警,驱逐问题可以从被动救火转为主动预防。
原创文章,作者:小编,如若转载,请注明出处:https://www.yunthe.com/kubernetes-rong-qi-bian-pai-zhong-pod-qu-zhu-pai-cha-cong/