节点问题往往比 Pod 问题更“放大”。一个 Pod 出问题,影响可能只是一个实例;一个 Node 出问题,影响的可能是整台机器上的工作负载。Kubernetes v1.32 中,节点状态可通过 kubectl describe node 查看,其中最关键的是 Ready、MemoryPressure、DiskPressure、PIDPressure 等 Conditions,这些条件会直接影响调度、驱逐和服务稳定性::cite[393]。
9.4.1 Node NotReady 的排查步骤
Node NotReady 是最常见的节点异常之一。它不代表“节点一定宕机”,但至少说明控制面已经认为该节点当前不满足正常服务条件。
先建立全局视图
kubectl get nodes
kubectl get pods -A -o wide | grep worker-01
kubectl describe node worker-01
你要先回答几个问题:
- 是单个节点 NotReady,还是多个节点一起异常?
- 同节点上的 Pod 是否同步出现大量重建、驱逐、网络异常?
- 问题发生前是否有升级、重启、磁盘打满或网络波动?
标准排查顺序
第一步:看 Node Conditions
kubectl describe node 中最重要的是 Conditions 区域:
ReadyMemoryPressureDiskPressurePIDPressureNetworkUnavailable(是否出现取决于环境)
如果 Ready=False,通常还会伴随 Reason 和最近事件,帮助你判断是 kubelet 失联、节点资源异常,还是底层系统问题::cite[393]。
第二步:看 Pod 分布和受影响范围
kubectl get pods -A -o wide | grep worker-01
如果只有该节点上的新 Pod 无法调度,而老 Pod 还在运行,可能是节点被污点隔离或心跳异常;如果老 Pod 也在大量失败,往往说明问题更深,可能已经影响到 kubelet、容器运行时或节点系统资源。
第三步:看时间线
kubectl get events -A --sort-by='.metadata.creationTimestamp'
观察故障开始前后是否出现:
- 节点状态切换
- Pod 驱逐
- 挂载失败
- 容器运行时相关报错
NotReady 的常见根因
| 根因 | 常见表现 |
|---|---|
| kubelet 异常 | 节点心跳中断、Pod 状态更新失败 |
| 容器运行时异常 | Pod 无法创建、沙箱启动失败 |
| 节点网络中断 | API Server 无法与节点正常通信 |
| 系统资源耗尽 | 磁盘满、内存压力、PID 用尽 |
| 机器重启或内核故障 | 节点短时消失或长时间不可用 |
9.4.2 kubelet、容器运行时与系统资源异常
节点排障时,最重要的一个原则是:不要只看 Kubernetes 对象,还要把 kubelet、容器运行时和宿主机状态结合起来看。
一、kubelet 异常
kubelet 是节点和控制面的“联络官”。如果 kubelet 自己有问题,节点就可能变成 NotReady,或者 Pod 状态迟迟不更新。
在 Kubernetes 侧,你可以先看:
kubectl describe node worker-01
如果看到节点长时间没有心跳更新,或者事件里出现节点状态抖动,就要重点怀疑 kubelet 进程、证书、网络连通性或节点系统资源。
二、容器运行时异常
节点 Ready 不代表容器运行时一定健康。常见现象包括:
- Pod 一直创建不起来
- sandbox 创建失败
- 镜像拉取正常但容器启动失败
- 同节点多个 Pod 同时报运行时错误
这类问题的典型思路是:
- 先从 Pod 的
describe看事件 - 再从 Node 的
describe看整体状态 - 最后再落到节点侧检查 containerd / CRI-O 等运行时
三、系统资源异常会放大上层症状
很多表面上的“运行时问题”,根因其实是宿主机资源不足,比如:
- 临时目录满了,导致镜像解压失败
- inode 用尽,导致文件创建失败
- 内存压力太高,导致关键进程不稳定
- PID 过多,导致无法再 fork 新进程
所以在节点问题中,一定要有“系统视角”。
9.4.3 磁盘、内存、PID 压力导致的问题
Kubernetes 官方节点状态文档明确把 MemoryPressure、DiskPressure、PIDPressure 作为节点关键条件;这些条件一旦出现,就说明节点已经开始接近或进入不可持续状态::cite[393]。
一、内存压力
内存压力最常见的症状是:
- 新 Pod 调度受限
- 已有 Pod 被驱逐
- 业务抖动、重启增多
- 节点上多个服务同时不稳定
Kubernetes 对内存压力的处理还会与 QoS、污点和调度行为相关联。官方文档提到,控制面会根据节点条件自动施加相应污点,而某些非 BestEffort Pod 会自动拥有对应的内存压力容忍行为::cite[392]。
你可以这样观察:
kubectl describe node worker-01
kubectl top node
kubectl get pods -A -o wide | grep worker-01
二、磁盘压力
磁盘压力会带来很多“看起来不像磁盘问题”的现象:
- 容器日志写不进去
- 镜像拉取失败
- 临时文件写入失败
- Pod 被驱逐
因此,只要你看到:
- 大量
Evicted - 镜像相关异常
- 节点
DiskPressure=True
就应该优先检查:
- 镜像缓存是否过多
- 容器日志是否暴涨
emptyDir是否写爆- 节点临时目录是否不足
三、PID 压力
PID 是非常容易被忽略的节点资源。Kubernetes 官方在 PID 限制文档中专门说明,节点上的可分配 PID 也是一种基础资源;一旦进程数被打满,系统和工作负载都可能无法再创建新进程::cite[394]。
症状通常包括:
- 新进程无法启动
- 应用 fork 失败
- 容器创建异常
- 节点上守护进程行为异常
这类问题排查时,要特别警惕:
- 进程泄漏
- 僵尸进程堆积
- 大量短生命周期进程风暴
节点压力问题的统一排查法
kubectl describe node worker-01
kubectl top node
kubectl get pods -A -o wide | grep worker-01
kubectl get events -A --sort-by='.metadata.creationTimestamp'
先看条件,再看资源,再看受影响的 Pod,最后回到时间线验证是否和某次发布、批任务或流量高峰重合。
9.4.4 节点维护、驱逐与恢复策略
排障不只是“找到问题”,还要知道如何安全处置节点。
一、什么时候应该先维护、再深挖
如果节点已经明显不稳定,例如:
- 持续 NotReady
- 频繁磁盘或内存压力
- 容器运行时反复异常
- 某个节点上的服务持续抖动
那通常应优先考虑把业务从节点上迁走,再进行深度排查。
二、使用 cordon / drain 做维护
kubectl cordon worker-01
kubectl drain worker-01 --ignore-daemonsets --delete-emptydir-data
这两个动作的区别:
cordon:把节点标记为不可调度,不再接收新 Poddrain:在不可调度基础上,主动驱逐可迁移工作负载
适用场景:
- 节点准备下线维护
- 节点存在硬件或系统异常
- 想控制影响面,先把业务迁走
三、恢复节点时的基本步骤
当节点问题修复后,可以按下面顺序恢复:
- 确认 kubelet / 容器运行时恢复正常
- 确认 Node Conditions 回到健康状态
- 观察是否还有异常事件
- 解除不可调度状态
kubectl get node worker-01
kubectl describe node worker-01
kubectl uncordon worker-01
四、需要准备的工程化策略
成熟集群里,节点异常不应该总靠人工救火,至少要准备这些机制:
- 节点资源告警(内存、磁盘、inode、PID)
- kubelet / 容器运行时健康检查
- 自动化节点巡检
- 可中断工作负载与关键工作负载分层部署
- 合理的 PodDisruptionBudget
- 容量水位预警与扩容策略
五、必要时用 kubectl debug node
当问题已经明确落在节点侧,但仅靠对象视角看不清时,可以考虑使用节点调试能力。Kubernetes v1.32 的 kubectl debug 支持面向集群资源发起交互式调试,这对于查看节点命名空间、检查网络或临时执行诊断命令非常有帮助::cite[403]。
本章小结
节点异常处理的核心,不是盯着 NotReady 这个状态名,而是要迅速判断问题属于哪一层:
- 控制连接层:kubelet 是否还在正常汇报状态
- 运行时层:容器运行时是否还能创建与管理容器
- 资源层:内存、磁盘、PID 是否逼近极限
- 处置层:是否应先 cordon / drain,再修复与恢复
只要你建立了“节点条件 + 资源状态 + 业务影响面 + 维护动作”这套联动视角,节点问题就不再只是“看上去很大、实际上无从下手”的黑盒故障。
📝 版权声明:本文为原创技术博客,转载请注明出处。
如文章中存在错误或不准确之处,欢迎在评论区指正,感谢您的阅读与支持!