4. 污点与容忍入门:Taint 与 Toleration 概念、Effect 类型与基本语法

在 Kubernetes 集群中,调度器默认采用“资源匹配 + 亲和性”策略将 Pod 分配到合适的 Node。然而,实际生产环境往往需要更精细的“排斥”机制:某些 Node 应被预留(如 GPU 节点、专用计算节点),某些 Node 在故障或维护期间应禁止新 Pod 调度。Kubernetes 通过 Taint(污点) 与 Toleration(容忍) 实现了这一能力——Node 打上污点以“排斥”不匹配的 Pod,Pod 声明容忍以“突破”排斥。

4.1 核心概念

  • Taint(污点):附加在 Node 上的键值对属性,包含一个 Effect 字段,用于定义对 Pod 的排斥行为。Node 可以拥有多个污点。
  • Toleration(容忍):附加在 Pod 上的声明,表示该 Pod 能够“容忍”某个或某些污点。容忍不保证调度到该 Node,但允许调度器将 Pod 分配到带有对应污点的 Node。
  • 调度决策逻辑:调度器检查 Node 的所有污点,如果 Pod 没有容忍其中任何一个污点,则根据 Effect 类型执行相应操作(禁止调度、尽量不调度或驱逐已有 Pod)。
关键理解: 污点是 Node 对 Pod 的“排斥条件”,容忍是 Pod 对排斥的“豁免声明”。两者共同构成 Kubernetes 中“白名单式”的调度控制模型。

4.2 Effect 类型详解

Kubernetes 定义了三种 Effect,决定了污点对 Pod 的影响程度:

Effect 类型 行为描述 对未容忍 Pod 的影响 典型使用场景
NoSchedule 强制禁止调度 调度器不会将未容忍该污点的 Pod 调度到该 Node 专用节点(GPU、FPGA)、预留节点、故障节点
PreferNoSchedule 尽量不调度(软约束) 调度器会尽量避免,但如果没有其他可用 Node,仍可能调度 低优先级节点、临时维护节点、成本优化场景
NoExecute 禁止调度 + 驱逐已有 Pod 不仅禁止新 Pod 调度,还会驱逐 Node 上所有未容忍该污点的已有 Pod 节点故障、安全隔离、节点下线、紧急维护
注意: NoExecute 是最严厉的 Effect,它会立即影响正在运行的 Pod。生产环境中使用 NoExecute 时,务必确保关键 Pod 已配置对应的容忍,否则可能导致服务中断。

4.3 基本语法与操作

4.3.1 为 Node 添加污点

使用 kubectl taint 命令为 Node 添加污点,语法格式为:

kubectl taint nodes <node-name> <key>=<value>:<Effect>

示例:为 node-gpu-01 添加一个 GPU 专用污点:

kubectl taint nodes node-gpu-01 gpu=true:NoSchedule

该命令执行后,任何未声明 gpu=true 容忍的 Pod 都无法调度到 node-gpu-01。

4.3.2 在 Pod 中声明容忍

在 Pod 或 Deployment 的 spec.tolerations 字段中声明容忍,基本结构如下:

apiVersion: v1
kind: Pod
metadata:
  name: gpu-pod
spec:
  tolerations:
  - key: "gpu"
    operator: "Equal"
    value: "true"
    effect: "NoSchedule"
  containers:
  - name: gpu-container
    image: nvidia/cuda:11.0-base

容忍字段说明:

  • key:污点的键,必须与 Node 污点的 key 匹配。
  • operator:匹配运算符,支持 Equal(精确匹配 key 和 value)和 Exists(仅匹配 key,忽略 value)。
  • value:当 operator 为 Equal 时,必须与污点的 value 一致。
  • effect:可选字段,指定容忍的 Effect 类型。如果省略,则容忍所有 Effect。
  • tolerationSeconds:仅对 NoExecute 有效,指定 Pod 在被驱逐前可以继续运行的秒数。

4.3.3 查看与删除污点

查看 Node 污点:

kubectl describe node <node-name> | grep Taints

删除污点(在末尾添加减号):

kubectl taint nodes <node-name> <key>=<value>:<Effect>-

示例:删除 node-gpu-01 上的 GPU 污点:

kubectl taint nodes node-gpu-01 gpu=true:NoSchedule-

4.4 污点与容忍工作流程

污点与容忍调度决策流程 污点与容忍调度决策流程 Pod 待调度 调度器检查 Node 所有污点 是否存在未容忍的污点? 否 是 允许调度到该 Node 根据 Effect 处理 NoSchedule → 禁止调度 | PreferNoSchedule → 尽量不调度 | NoExecute → 禁止调度 + 驱逐已有 Pod

4.5 常见操作模式

模式一:专用节点隔离
为 GPU 节点添加 gpu=true:NoSchedule,仅允许声明了对应容忍的 AI 训练 Pod 调度。
模式二:节点维护
在节点维护前添加 maintenance=true:NoExecute,自动驱逐未容忍的 Pod,同时阻止新 Pod 调度。
模式三:软约束成本优化
为低成本竞价实例节点添加 spot=true:PreferNoSchedule,优先使用普通节点,但在资源紧张时允许调度。

4.6 避坑指南

  • 容忍不匹配:容忍的 key、value、effect 必须与污点完全匹配(或使用 Exists 运算符),否则容忍无效。
  • 多个污点叠加:Node 可以同时拥有多个污点,Pod 必须容忍所有污点才能被调度。只要有一个污点未容忍,调度器就会根据 Effect 拒绝调度。
  • NoExecute 的驱逐延迟:通过 tolerationSeconds 可以为 Pod 设置驱逐宽限期,适用于需要优雅退出的工作负载。
  • 容忍不等于亲和:容忍只解除排斥,不保证 Pod 一定会调度到该 Node。如果需要强制调度,需结合 nodeSelector 或节点亲和性。
污点与容忍匹配规则 污点与容忍匹配规则 Node 污点集合 key1=value1:NoSchedule key2=value2:NoExecute key3=value3:PreferNoSchedule Pod 容忍声明 - key: key1, operator: Equal, value: value1, effect: NoSchedule - key: key2, operator: Exists, effect: NoExecute (未声明 key3 的容忍) 匹配 匹配 未匹配 结果:Pod 容忍了 key1 和 key2,但未容忍 key3 → 调度被拒绝(NoSchedule) 核心规则:Pod 必须容忍 Node 上所有污点,才能被调度到该 Node 容忍匹配支持 Equal(精确匹配 key+value)和 Exists(仅匹配 key)两种运算符

4.7 本章小结

污点与容忍是 Kubernetes 调度体系中实现“节点隔离”与“调度控制”的核心机制。通过三种 Effect 类型(NoSchedule、PreferNoSchedule、NoExecute),运维人员可以精确控制 Pod 与 Node 之间的调度关系。掌握污点与容忍的基本语法和匹配规则,是后续学习高级调度策略(如节点亲和性、Pod 拓扑分布约束)的基础。