当 Kubernetes 节点因 inode 被耗尽导致 Pod 无法调度或运行异常时,需结合 Kubernetes 特性和 Linux 系统管理方法处理。以下是详细步骤:
1. 确认 inode 耗尽
首先登录问题节点,检查 inode 使用率:
# 查看全局 inode 使用情况
df -i
# 输出示例:
Filesystem Inodes IUsed IFree IUse% Mounted on
/dev/nvme0n1p1 5242880 5242880 0 100% /var/lib/docker
若 IUse%
达到 100%,说明 inode 已耗尽。
2. 快速清理 inode
(1) 清理 Kubernetes 相关临时文件
终止状态的 Pod:
kubectl delete pod --field-selector=status.phase=Failed --all-namespaces
残留的容器和镜像:
# 清理未运行的容器和悬空镜像
docker system prune -af # Docker 运行时
crictl rmi --prune # Containerd 运行时
(2) 清理系统日志和 Pod 日志
Kubernetes Pod 日志:
# 清理 /var/log/pods 中的旧日志
sudo find /var/log/pods -name "*.log" -type f -mtime +7 -delete
系统日志:
sudo journalctl --vacuum-time=7d # 保留最近 7 天日志
sudo rm -rf /var/log/journal/* # 手动清理日志文件
(3) 清理 Docker/Containerd 存储
检查 Docker 存储目录:
sudo du -sh /var/lib/docker/overlay2/* | sort -rh
删除无效的容器层目录(确认无活跃容器使用后):
sudo rm -rf /var/lib/docker/overlay2/<hash>-*
3. 定位 inode 占用来源
(1) 查找小文件密集目录
# 统计根目录下各子目录的 inode 数量
sudo find / -xdev -type f | cut -d "/" -f 2 | sort | uniq -c | sort -nr
# 常见高 inode 目录: # - /var/lib/docker/overlay2(容器层) # - /var/lib/kubelet/pods(Pod 数据) # - /var/log/pods(Pod 日志)
(2) 使用 ncdu
工具可视化分析
sudo ncdu / # 扫描根目录
按 Enter
进入子目录,按 d
删除无用文件。
4. Kubernetes 相关配置优化
(1) 限制 Pod 日志大小
在 Pod 配置中限制日志卷大小:
apiVersion: v1
kind: Pod
metadata:
name: mypod
spec:
containers:
- name: mycontainer
image: nginx
volumeMounts:
- name: log-volume
mountPath: /var/log/nginx
volumes:
- name: log-volume
emptyDir:
sizeLimit: 100Mi # 限制日志目录大小
(2) 配置 kubelet 自动清理镜像
修改 kubelet 参数,定期回收未使用的镜像:
# 编辑 kubelet 配置文件(如 /etc/kubernetes/kubelet.conf)
--image-gc-high-threshold=85 # 当磁盘使用率超过 85% 时触发清理
--image-gc-low-threshold=80 # 清理至磁盘使用率降至 80%
5. 长期预防措施
(1) 监控 inode 使用率
部署 Node Exporter + Prometheus + Grafana:
-
通过 Node Exporter 采集节点 inode 指标。
-
设置告警规则(例如
node_filesystem_files_free{device!~"tmpfs"} < 1000
)。
(2) 定期清理任务
创建 CronJob 自动清理旧文件:
apiVersion: batch/v1
kind: CronJob
metadata:
name: log-cleaner
spec:
schedule: "0 0 * * *"
jobTemplate:
spec:
template:
spec:
containers:
- name: cleaner
image: alpine
command:
- /bin/sh
- -c
- find /var/log/pods -name "*.log" -mtime +7 -delete
restartPolicy: OnFailure
hostPID: true
hostNetwork: true
volumes:
- name: host-log
hostPath:
path: /var/log/pods
(3) 调整文件系统 inode 数量(谨慎操作)
如果节点磁盘允许重新格式化,可调整 inode 密度:
# 格式化 ext4 文件系统时指定更小的 inode 比例(增加 inode 总数)
mkfs.ext4 -i 8192 /dev/sdb1 # 默认 16384 bytes/inode
注意:此操作会清空磁盘数据,仅适用于新节点或非生产环境!
6. 扩展磁盘或迁移负载
-
扩容磁盘:直接扩展节点磁盘大小(云环境通常支持在线扩容)。
-
迁移 Pod:将 Pod 调度到其他节点:
kubectl drain <node-name> --ignore-daemonsets # 排空节点 kubectl uncordon <node-name> # 恢复节点
总结
-
应急处理:清理 Pod 日志、容器残留文件和系统日志。
-
根因分析 :通过
find
或ncdu
定位小文件密集目录。 -
预防措施:监控 inode、限制日志大小、定期清理任务。
-
终极方案:扩容磁盘或调整文件系统 inode 分配。