Kubernetes集群搭建完成后,用kubectl get nodes查看节点状态时,如果看到某个节点长时间停留在NotReady,说明该节点上的工作负载无法正常调度。这个问题在CentOS系统上尤其常见,因为CentOS默认开启swap、防火墙策略严格,加上容器运行时和kubelet的cgroup驱动容易不一致,任何一个环节出问题都会导致节点失联。本文将系统梳理NotReady的排查思路和修复方法。

一、先弄清楚NotReady背后的判定机制
Kubernetes判断节点是否Ready,依赖的是节点上运行的多个组件协同工作:kubelet负责上报节点状态,容器运行时负责运行Pod,网络插件负责打通Pod之间的通信。当controller-manager在默认40秒内没有收到某个节点的状态心跳,就会把该节点标记为NotReady。
也就是说,NotReady只是最终的表现,它可能由kubelet挂了引起,可能是容器运行时异常,也可能是CNI网络插件没有正确部署。排查的第一步永远是拿到更详细的事件信息:
# 查看节点详情,重点看Conditions和Events部分 kubectl describe node <node-name> # 查看节点上kube-system的Pod是否正常 kubectl get pods -n kube-system -o wide # 登录到NotReady的节点上查看kubelet日志 journalctl -u kubelet -f --no-pager
在describe输出的Events区域,经常会看到类似KubeletNotReady的信息,后面通常跟着具体原因,比如container runtime not ready或者network plugin is not ready,这就是接下来排查的方向标。
二、CentOS特有的几个高发原因
1. swap没有彻底关闭
kubelet默认拒绝在开启swap的机器上运行,这是CentOS上最常见的原因。虽然安装文档里都会提到关闭swap,但很多人只执行了swapoff -a,重启机器后swap又会自动挂载回来。正确的做法是同时修改配置文件:
# 临时关闭 swapoff -a # 永久关闭,注释掉fstab中的swap行 sed -ri 's/.*swap.*/#&/' /etc/fstab # 验证,输出应该为空 free -m | grep -i swap
另外建议检查/etc/sysconfig/kubelet,确保没有设置KUBELET_EXTRA_ARGS=--fail-swap-on=false这种绕过参数,生产环境强行绕过swap检测会带来性能和稳定性风险。
2. cgroup驱动不一致
CentOS 7默认使用cgroup v1,而新版本Docker和containerd的默认cgroup驱动可能是systemd。如果kubelet配置的是systemd驱动,而容器运行时用的是cgroupfs驱动,kubelet会启动失败,日志里会出现failed to get container info之类的报错。修复方法是统一两端配置:
# 查看docker当前的cgroup驱动
docker info | grep -i cgroup
# 编辑 /etc/docker/daemon.json 统一为systemd
{
"exec-opts": ["native.cgroupdriver=systemd"],
"log-driver": "json-file",
"log-opts": {
"max-size": "100m"
}
}
# 重启docker
systemctl daemon-reload && systemctl restart docker如果使用containerd,则需要修改/etc/containerd/config.toml中SystemdCgroup = true,然后重启containerd服务。
3. 防火墙和SELinux拦截了通信
CentOS的firewalld会拦截flannel、calico等网络插件需要的端口,导致节点之间无法建立overlay网络。典型现象是master上节点显示NotReady,并且kube-system里的flannel或calico Pod不断重启。测试环境可以直接关闭防火墙:
systemctl stop firewalld systemctl disable firewalld # 临时关闭SELinux setenforce 0 # 永久关闭 sed -i 's/^SELINUX=enforcing$/SELINUX=permissive/' /etc/selinux/config
生产环境不建议直接关闭,而应该按需放行端口。flannel的VXLAN模式至少需要放行8472/UDP(节点间隧道)、2379和2380/TCP(etcd)、10250/TCP(kubelet API)、443/TCP(apiserver)。
三、网络插件与容器运行时的排查
1. CNI插件未正确部署
如果describe节点时看到network plugin is not ready: cni config uninitialized,说明CNI网络插件没有起来。先检查/etc/cni/net.d/目录下是否有配置文件,再确认kube-system命名空间下flannel或calico的Pod状态:
# 查看flannel pod日志 kubectl logs -n kube-system -l app=flannel --tail=100 # 查看daemonset是否在所有节点上都有实例 kubectl get ds -n kube-system
常见坑是flannel镜像在国外拉取超时导致Pod一直是ImagePullBackOff,解决办法是提前手动导入镜像或者配置国内镜像加速地址。
2. kubelet证书或配置问题
kubeadm环境下,节点证书过期或/var/lib/kubelet/config.yaml配置损坏也会导致NotReady。可以用kubeadm certs check-expiration检查证书有效期,过期的证书需要重新生成并重启控制面组件。同时确认kubelet.conf中指向的kubeconfig文件路径存在且内容正确。
3. 时间不同步引发的异常
节点之间时间偏差过大会导致证书校验失败,kubelet无法与apiserver建立连接。CentOS上建议安装chrony并确认时间同步状态:
yum install -y chrony systemctl enable --now chronyd chronyc sources -v timedatectl status
确保所有节点的系统时间偏差在秒级以内,虚拟机环境尤其要注意宿主机休眠后时间跳变的问题。
四、一套完整的排查清单
综合来看,遇到CentOS节点NotReady时可以按以下顺序快速定位:先看systemctl status kubelet确认kubelet进程是否存活;再看journalctl -u kubelet的最后几十行日志找直接报错;然后检查swap、防火墙、SELinux这三个CentOS特有的开关;接着核对容器运行时的cgroup驱动与kubelet是否一致;最后验证CNI插件的Pod状态和镜像拉取情况。
排查这类问题的核心思路是由近及远:从节点本机的服务状态入手,再到组件之间的连接性,最后看插件层面的配置。大多数NotReady问题都能在前两步找到答案,只要日志看得足够仔细,定位根因通常不超过十分钟。修复完成后用kubectl get nodes确认节点进入Ready状态,并观察几分钟确保状态稳定不再翻转即可。
KubernetesNotReadyCentOS修改时间:2026-09-15 18:20:32