2. Kubernetes 节点管理基础:节点生命周期、节点状态、节点健康检查机制

在实施节点滚动升级之前,必须深入理解 Kubernetes 节点的底层管理模型。节点是承载 Pod 的物理或虚拟工作单元,其生命周期、状态转换和健康检查机制直接决定了升级操作的窗口选择、风险边界和回退策略。本节将系统梳理这三个核心维度,为后续 Policy as Code 窗口控制提供坚实的知识基础。

2.1 节点生命周期:从注册到退役

Kubernetes 节点的生命周期包含四个关键阶段:注册(Registration)、就绪(Ready)、维护(Maintenance)、退役(Retirement)。每个阶段对应不同的控制面行为和调度策略。

阶段 触发条件 控制面行为 调度影响
注册 kubelet 启动后向 API Server 创建 Node 对象 验证节点凭证,分配节点 CIDR,启动节点控制器监控 节点不可调度(NoSchedule)直到就绪
就绪 节点通过所有健康检查,NodeReady 条件为 True 更新节点状态,调度器将 Pod 调度到该节点 正常调度 Pod
维护 管理员执行 cordon/drain 或节点进入 NotReady 标记节点不可调度,驱逐 Pod(drain 时) 禁止新 Pod 调度,逐步迁移已有 Pod
退役 节点被删除或长时间不可恢复 清理节点对象,释放关联资源(如 PV) 节点从集群中完全移除
关键认知:滚动升级本质上是在“维护”阶段对节点进行批量操作。理解节点从“就绪”到“维护”再到“就绪”的完整闭环,是设计窗口控制策略的前提。

2.2 节点状态:NodeCondition 与状态机

每个节点通过 status.conditions 字段报告一组标准条件(NodeCondition)。这些条件共同构成节点的健康快照,也是节点控制器和调度器做出决策的依据。

核心 NodeCondition 包括:

  • NodeReady:节点是否能够正常接受 Pod。True 表示健康,False 或 Unknown 表示异常。
  • NodeDiskPressure:节点磁盘空间是否不足。True 表示存在压力,调度器会避免调度新 Pod。
  • NodeMemoryPressure:节点内存是否不足。True 表示内存紧张,kubelet 可能开始驱逐低优先级 Pod。
  • NodePIDPressure:节点 PID 资源是否耗尽。True 表示进程数接近上限。
  • NodeNetworkUnavailable:节点网络配置是否正确。True 表示网络不可用。

节点状态机遵循以下转换逻辑:

注册 → NodeReady=False(初始)
  ↓
健康检查通过 → NodeReady=True(正常调度)
  ↓
健康检查失败 → NodeReady=False 或 Unknown(触发驱逐)
  ↓
管理员干预 → NodeReady=True(恢复)或 节点删除(退役)
升级窗口陷阱:如果节点在升级过程中出现 NodeMemoryPressure 或 NodeDiskPressure 为 True,即使 NodeReady 仍为 True,调度器也会限制新 Pod 调度。窗口控制策略必须将这些压力条件纳入“禁止升级”的规则集。

2.3 节点健康检查机制:kubelet 与节点控制器

Kubernetes 通过两层健康检查机制保障节点状态的准确性:kubelet 自检和节点控制器(Node Controller)监控。

2.3.1 kubelet 自检

kubelet 在每个节点上运行,定期执行以下检查:

  • 资源检查:监控 CPU、内存、磁盘、PID 使用率,更新对应的压力条件。
  • 运行时检查:验证容器运行时(如 containerd)是否响应。
  • 网络检查:验证节点网络插件(如 Calico、Cilium)是否正常。

kubelet 通过 --node-status-update-frequency 参数(默认 10 秒)向 API Server 上报状态。如果 kubelet 自身崩溃,则停止上报。

2.3.2 节点控制器监控

节点控制器运行在控制面,负责:

  • 心跳超时检测:如果节点超过 --node-monitor-grace-period(默认 40 秒)未上报状态,将 NodeReady 标记为 Unknown。
  • Pod 驱逐:如果节点在 --pod-eviction-timeout(默认 5 分钟)内未恢复,开始驱逐该节点上的 Pod。
  • 污点管理:自动为异常节点添加 node.kubernetes.io/unreachable 或 node.kubernetes.io/not-ready 污点。
升级窗口关联:滚动升级时,节点会短暂重启 kubelet 或操作系统,导致心跳中断。节点控制器在 --node-monitor-grace-period 内不会触发驱逐,这为升级操作提供了天然的安全窗口。Policy as Code 应利用这个参数计算最大允许升级时间。

2.4 节点生命周期与健康检查的 SVG 架构图

下图展示了节点从注册到退役的完整生命周期,以及健康检查机制在其中的作用位置:

节点生命周期与健康检查架构 节点生命周期与健康检查架构 注册 kubelet 创建 Node 对象 就绪 健康检查通过 维护 cordon/drain/NotReady 退役 节点删除 健康检查通过 升级/故障 恢复 不可恢复 健康检查机制 kubelet 自检 每 10s 上报状态 节点控制器 40s 超时 → 5min 驱逐 升级安全窗口 ≤ 40s 不触发驱逐

2.5 节点状态与健康检查的决策矩阵

在实际运维中,节点状态和健康检查结果共同决定升级操作的可行性。以下矩阵总结了常见场景下的决策逻辑:

NodeReady 压力条件 kubelet 心跳 节点控制器动作 升级窗口可用性
True 全部 False 正常 无 ✅ 可用
True 任一 True 正常 限制调度 ⚠️ 谨慎(可能影响 Pod 重调度)
False — 停止 40s 后标记 Unknown ❌ 不可用(节点已异常)
Unknown — 停止 5min 后开始驱逐 ❌ 不可用(触发驱逐)
Policy as Code 映射:在 OPA/Gatekeeper 或 Kyverno 策略中,应检查 status.conditions 中 NodeReady 是否为 True,且所有压力条件为 False,才允许对该节点执行升级操作。这可以避免在节点已经处于亚健康状态时进行升级,防止故障扩散。

2.6 节点管理命令速查

以下命令是节点生命周期管理的基础工具,也是滚动升级操作的前置步骤:

# 查看节点状态和条件
kubectl get nodes -o wide
kubectl describe node <node-name>

# 标记节点不可调度(cordon)
kubectl cordon <node-name>

# 驱逐节点上的 Pod(drain)
kubectl drain <node-name> --ignore-daemonsets --delete-emptydir-data

# 恢复节点调度(uncordon)
kubectl uncordon <node-name>

# 查看节点事件
kubectl get events --field-selector involvedObject.kind=Node
实践注意:kubectl drain 会先 cordon 节点,然后驱逐所有非 DaemonSet Pod。如果 Pod 使用 emptyDir 且未设置 PDB(PodDisruptionBudget),drain 可能失败。窗口控制策略应要求目标节点上的所有关键工作负载已配置 PDB。