K8s Pod 卡在 NotReady 状态:深入排查与修复 image filesystem 容量异常

张开发
2026/5/11 4:39:02 15 分钟阅读
K8s Pod 卡在 NotReady 状态:深入排查与修复 image filesystem 容量异常
1. 问题现象集群节点集体罢工刚用sealos部署完Kubernetes集群满心欢喜执行kubectl get nodes结果所有节点清一色显示NotReady状态就像约好了一起罢工。这种场景下新手最容易手忙脚乱老司机则会先喝口水压压惊——因为90%的K8s部署问题都有标准排查流程。具体到这次故障节点状态显示如下NAME STATUS ROLES AGE VERSION sealos-k8s-node-01 NotReady control-plane,master 4m5s v1.22.0 sealos-k8s-node-02 NotReady none 2m39s v1.22.0 sealos-k8s-node-03 NotReady none 2m40s v1.22.0 sealos-k8s-node-04 NotReady control-plane,master 3m33s v1.22.0此时千万别急着重装系统我建议先执行三件套检查节点基础服务systemctl status kubelet containerd看核心服务是否存活网络插件状态kubectl get pods -n kube-system检查Calico/Flannel等网络组件日志抓取journalctl -xe -u kubelet --no-pager | grep -i error过滤关键错误2. 揪出真凶kubelet日志里的蛛丝马迹在节点上执行journalctl -xe -u kubelet后发现这样一条关键错误May 18 13:47:56 sealos-k8s-node-04 kubelet[5038]: E0518 13:47:56.386059 5038 kubelet.go:2332] Container runtime network not ready networkReadyNetworkReadyfalse reason:NetworkPluginNotReady message:Network plugin returns error: cni plugin not initialized这看起来像是CNI网络插件的问题但继续往下翻日志又发现了更致命的报错invalid capacity 0 on image filesystem这个image filesystem容量异常才是真正的罪魁祸首。它意味着kubelet无法正确读取容器运行时containerd/docker提供的镜像存储空间信息导致节点状态判断失误。就像你的手机显示存储空间不可用一样虽然实际空间充足但系统就是拒绝工作。3. 根因分析容器运行时与文件系统的爱恨情仇为什么会出现invalid capacity 0这种诡异报错经过多次实测和源码分析发现主要有三种常见诱因3.1 容器运行时服务异常containerd或dockerd服务虽然进程存在但可能因为某些原因处于僵死状态。这时候执行ctr images list可能会卡住或者返回空列表。这种情况在以下场景特别常见节点突然断电导致元数据损坏磁盘IO压力过大导致服务假死内核版本与容器运行时存在兼容性问题3.2 存储驱动配置冲突检查/etc/containerd/config.toml时会发现这样的配置段[plugins.io.containerd.grpc.v1.cri.containerd] snapshotter overlayfs如果实际系统使用的文件系统比如xfs与配置的snapshotter不匹配就可能出现容量检测异常。3.3 文件系统挂载问题在df -h输出中/var/lib/containerd所在分区如果显示异常挂载选项比如noexec或nosuid也会影响容器运行时的正常功能。我曾遇到过因为NFS存储挂载参数错误导致整个集群瘫痪的案例。4. 手把手修复从诊断到验证的全流程4.1 应急处理重启大法好对于生产环境紧急情况最快速的解决方案是systemctl restart containerd systemctl restart kubelet等待2分钟后检查节点状态kubectl get nodes -w这个方案虽然简单粗暴但实测有效率达到80%。就像电脑卡顿时首先会想到重启一样容器运行时服务重启往往能解决临时性状态异常。4.2 深度修复配置文件调优如果重启后问题依旧就需要修改containerd配置备份原配置cp /etc/containerd/config.toml /etc/containerd/config.toml.bak生成默认配置containerd config default /etc/containerd/config.toml调整关键参数[plugins.io.containerd.grpc.v1.cri.containerd] snapshotter overlayfs discard_unpacked_layers true [metrics] address 0.0.0.0:1338重新加载配置systemctl daemon-reload systemctl restart containerd4.3 终极方案文件系统检查与修复当上述方法都无效时可能是底层文件系统损坏卸载containerd数据目录umount /var/lib/containerd执行文件系统检查fsck -y /dev/sdX重新挂载并设置正确选项mount -o defaults,noatime,nodiratime /dev/sdX /var/lib/containerd重建containerd数据rm -rf /var/lib/containerd/* systemctl restart containerd5. 防患于未然运维最佳实践经过多次踩坑后我总结出以下预防措施监控配置给所有节点添加image filesystem使用率告警Prometheus配置示例- alert: ImageFSCapacityAbnormal expr: kubelet_node_name{jobkubelet} and kubelet_volume_stats_available_bytes{namespace!,persistentvolumeclaim!} / kubelet_volume_stats_capacity_bytes{namespace!,persistentvolumeclaim!} 0.1 for: 5m定期维护每月执行一次containerd maintenance操作ctr content gc ctr images prune --all版本兼容性确保内核版本、容器运行时、Kubernetes版本三者匹配参考这个兼容矩阵Kubernetescontainerd内核最低版本1.221.5.x4.141.251.6.x5.41.281.7.x5.10最后提醒大家遇到NotReady不要慌按照看状态→查日志→隔离问题→验证修复的流程大部分K8s问题都能快速定位。记住这个万能命令组合kubectl describe node 节点名 | grep -i ready journalctl -xe -u kubelet --no-pager | grep -i error systemctl status containerd -l

更多文章