2. Kubernetes 节点生命周期管理基础:Node状态、Taint与Toleration、Cordon与Drain概念

节点是Kubernetes集群的计算资源载体,其生命周期管理直接决定工作负载的可用性与运维操作的平滑度。本章从节点状态机出发,逐步深入污点与容忍度调度控制,再到封锁与驱逐的实操语义,为后续集群升级中的节点排水治理建立完整认知基础。

2.1 节点状态机与核心字段

每个Node对象通过 status.conditions 数组报告当前健康状态,kube-controller-manager 中的 node-lifecycle-controller 根据心跳与条件变化驱动状态迁移。

条件类型 可能状态 含义
Ready True / False / Unknown 节点是否正常接收并响应Pod调度请求
DiskPressure True / False 节点磁盘容量或inode接近耗尽
MemoryPressure True / False 节点内存剩余低于驱逐阈值
PIDPressure True / False 节点PID分配接近上限
NetworkUnavailable True / False 节点网络插件报告不可用
关键行为:当 node-monitor-grace-period(默认40s)内未收到节点心跳,条件变为 Unknown;超过 pod-eviction-timeout(默认5m)后,控制面开始驱逐该节点上的Pod。

2.2 Taint(污点)与 Toleration(容忍度)

Taint 是节点对Pod的排斥标记,Toleration 是Pod对特定Taint的容忍声明。两者共同构成Kubernetes调度准入的“白名单”机制。

2.2.1 Taint 三元组

kubectl taint nodes node1 key=value:Effect
Effect 调度行为 典型场景
NoSchedule 不允许新Pod调度到该节点(已有Pod不受影响) 节点维护前预标记
PreferNoSchedule 尽量不调度,但不强制(软约束) 节点资源紧张但未完全不可用
NoExecute 不允许新Pod调度,且立即驱逐不匹配的已有Pod 节点故障隔离、安全隔离

2.2.2 Toleration 声明格式

tolerations:
- key: "node.kubernetes.io/unreachable"
  operator: "Exists"
  effect: "NoExecute"
  tolerationSeconds: 300
最佳实践:DaemonSet 默认对所有节点添加 node.kubernetes.io/unschedulable:NoSchedule 的容忍度,确保系统组件在节点被封锁时仍可运行。

2.3 Cordon(封锁)与 Drain(排水)

Cordon 与 Drain 是节点下线前最常用的两个操作,但语义与影响范围有本质区别。

2.3.1 Cordon:标记不可调度

kubectl cordon node1
# 节点状态变为 SchedulingDisabled
  • 效果:仅阻止新Pod调度到该节点,已有Pod继续运行。
  • 恢复:kubectl uncordon node1 移除封锁标记。
  • 适用:节点短暂维护、资源预留、灰度下线前准备。

2.3.2 Drain:驱逐Pod并标记不可调度

kubectl drain node1 --ignore-daemonsets --delete-emptydir-data
  • 效果:先执行Cordon,再驱逐节点上所有非DaemonSet的Pod(通过eviction API)。
  • 关键参数:
    • --ignore-daemonsets:保留DaemonSet Pod(必须指定)。
    • --delete-emptydir-data:允许驱逐使用emptyDir的Pod(默认拒绝)。
    • --force:强制驱逐不受Pdb保护的Pod。
    • --grace-period:Pod优雅终止宽限期(秒)。
  • 恢复:必须先 uncordon 才能重新调度Pod。
常见陷阱:未指定 --ignore-daemonsets 会导致Drain命令阻塞;未指定 --delete-emptydir-data 时,使用emptyDir的Pod不会被驱逐,Drain命令会一直等待。

2.4 节点生命周期状态迁移图

下图展示了节点从正常状态到完全下线过程中,Cordon、Drain、Taint 三个操作的作用阶段与状态变化。

节点生命周期状态迁移图 节点生命周期状态迁移图 正常节点 Cordon Drain Uncordon 节点下线 kubectl cordon kubectl drain uncordon 恢复调度 关机/删除 说明: Cordon仅阻止新Pod调度; Drain先Cordon再驱逐Pod; Uncordon恢复调度能力。

2.5 操作对比速查表

操作 阻止新Pod调度 驱逐已有Pod 影响DaemonSet 恢复方式
Cordon ✅ 是 ❌ 否 ❌ 否 uncordon
Drain ✅ 是 ✅ 是(通过eviction) ❌ 需 --ignore-daemonsets uncordon
Taint (NoSchedule) ✅ 是 ❌ 否 ❌ 否(除非无容忍度) 删除Taint
Taint (NoExecute) ✅ 是 ✅ 是(立即驱逐不匹配Pod) ✅ 是(除非有容忍度) 删除Taint

2.6 节点生命周期管理流程图

以下流程图展示了集群升级场景中,节点从正常状态到完成排水、升级、再恢复的完整操作序列。

节点升级排水操作流程图 节点升级排水操作流程图 节点正常 预检查 Cordon Drain 节点升级 Uncordon 预检查清单: 1. 节点上是否有Pdb保护的Pod 2. 节点上是否有emptyDir卷的Pod 3. 集群是否有足够的剩余资源 4. 节点是否属于某个Auto Scaling组 5. 节点上是否有StatefulSet Pod
生产建议:在集群升级前,先对非关键节点执行 drain --dry-run 验证驱逐可行性;使用 kubectl get nodes -o wide 查看节点 TAINTS 列,确认是否存在影响调度的污点。