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 三个操作的作用阶段与状态变化。
2.5 操作对比速查表
| 操作 | 阻止新Pod调度 | 驱逐已有Pod | 影响DaemonSet | 恢复方式 |
|---|---|---|---|---|
| Cordon | ✅ 是 | ❌ 否 | ❌ 否 | uncordon |
| Drain | ✅ 是 | ✅ 是(通过eviction) | ❌ 需 --ignore-daemonsets |
uncordon |
| Taint (NoSchedule) | ✅ 是 | ❌ 否 | ❌ 否(除非无容忍度) | 删除Taint |
| Taint (NoExecute) | ✅ 是 | ✅ 是(立即驱逐不匹配Pod) | ✅ 是(除非有容忍度) | 删除Taint |
2.6 节点生命周期管理流程图
以下流程图展示了集群升级场景中,节点从正常状态到完成排水、升级、再恢复的完整操作序列。
生产建议:在集群升级前,先对非关键节点执行
drain --dry-run 验证驱逐可行性;使用 kubectl get nodes -o wide 查看节点 TAINTS 列,确认是否存在影响调度的污点。