4. Pod 驱逐机制详解:node-lifecycle-controller 与 Taint/Toleration 原理

在 Kubernetes 集群中,节点故障是常态而非例外。当节点发生故障(如网络不可达、磁盘压力、内存不足)时,控制平面需要快速、安全地将受影响的 Pod 从故障节点上驱逐,以保障工作负载的 SLO。这一过程的核心驱动力来自 kube-controller-manager 中的 node-lifecycle-controller,以及 Taint(污点) 与 Toleration(容忍) 机制。

4.1 node-lifecycle-controller:节点状态监控与条件管理

node-lifecycle-controller 是 kube-controller-manager 中的一个核心控制器,负责持续监控集群中每个节点的健康状态,并根据节点条件(Node Conditions)自动添加或移除 Taint。其工作流程如下:

  1. 心跳检测:每个节点上的 kubelet 定期向 API Server 上报心跳(Node Status),默认间隔为 10 秒(--node-status-update-frequency)。
  2. 条件评估:node-lifecycle-controller 检查节点状态中的 Ready、DiskPressure、MemoryPressure、PIDPressure 等条件。
  3. 超时判定:如果节点在 --node-monitor-grace-period(默认 40 秒)内未上报状态,控制器将节点标记为 Unknown。
  4. 自动添加 Taint:根据节点条件,控制器自动为节点添加对应的 Taint(如 node.kubernetes.io/unreachable、node.kubernetes.io/not-ready)。
  5. Pod 驱逐触发:已存在的 Pod 如果没有对应的 Toleration,将根据 Taint 的 effect 被驱逐。
关键参数速查表(位于 kube-controller-manager 启动参数中):
参数名 默认值 作用
--node-monitor-period 5s 控制器轮询节点状态的周期
--node-monitor-grace-period 40s 节点状态上报超时宽限期
--pod-eviction-timeout 5m 节点 NotReady 或 Unreachable 后,Pod 被强制驱逐的等待时间
--node-startup-grace-period 1m0s 节点启动期间的特殊宽限期

4.2 Taint 与 Toleration:Pod 调度的“准入与排斥”机制

Taint 是附加在节点上的一组键值对,用于标记节点的“缺陷”或“特殊属性”。Toleration 是附加在 Pod 上的声明,表示 Pod 能够“容忍”某些 Taint。两者共同决定了 Pod 能否被调度到特定节点,以及节点故障时 Pod 是否被驱逐。

4.2.1 Taint 的结构与 Effect

一个 Taint 由三个部分组成:key、value(可选)和 effect。Effect 决定了 Pod 对 Taint 的反应行为:

Effect 类型 行为描述 典型场景
NoSchedule 新的 Pod 不会被调度到该节点(已存在的 Pod 不受影响) 节点维护、预留资源
PreferNoSchedule 尽量不调度新 Pod 到该节点(软约束,调度器会尽量避免) 节点负载较高但未达到硬限制
NoExecute 新的 Pod 不会被调度,且已存在的 Pod 如果没有对应 Toleration 将被驱逐 节点故障、磁盘压力、内存压力

4.2.2 系统自动添加的 Taint

node-lifecycle-controller 会根据节点条件自动添加以下 Taint(均为 NoExecute 效果):

  • node.kubernetes.io/not-ready:节点未就绪(Ready 条件为 False)
  • node.kubernetes.io/unreachable:节点不可达(Ready 条件为 Unknown)
  • node.kubernetes.io/memory-pressure:节点内存压力
  • node.kubernetes.io/disk-pressure:节点磁盘压力
  • node.kubernetes.io/pid-pressure:节点 PID 压力
  • node.kubernetes.io/network-unavailable:节点网络不可用
  • node.kubernetes.io/unschedulable:节点被标记为不可调度
最佳实践:对于关键业务 Pod(如 SLO 作业),建议在 Pod 模板中显式添加对 node.kubernetes.io/not-ready 和 node.kubernetes.io/unreachable 的 Toleration,并设置合理的 tolerationSeconds,以控制 Pod 在节点故障后的存活时间,避免被立即驱逐。

