当集群开始报告 Kubernetes 节点 NotReady 时,经验丰富的运维人员都知道,故障影响范围往往会迅速扩大。一个工作节点一旦停止上报健康状态,就可能打乱调度、触发驱逐,并让业务负载进入不稳定状态。在真实的服务器租用和服务器托管环境中,最快的恢复方式并不是凭经验盲猜,而是有条理地检查节点状态、本地运行时健康状况、系统资源以及与控制平面的连通性。本文将围绕一套务实的恢复流程展开,面向希望获得高价值技术信息而非空泛描述的技术读者。

NotReady 在节点层面究竟意味着什么

在 Kubernetes 中,节点健康状态通过一组状态条件来发布,其中最关键的是 Ready。当这个条件切换为 False 时,说明该节点已不再被视为足够健康,无法继续正常接收新的工作负载调度。官方文档也指出,当 Ready 条件持续异常一段时间后,控制平面可能会为该节点添加 not-ready taint,这会影响调度行为,并根据 toleration 配置进一步影响正在运行的工作负载。

节点进入该状态的原因可能很多,但其底层机制很直接:

  • 节点代理停止上报健康状态。
  • 控制平面未能按预期收到心跳或租约更新。
  • 资源压力或网络异常将节点标记为不健康。
  • 调度器和控制器开始将该节点视为不可靠目标。

也就是说,NotReady 并不是根本原因,而是集群对外暴露出的症状。真正的任务,是找出最先失效的子系统,并恢复节点、本地运行时以及 API 端点之间最基础的信任链路。Kubernetes 官方文档介绍了节点心跳依赖状态更新与 Lease 对象,因此无论是代理健康还是网络路径,在排查中都至关重要。

导致节点进入 NotReady 的常见故障域

大多数故障事件都可以归入几个高度重复的类别。按照故障域来组织思路,可以显著缩短恢复时间,因为每一类问题都会在日志和状态条件中留下不同痕迹。

  • 节点代理故障:本地代理服务停止、卡死、配置错误,或无法完成认证。
  • 容器运行时异常:运行时套接字不可用、服务宕掉,或运行时接口配置错误。
  • 网络路径问题:节点无法访问 API 端点、DNS 出现故障,或覆盖网络不健康。
  • 资源压力:磁盘、内存或进程资源压力使节点进入降级状态。
  • 启动或维护漂移:节点重启后,服务启动顺序、证书或配置文件未能正确恢复。

官方节点状态说明列出了常见条件,例如 DiskPressure、MemoryPressure、PIDPressure 和 NetworkUnavailable。这些条件往往是排查的第一条线索,因为它们能在无需深入取证的前提下快速缩小问题范围。

先做最高信噪比的快速检查

首轮排查的目标只有一个:判断该节点是被隔离了、被压垮了,还是内部组件本身已经失效。不要一上来就重启。重启虽然看似简单,却可能掩盖原始故障特征;而如果存储、网络或证书本就处于异常状态,盲目重启还可能让恢复更复杂。

  1. 先确认节点是 NotReady 还是 Unknown。
  2. 检查节点状态条件与最近事件。
  3. 确认节点代理服务是否处于活动状态。
  4. 确认容器运行时是否处于活动状态且可访问。
  5. 检查磁盘、内存、inode 以及进程压力。
  6. 从节点测试到 API 端点的可达性。
  7. 仅在基础项都通过后,再深入检查网络组件。

通常一组简短的命令就足以提供足够上下文,帮助你选择正确的修复分支:

  • kubectl get nodes
  • kubectl describe node <node-name>
  • systemctl status kubelet
  • journalctl -u kubelet -xe
  • systemctl status containerd
  • df -h 和 free -m

如果节点代理仍在运行,却无法维持注册状态,那么日志通常会指向认证、运行时或网络问题。如果节点代理已经停止,应优先恢复它。如果节点代理健康而运行时已经失效,则先修复运行时。这一顺序非常关键,因为仅仅恢复健康的运行时,并不能让节点重新变为 Ready;节点代理必须能够重新向上游成功汇报状态。Kubernetes 运行时文档同样指出,如果运行时接口不可用或配置错误,节点注册就可能失败。

