应直接查看nodefs.available实际水位而非仅执行df -h /,确认diskpressure污点是否真实触发,定位共享卷落盘位置(如/var/lib/kubelet/pods),区分nodefs与imagefs,核查kubelet驱逐阈值并按需调整。

直接看 nodefs.available 实际水位,而不是只跑 df -h / —— 大部分人卡在这一步就误判了根因。
确认 DiskPressure 是真触发,不是误报
节点上出现 node.kubernetes.io/disk-pressure:NoSchedule 污点,不代表一定空间不足,可能是 kubelet 误判或阈值过激:
- 用
kubectl describe node <node-name></node-name>查Conditions段,确认DiskPressure的Status确实是True,且LastHeartbeatTime是近期时间 - 检查
Allocated resources下的ephemeral-storage使用率,它和nodefs.available不是一回事,别混淆 - 运行
journalctl -u kubelet --no-pager -n 200 | grep -i "eviction\|disk-pressure",找类似threshold [signal=nodefs.available, quantity=10%]的行——这才是真正触发的信号和阈值
定位共享卷实际落盘位置和用量
业务往 emptyDir 或 hostPath 写大文件,压的是 nodefs,但具体落在哪块设备上,得手动挖:
-
kubectl get pod <pod-name> -o yaml</pod-name>查volumes定义,确认是emptyDir{}还是hostPath{path: /data} - 登录对应节点,执行
find /var/lib/kubelet/pods -name "*<pod-uid>*" -exec ls -ld {} \; 2>/dev/null</pod-uid>找到该 Pod 的挂载根目录(通常形如/var/lib/kubelet/pods/<uid>/volumes/kubernetes.io~empty-dir/<vol-name></vol-name></uid>) - 进该目录后,用
du -sh * | sort -hr | head -5快速揪出最大文件或子目录;特别盯日志文件(*.log)、归档包(*.tar.gz)、临时上传文件(/tmp/uploads/)
区分 nodefs 和 imagefs,避免查错分区
很多人一看到 DiskPressure 就去清 /var/lib/docker,结果发现空间没变化——因为那是 imagefs,而业务写入压的是 nodefs:
-
df -h输出里重点看/var/lib/kubelet/pods、/tmp、/data所在挂载点,不是只看/根分区 -
imagefs专指容器镜像与可写层所在路径(通常是/var/lib/docker或独立磁盘),由docker info或containerd config dump中的root配置决定 - 如果
df -h显示/var/lib/docker占用高但/var/lib/kubelet/pods所在分区还很空,那大概率不是你的业务导致的DiskPressure
验证并调整 kubelet 驱逐阈值
默认硬阈值 nodefs.available 对某些长期写入型业务太激进,但改之前必须确认真实瓶颈:
- 查 kubelet 启动参数:
ps aux | grep kubelet | grep -o '\-\-config=[^ ]*',再读取该 YAML 文件里的evictionHard字段 - 若确认是业务合理写入导致,可将
nodefs.available调至"15%"或加绝对值如"2Gi",但务必同步配置systemReserved(例如systemReserved: {"ephemeral-storage": "4Gi"}),否则系统进程可能被饿死 - 修改后重启 kubelet:
systemctl restart kubelet,再等 1–2 分钟观察污点是否自动清除(不会立即消失)
最常被忽略的一点:Pod 内部的 emptyDir 数据,在容器退出后仍保留在节点上,直到整个 Pod 被删除。这意味着一个反复 Crash 的 Pod,可能在节点上悄悄堆积数 GB 日志,而 kubectl logs 却只显示最新一次启动的内容。