4.3 Pod 驱逐流程:从节点故障到 Pod 终止

下图展示了当节点发生网络故障时,从节点状态变化到 Pod 被驱逐的完整流程:

节点故障 → Pod 驱逐完整流程 节点网络故障 kubelet 心跳中断 API Server 节点状态更新为 Unknown node-lifecycle-controller 检测到节点不可达 添加 Taint: unreachable (NoExecute) 节点对象更新 Taint 列表新增 unreachable Pod 驱逐决策 检查 Pod 是否有对应 Toleration 无 Toleration → 触发驱逐 Pod 被驱逐 重新调度到其他健康节点 说明:Pod 驱逐的默认等待时间为 5 分钟(pod-eviction-timeout),可通过 TolerationSeconds 自定义

4.4 Toleration 的配置与 TolerationSeconds

Pod 通过 spec.tolerations 字段声明对 Taint 的容忍。以下是一个典型的 Toleration 配置示例:

apiVersion: v1
kind: Pod
metadata:
  name: slo-job-pod
spec:
  tolerations:
  - key: "node.kubernetes.io/unreachable"
    operator: "Exists"
    effect: "NoExecute"
    tolerationSeconds: 120
  - key: "node.kubernetes.io/not-ready"
    operator: "Exists"
    effect: "NoExecute"
    tolerationSeconds: 120
  containers:
  - name: workload
    image: my-slo-app:latest

Toleration 字段详解:

字段 说明 示例值
key 要容忍的 Taint 的键 node.kubernetes.io/unreachable
operator 匹配操作符:Exists(仅匹配 key)或 Equal(匹配 key+value) Exists
value 当 operator 为 Equal 时需指定 node1
effect 要容忍的 Taint 效果,留空则匹配所有效果 NoExecute
tolerationSeconds Pod 在节点上容忍 Taint 的最大秒数,超时后将被驱逐 120
注意:tolerationSeconds 仅对 NoExecute 效果有效。如果不设置该字段,Pod 将永久容忍该 Taint(即永远不会被驱逐)。对于 SLO 作业,建议设置一个合理的超时时间(如 60-300 秒),以便在节点短暂故障时保留 Pod,避免频繁重建。

4.5 节点故障时的 Pod 驱逐时间线

以下时间线展示了从节点故障到 Pod 被驱逐的完整过程(假设使用默认参数):

节点故障 → Pod 驱逐时间线(默认参数) T=0s 节点故障 T=40s 节点状态 Unknown T=5m Pod 开始驱逐 T=5m+ Pod 终止完成 T=5m+Δt Pod 在新节点启动 关键时间点说明 • 0-40s:节点故障但未触发驱逐(宽限期) • 40s-5m:节点标记为 Unknown,Taint 已添加,Pod 等待驱逐超时

4.6 驱逐策略对 SLO 作业的影响

对于 SLO 作业(如批处理任务、实时推理服务),Pod 驱逐可能导致作业中断、数据丢失或延迟飙升。以下是针对不同场景的优化建议:

场景 推荐策略 配置示例
短生命周期批处理作业 设置较短的 tolerationSeconds(如 30s),快速驱逐并重新调度 tolerationSeconds: 30
长生命周期有状态服务 设置较长的 tolerationSeconds(如 300s),等待节点恢复 tolerationSeconds: 300
对延迟敏感的服务 使用 PreferNoSchedule 的 Toleration,配合 PDB(PodDisruptionBudget) 不设置 tolerationSeconds,依赖 PDB 控制
需要保证数据完整性的作业 使用 preStop 钩子 + 优雅关闭,配合 terminationGracePeriodSeconds terminationGracePeriodSeconds: 60
核心结论:Taint 与 Toleration 是 Kubernetes 节点故障时 Pod 驱逐的“第一道防线”。理解 node-lifecycle-controller 的工作机制,合理配置 TolerationSeconds 和 PDB,是保障 SLO 作业在节点故障时平稳迁移的关键。