当你在管理一个Kubernetes集群时,最让人头疼的警报之一可能就是某个节点突然变成了“NotReady”状态。这就像你家里的一个智能设备突然离线了,整个系统都可能会受到影响。别担心,今天我们就来一起梳理一下,遇到这种情况时,我们该如何一步步排查和解决问题。我们会用尽量生活化的语言,结合具体的例子,让你即使不是Kubernetes专家也能看懂、学会操作。
一、先搞清楚状况:节点NotReady是什么意思?
想象一下,Kubernetes集群就像一个现代化的工厂,每个节点(Node)就是一条独立的生产线。当一条生产线显示为“NotReady”,就表示它暂时无法接收新的生产任务(调度Pod),或者上面正在运行的任务(已有Pod)可能已经出了问题。
首先,我们得确认一下状况。最直接的方法就是使用kubectl这个命令行工具来查看所有节点的状态。
技术栈:Kubernetes (kubectl)
# 查看所有节点的详细状态,这是我们的第一步诊断
kubectl get nodes -o wide
执行这个命令后,你可能会看到类似下面的输出。注意STATUS这一列。
NAME STATUS ROLES AGE VERSION INTERNAL-IP EXTERNAL-IP OS-IMAGE KERNEL-VERSION CONTAINER-RUNTIME
master-01 Ready master 50d v1.24.3 192.168.1.10 <none> Ubuntu 20.04.4 LTS 5.4.0-121-generic containerd://1.6.8
worker-01 Ready <none> 50d v1.24.3 192.168.1.11 <none> Ubuntu 20.04.4 LTS 5.4.0-121-generic containerd://1.6.8
worker-02 NotReady <none> 50d v1.24.3 192.168.1.12 <none> Ubuntu 20.04.4 LTS 5.4.0-121-generic containerd://1.6.8
看,worker-02的状态就是NotReady。这只是一个表象,我们需要知道具体原因。这时,可以查看该节点的详细描述信息。
# 查看问题节点的详细描述,这里通常会有错误信息或事件
kubectl describe node worker-02
在describe命令输出的最后部分,Conditions字段和Events字段是黄金信息源。你可能会看到诸如Kubelet stopped posting node status、Container runtime is down或网络相关的错误信息。这些就是我们的排查线索。
二、按图索骥:常见的故障原因和排查步骤
节点NotReady的原因多种多样,但通常逃不出下面这几个大类。我们可以按照从易到难、从外到内的顺序进行排查。
### 1. 网络连接问题
这是最常见的原因之一。Kubernetes节点之间、节点与控制平面(Master)之间需要持续通信。如果网络不通,节点就会被标记为NotReady。
- 如何排查?
- 从Master节点ping问题节点: 检查基础网络连通性。
ping 192.168.1.12 - 检查端口连通性: Kubernetes组件使用特定端口通信(如Kubelet的10250端口)。可以使用
telnet或nc命令。# 检查问题节点的Kubelet端口是否开放 telnet 192.168.1.12 10250 # 或者使用nc nc -zv 192.168.1.12 10250 - 检查节点本地防火墙: 登录到
worker-02节点,检查防火墙(如firewalld、iptables或ufw)是否屏蔽了必要的端口。# 例如,查看firewalld开放端口 sudo firewall-cmd --list-ports # 查看iptables规则 sudo iptables -L -n
- 从Master节点ping问题节点: 检查基础网络连通性。
### 2. Kubelet进程问题
Kubelet是运行在每个节点上的“节点代理”,负责与管理面通信并维护Pod。如果它挂了,节点必然NotReady。
- 如何排查?
- 登录问题节点,检查Kubelet服务状态:
# 查看Kubelet服务是否在运行 sudo systemctl status kubelet - 如果服务停止,尝试重启并查看日志:
# 重启Kubelet服务 sudo systemctl restart kubelet # 查看Kubelet的日志,寻找错误信息 sudo journalctl -u kubelet -f --since “5 minutes ago” - 常见Kubelet问题:
- 证书过期: Kubelet的客户端证书可能过期。日志中会有明显的“x509: certificate has expired or is not yet valid”错误。这通常需要从Master节点重新签发证书并分发。
- 配置错误:
kubelet.conf配置文件错误。可以对比正常节点的配置。 - 资源不足: 节点磁盘空间满(尤其是
/var分区),会导致Kubelet无法运行。使用df -h命令检查。
- 登录问题节点,检查Kubelet服务状态:
### 3. 容器运行时(Container Runtime)问题
Kubelet需要通过容器运行时(如Docker、Containerd)来真正操作容器。如果运行时出问题,Kubelet就无法工作。
- 如何排查?(以Containerd为例)
- 检查容器运行时服务状态:
sudo systemctl status containerd - 检查容器运行时与Kubelet的通信: Kubelet默认通过Unix socket(如
/run/containerd/containerd.sock)与Containerd通信。检查该socket文件是否存在且权限正确。ls -la /run/containerd/containerd.sock - 查看容器运行时日志:
sudo journalctl -u containerd -f
- 检查容器运行时服务状态:
### 4. 系统资源压力
如果节点内存或磁盘压力过大,Kubelet可能会主动停止工作,并将节点标记为有压力,但有时也可能直接导致NotReady。
- 如何排查?
- 登录节点,检查资源使用情况:
# 查看内存和交换空间使用情况 free -h # 查看磁盘使用情况 df -h # 查看CPU负载 top - 清理资源: 如果磁盘满了,可以清理Docker/Containerd的旧镜像、无用卷或日志文件。
# 清理Containerd未使用的镜像(谨慎操作) sudo crictl rmi --prune # 查看大文件 sudo find /var -type f -size +100M -exec ls -lh {} \;
- 登录节点,检查资源使用情况:
三、实战演练:一个完整的故障处理示例
假设我们收到了worker-02节点NotReady的告警。我们按照上面的流程来操作。
技术栈:Kubernetes (kubectl, systemd, Linux)
步骤1:确认状态并获取线索
# 在Master节点操作
kubectl get nodes
# 发现worker-02状态为NotReady
kubectl describe node worker-02
# 在Events部分看到一条关键信息:
# “Node worker-02 status is now: NodeHasDiskPressure”
# 同时Conditions里DiskPressure为True。
线索指向磁盘压力。
步骤2:登录问题节点深入排查
# 通过SSH登录worker-02节点
ssh user@192.168.1.12
# 检查磁盘使用情况
df -h
# 输出显示 /var 分区使用率100%
# Filesystem Size Used Avail Use% Mounted on
# /dev/sda1 50G 50G 0G 100% /var
# 查看/var目录下哪个子目录占用最大
sudo du -sh /var/* | sort -rh | head -10
# 发现 /var/lib/containerd 和 /var/log 非常大
步骤3:执行清理操作
# 1. 清理容器运行时未使用的镜像和缓存
sudo crictl rmi --prune
# 这会删除所有未被任何容器引用的镜像
# 2. 清理旧的系统日志(保留最近7天)
sudo find /var/log -type f -name “*.log” -mtime +7 -delete
# 也可以使用日志轮转工具如logrotate
# 3. 再次检查磁盘空间
df -h
# /var 分区有了一些可用空间,例如从0G变成了5G
步骤4:恢复节点服务
# 磁盘压力解除后,Kubelet可能不会自动恢复,需要重启
sudo systemctl restart kubelet
# 等待一两分钟,然后回到Master节点检查状态
# (在另一个终端或退出SSH)
kubectl get nodes
# 观察worker-02的状态是否从NotReady变回Ready
步骤5:事后分析与加固 故障解决了,但我们要防止它再次发生。
- 设置监控告警: 为节点磁盘使用率设置告警规则(例如>85%就告警),早发现早处理。
- 配置日志轮转: 确保
/var/log下的日志文件被正确轮转和压缩,避免无限增长。 - 调整Kubelet配置: 可以配置Kubelet在磁盘空间低于某个阈值时自动进行垃圾回收。
# 编辑Kubelet配置文件(例如 /etc/kubernetes/kubelet.conf) # 添加或修改如下参数(具体参数名请参考对应K8s版本文档) # --eviction-hard=memory.available<100Mi,nodefs.available<10%,imagefs.available<15% # --eviction-soft=nodefs.available<15% # --eviction-soft-grace-period=nodefs.available=2m # 修改后重启kubelet生效
四、关联技术:理解Kubernetes节点管理
为了更好地处理节点故障,了解一些背景知识很有帮助。Kubernetes通过几个核心组件协同工作来管理节点状态:
- Kubelet: 节点的“守护进程”,向API Server报告节点和Pod状态,并执行来自API Server的指令。
- Node Controller: 运行在控制平面(Controller Manager)中,负责监控节点状态。如果它长时间(默认为40秒)收不到某个节点的更新,就会将该节点的状态标记为
Unknown,随后若持续无响应(默认为5分钟),可能会将节点上的Pod标记为需删除(如果配置了--pod-eviction-timeout)。 - Conditions(状态条件): 节点通过
Conditions字段报告其健康状况,如Ready、MemoryPressure、DiskPressure、PIDPressure、NetworkUnavailable等。NotReady通常意味着Ready这个Condition的状态是False。
五、应用场景、优缺点、注意事项与总结
应用场景: 本手册适用于所有使用Kubernetes进行容器编排的环境,包括开发、测试和生产集群。无论是云上的托管K8s服务(如EKS, AKS, GKE)还是自建集群,节点NotReady都是运维人员必须掌握的故障处理场景。
技术优缺点:
- 优点: 本文提供的排查方法逻辑清晰,覆盖了绝大多数常见原因。采用从外到内、从服务到资源的排查顺序,效率高。结合具体命令和示例,可操作性强。
- 缺点: 无法覆盖所有极端或特定环境下的复杂故障(如特定内核bug、硬件故障、深度定制的CNI网络问题)。对于这些情况,需要更深入的专项知识和日志分析能力。
注意事项:
- 生产环境谨慎操作: 在重启Kubelet或容器运行时前,请评估该节点上运行的Pod是否重要,是否可以被迁移或容忍短暂中断。对于有状态服务,尤其要小心。
- 备份配置文件: 在修改任何配置文件(如
kubelet.conf)之前,务必进行备份。 - 理解上下文:
kubectl describe node和journalctl输出的日志是解决问题的关键,一定要学会阅读和理解其中的错误信息。 - 利用监控: 建立完善的监控体系(如Prometheus+Grafana),对节点资源、组件状态进行持续监控和告警,可以做到防患于未然。
文章总结: 处理Kubernetes节点NotReady状态,是一个系统性的排错过程。核心思路是“先观察,后动手;先外部,后内部;先服务,后资源”。记住这个排查路径:检查节点状态描述 -> 排查网络连通性 -> 检查Kubelet服务 -> 检查容器运行时 -> 检查系统资源(磁盘、内存)。通过本文提供的步骤和实战示例,你已经掌握了应对这一常见故障的“组合拳”。保持冷静,按部就班,你就能成为集群的可靠守护者。运维工作很多时候就是经验的积累,遇到并解决一次问题,你的技能树就又点亮了一盏灯。
评论