kubernetes节点驱逐基于nodefs.available(根文件系统可用空间)和imagefs.available(镜像存储空间)两个独立指标,其中emptydir、hostpath等共享卷数据默认落在nodefs,而容器镜像与可写层归属imagefs;默认硬驱逐阈值分别为10%和15%,触发后kubelet立即驱逐pod并标记diskpressure污点。

直接看 imagefs.available 和 nodefs.available 两个指标的实际使用率,而不是只盯 df -h /。业务往共享卷(如 emptyDir、hostPath)写大文件,主要压的是 nodefs,但 kubelet 是否触发驱逐,取决于它配置的阈值和当前真实水位。
确认被压的是 nodefs,不是 imagefs
共享卷(比如 emptyDir、hostPath 挂载到 /data 或 /tmp)的数据默认落在节点根分区或其子挂载点上,属于 nodefs 范畴。而 imagefs 专指容器镜像和可写层所在的文件系统(通常是 /var/lib/docker 或独立磁盘)。排查时要分开查:
- 运行
df -h,重点看 Pod 共享卷所在路径的挂载点,例如/var/lib/kubelet/pods、/tmp、/data所在的设备 - 对比
kubectl describe node <node-name></node-name>输出中的Conditions和Allocated resources,留意是否出现node.kubernetes.io/disk-pressure:NoSchedule污点 - 检查 kubelet 日志:
journalctl -u kubelet -n 200 --no-pager | grep -i "eviction\|disk-pressure",找类似threshold [signal=nodefs.available, quantity=...]的行,确认是哪个信号触发的
查清共享卷实际落盘位置与用量
很多用户误以为 emptyDir 是“内存盘”,其实默认类型就是磁盘型(medium: ""),数据直写本地文件系统。要定位真实压力源:
- 用
kubectl get pod <pod-name> -o yaml</pod-name>查 volume 定义,确认是emptyDir{}还是hostPath{path: /xxx} - 登录对应节点,执行
find /var/lib/kubelet/pods -name "*<pod-uid>*" -exec ls -ld {} \; 2>/dev/null</pod-uid>,找到该 Pod 的挂载目录 - 进入该目录,用
du -sh * | sort -hr | head -5快速识别占用最大的子目录或文件 - 特别注意日志轮转缺失、临时文件未清理、归档包堆积等典型场景
验证 kubelet 驱逐阈值配置
驱逐不是凭空发生的,而是由 kubelet 启动参数或 config.yaml 中的 evictionHard 或 evictionSoft 控制。常见配置如下:
- 默认硬阈值通常为
nodefs.available 或 <code>"2Gi",软阈值可能设为"15%"+ 宽限期 - 查看实际配置:
ps aux | grep kubelet找--config路径,再读取该 YAML 文件中的evictionHard字段 - 若业务需长期写入大量临时数据,建议调高
nodefs.available硬阈值(如"15%"),并为系统预留空间(通过systemReserved)避免误伤
临时缓解与长期规避
紧急情况下不能只删文件,要同步解除污点并防止反复触发:
- 清理后,用
kubectl taint node <node> node.kubernetes.io/disk-pressure:NoSchedule-</node>手动移除污点(kubelet 一般会在下次检测达标后自动清除,但手动可加速恢复) - 对写密集型业务,改用
emptyDir{medium: Memory}(仅限小量缓存)或挂载独立 PV(如云盘、NAS),把 I/O 压力从 nodefs 上剥离 - 在应用层加大小文件限制、启用自动压缩/轮转、设置
lifecycle.preStop清理临时目录 - 通过监控告警(如 Prometheus 抓取
node_filesystem_avail_bytes{mountpoint=~"/var/lib/kubelet.*"})提前干预,别等驱逐发生










