K8s节点磁盘占满导致Pod被驱逐(状态Evicted)并触发镜像GC,本质是imagefs空间不足引发kubelet被动清理;需准确定位nodefs/imagefs瓶颈、调优GC阈值(如high90%/low75%)、配合主动清理(crictl rmi --prune等)。

K8s 节点磁盘占满导致旧镜像被频繁驱逐,本质不是“镜像被驱逐”,而是 kubelet 因 imagefs 磁盘压力触发 Pod 驱逐 + 同步执行镜像垃圾回收。真正被“驱逐”的是 Pod(状态变为 Evicted),而旧镜像只是在 GC 过程中被顺带清理——但若配置不合理或空间持续紧张,就会陷入“刚拉新镜像、立刻删旧镜像、再拉再删”的恶性循环。
要稳定解决,需分三步:准确定位瓶颈、调优原生 GC、补充主动治理。
明确到底是哪块盘满了
Kubelet 不看 / 根分区,而是盯紧两个独立文件系统:
-
nodefs:存 Pod 日志、emptyDir、kubelet 自身数据(如/var/log、/var/lib/kubelet) -
imagefs:存容器镜像层(Docker 对应/var/lib/docker,containerd 对应/var/lib/containerd)
用这两条命令快速诊断:
# 查看 kubelet 认为的磁盘使用(含 nodefs/imagefs 分离统计) kubectl describe node <node-name> | grep -A 5 "Allocated resources" # 登录节点,查实际挂载点和使用率 df -hT /var/lib/docker /var/lib/containerd /var/lib/kubelet /var/log
⚠️ 常见误区:df -h / 显示还有 20% 空间,但 /var/lib/containerd 单独已 98% —— 这才是触发 imagefs.available < 15% 驱逐的真凶。
调整 kubelet 镜像 GC 参数,避免“高频抖动”
默认水位(高 85% → 低 80%)太窄,容易在 82%~84% 区间反复触发 GC。建议放宽阈值并延长保护期:
在 /var/lib/kubelet/config.yaml 中修改:
评估 Kubernetes 集群安全态势,覆盖 RBAC、工作负载安全、网络策略、基础设施即代码(IaC)、运行时监控和密钥管理等 30 项控制项……
imageGCHighThresholdPercent: 90 # 拉到 90% 再启动 GC,留出缓冲 imageGCLowThresholdPercent: 75 # 清到 75% 才停,避免刚清完又触发 imageMinimumGCAge: "10m" # 镜像至少存活 10 分钟才可被删(防 CI/CD 频繁更新误删)
改完重启 kubelet:
systemctl daemon-reload && systemctl restart kubelet
主动清理 + 防止镜像堆积
原生 GC 是被动兜底,必须配合主动手段:
-
定期清理无引用镜像(不依赖 GC 触发):
# containerd 节点(推荐) crictl rmi --prune # Docker 节点 docker image prune -af --filter "until=72h"
禁止保留历史镜像层:在 CI/CD 流水线中,构建时加
--no-cache --pull,推送前用docker system prune -f清本地缓存。限制单节点镜像数量:通过 admission webhook 或策略工具(如 Kyverno)拦截未打标签、无
org.opencontainers.image.source注解的镜像推送。
不复杂但容易忽略。

