在接触服务器之前,先读节点对象

节点对象所能提供的信息,往往比很多人预想得更多。使用 describe 输出时,不要把它当作机械式检查项,而要把它当作一张地图。重点关注状态条件、污点以及事件流。

  • Ready=False:节点仍有一定连通性,足以上报“不健康”状态。
  • Ready=Unknown:控制平面已经无法稳定收到该节点的状态。
  • Pressure conditions:很可能存在本地资源耗尽。
  • NetworkUnavailable:集群网络层面值得重点怀疑。
  • Not-ready taint:调度行为已经发生变化。

官方文档说明,当 Ready 心跳异常或缺失时,系统可能会添加诸如 node.kubernetes.io/not-ready 或 node.kubernetes.io/unreachable 这样的污点。这个区别在运维上非常实用:False 往往表示节点仍能通信,但状态不健康;而 Unknown 更常意味着通信链路已经断开。

修复路径一:干净地恢复节点代理

如果节点代理已停止,或日志中显示启动失败,那么应将它视为首要故障点。常见原因包括无效参数、凭证过期、配置引用错误,或者无法连接运行时套接字。修复动作应尽量简洁,并确保可回滚。

  1. 先检查服务状态,阅读最近日志后再决定是否重启。
  2. 验证配置中的运行时端点以及本地证书是否正确。
  3. 确认主机名与节点身份仍然符合当前集群预期。
  4. 完成修改后,重启服务并实时观察最新日志。

不要忽视那些看起来并不显眼的认证错误。某些节点在本地 shell 中看似一切正常,却依旧无法完成注册或心跳更新。Kubernetes 官方也指出,节点代理负责节点状态上报以及 Lease 更新,因此它的任何异常都会直接影响就绪状态的可见性。

修复路径二:恢复容器运行时

容器运行时一旦损坏,表面现象往往会让人误以为是节点代理的问题,但真正的故障可能隐藏在更底层。如果运行时服务已经停止、卡死,或者暴露了错误的接口,Pod 生命周期操作就会停滞,节点就绪状态也可能随之崩溃。

  • 确认运行时服务处于活动状态。
  • 检查运行时套接字路径是否与节点代理配置一致。
  • 查看启动日志中是否存在插件、接口或配置解析错误。
  • 如果运行时明显异常,先重启运行时,再重启节点代理。

Kubernetes 官方运行时指导强调,运行时必须支持预期的接口版本,而围绕运行时接口的配置错误可能直接导致节点注册失败。

当运行时恢复后,也不要立刻宣告问题解决。还需要确认节点代理已经可以重新与其通信,然后再次检查节点对象。因为即便运行时成功启动,只要它仍无法为 Pod 建立沙箱网络,节点依旧谈不上稳定。

修复路径三:处理网络与 CNI 漂移

网络故障通常更棘手,因为它们可能伪装成控制平面失联、Pod 沙箱创建失败,或间歇性的就绪状态抖动。如果节点主机网络本身可达,但 Pod 无法完成网络初始化,就应仔细检查本地 CNI 配置和运行时日志。

  • 确认节点能够解析并访问 API 端点。
  • 检查本地 CNI 配置文件是否存在语法或版本不匹配。
  • 从运行时日志中查找沙箱网络或网络命名空间错误。
  • 只有在确认配置有效后,再重启网络组件。

Kubernetes 关于 CNI 相关错误的排障说明指出,插件行为与配置不匹配时,工作负载可能会陷入卡住状态,正确的做法应是先修正配置,再重启运行时和节点代理。

在服务器租用和服务器托管环境中,还应顺带检查近期是否发生了防火墙规则变更、MTU 不匹配,或维护窗口后的路由漂移。这类问题常常会在一次看似正常的重启之后集中暴露出来。

修复路径四:清除本地资源压力

