集群中某个(或某些)节点的 STATUS 从 Ready 变成 NotReady,上面的 Pod 被驱逐并重新调度到其他节点。节点 NotReady 通常是 kubelet 与 API Server 心跳丢失,背后原因分散在 kubelet、容器运行时、网络插件、资源压力与证书等环节。
问题现象与背景原因
1 | kubectl get nodes |
节点 NotReady 的本质是 kubelet 无法再向 API Server 上报节点状态(NodeStatus / lease)。常见根因:
- kubelet 进程异常 / 退出:配置错误、kubeconfig 损坏、kubelet 证书过期、OOM 被杀。
- 容器运行时故障:containerd / docker 挂掉或无法启动,kubelet 连不上运行时(failed to connect to CRI)。
- CNI 网络插件异常:flannel / calico / cilium 相关 Pod 崩溃,节点网络不可达,触发
NetworkUnavailable。 - 资源压力触发驱逐:节点磁盘(
/var/lib/ 日志盘)或内存达到 kubelet 驱逐阈值,kubelet 主动标记DiskPressure/MemoryPressure。 - 网络分区 / 时间不同步:节点与 apiserver 之间网络中断,或系统时间漂移导致证书校验失败。
排查过程(思路与定位方法)
第一步:在集群侧看节点的 Conditions 与消息。 describe node 的 Conditions 会列出 KubeletReady、MemoryPressure、DiskPressure、NetworkUnavailable 等状态及原因:
1 | kubectl describe node node-2 |
重点关注 KubeletReady 的 message 和 reason,常能看到 kubelet stopped posting node status 之类线索。
第二步:登录故障节点,检查 kubelet 本身。 大部分 NotReady 根因在节点本地:
1 | systemctl status kubelet |
若日志出现 x509: certificate has expired → 证书过期;出现 failed to connect to CRI / connect: connection refused → 运行时没起来。
第三步:检查容器运行时与 CNI。
1 | # containerd |
第四步:检查资源压力与时间。
1 | df -h /var/lib |
提示:NotReady 多数不是「网络突然断了」这么简单。先看 kubelet 日志,再看容器运行时,再看 CNI,按这个顺序能最快收敛。
最终的解决方法
kubelet 起不来:根据
journalctl报错修复配置;证书过期用kubeadm certs renew或轮换 kubelet 证书;被 OOM 则调大节点内存或限制其他负载。容器运行时故障:重启运行时并设为开机自启:
1
2systemctl restart containerd
systemctl enable containerdCNI 异常:重启对应网络插件 DaemonSet / Pod,或重装 CNI 配置;确认
/etc/cni/net.d下只有一个插件配置生效,避免多个 CNI 互相覆盖。资源压力:清理磁盘(删除无用镜像
crictl rmi、清理容器日志)、扩容磁盘,或调整 kubelet--eviction-hard阈值。时间不同步:启用并同步 NTP(
chronyd/systemd-timesyncd)。
修复后确认节点回到 Ready:
1 | systemctl restart kubelet |
操作命令(可直接复制执行)
1 | # 1. 集群侧看节点状态与条件 |