资源压力类问题往往最容易验证,却也最容易被低估。节点并不需要完全耗尽磁盘或内存,才会进入功能性异常状态。日志膨胀、镜像堆积、inode 耗尽以及失控进程,都可能足以把它推向边缘。

  1. 检查可用磁盘空间以及 inode 使用率。
  2. 检查可用内存,以及如适用时的 swap 行为。
  3. 查找过量日志、失效沙箱和遗留无用产物。
  4. 谨慎清理无效数据,并仅在必要时重启相关服务。

节点状态模型明确包含磁盘、内存和进程压力条件,因此一旦这些标志被触发,就应将其视为一类一等故障原因,而不是附带噪音。

用一句更“极客”的话来说:如果一台机器已经把大部分精力用在自我防御上,而不是服务工作负载,那么就绪状态受损几乎是必然结果。把节点清理到让内核、运行时和代理都重新拥有喘息空间,往往才是真正的恢复。

什么时候应该重新加入集群,而不是原地修补

有时候,最短路径并不是精细修补,而是进行一次可控替换。如果节点持续出现证书问题、配置严重漂移,或者在失败升级后遗留了混乱状态,那么与其不断叠加临时补丁,不如直接重新加入集群更稳妥。

  • 当节点身份或信任链已经损坏时,优先考虑重新加入。
  • 当本地配置变更历史不再可信时,优先考虑重新加入。
  • 当节点在 Ready 与 NotReady 之间频繁抖动时,优先考虑重新加入。
  • 如果业务允许控制中断,则可在 drain 后执行重新加入。

这种策略尤其适用于可替换型工作节点模式,但即使在更静态的服务器托管部署中,它同样能够有效缩短恢复到稳定状态的时间。关键在于保持流程纪律:能 drain 就先 drain,记录为何重建该节点,并确认替换后的节点不会继承同样的故障模式。

恢复后的验证检查

很多团队会在这里停得太早。kubectl get nodes 中节点重新变绿固然重要,但这只是必要条件,而不是充分条件。你真正需要的是整条就绪链路已经恢复健康的证据。

  1. 确认节点显示为 Ready。
  2. 确认资源压力和网络条件都恢复正常。
  3. 确认新的 Pod 可以在该节点上调度并成功启动。
  4. 确认运行时和节点代理日志在恢复后保持安静。
  5. 确认没有新的告警事件持续累积。

如果节点虽然回到了 Ready,却很快再次跌回异常状态,就不要继续陷入反复重启服务的循环。这通常意味着原始故障只是被暂时掩盖,而非真正修复。此时应回到最先失败的依赖项,从那里重新向前追踪。

保持集群稳定运行的预防策略

最快的恢复,往往是那些原本就很少需要恢复的系统。针对节点健康的预防性工程看似不够炫目,但每逢集群需要承受维护窗口、流量波动或文件系统膨胀时,它都会带来实实在在的回报。

  • 主动跟踪节点状态条件与 Lease 行为。
  • 为日志、镜像和系统守护进程预留足够本地资源余量。
  • 在内核或配置变更后测试节点重启行为。
  • 保证各节点之间的运行时和 CNI 配置一致。
  • 在生产事故发生之前,先演练节点替换流程。

Kubernetes 官方文档强调,节点可用性依赖于稳定的心跳和健康的本地状态上报。因此,围绕节点代理、Lease 活动、资源压力以及网络路径建立预防性监控,通常比单纯依赖通用可用性检测更有价值。

总结

快速恢复一次 Kubernetes 节点 NotReady 事件,关键不在于死记硬背零散命令,而在于尊重依赖顺序。先读节点对象,再验证节点代理,再验证运行时,然后检查资源压力,最后在证据指向明确时再进入网络修复或重新加入流程。对于在服务器租用或服务器托管环境中运行集群的技术团队而言,这种方法能让排障过程更锐利、更可复用,也更“无聊”——而在基础设施运维领域,这恰恰是一种优点:故障影响范围更小,根因更容易暴露,集群也能在尽可能少的戏剧性波动中恢复工作。