3. K8s 污点 (Taint) 与容忍 (Toleration) 核心概念:定义、语法、效果

在 Kubernetes 集群中,污点 (Taint) 与 容忍 (Toleration) 是一对协同工作的调度控制机制。它们允许节点主动“排斥”一组 Pod,而 Pod 则通过声明“容忍”来获得被调度到特定节点上的资格。这一机制是保障证书轮换作业等关键系统组件能够精准、安全地运行在指定节点上的基础。

3.1 核心定义与作用

  • 污点 (Taint):施加在 Node 上的属性,用于标记节点具有某种“缺陷”或“特殊用途”。一旦节点被打上污点,默认情况下所有 Pod 都无法调度到该节点上。
  • 容忍 (Toleration):施加在 Pod 上的属性,表示 Pod “容忍”了节点上的某个污点。只有声明了相应容忍的 Pod,才有可能被调度到带有该污点的节点上。
类比理解: 污点相当于节点上的“驱虫剂”,而容忍则是 Pod 携带的“免疫牌”。没有免疫牌的 Pod 会被驱虫剂赶走,无法靠近节点。

3.2 污点 (Taint) 的语法与操作

污点由 kubectl taint 命令管理,其语法格式为:

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

一个污点由三个部分组成:

  • Key:污点的键,用于标识污点的类别。
  • Value:污点的值,用于提供更具体的描述(可选)。
  • Effect:污点的效果,定义了 Pod 不满足容忍时的行为。

常用操作示例:

# 给节点 node1 添加一个污点,键为 "dedicated",值为 "cert-rotation",效果为 NoSchedule
kubectl taint nodes node1 dedicated=cert-rotation:NoSchedule

# 查看节点上的污点
kubectl describe node node1 | grep Taints

# 移除节点上的污点(在键名后加一个减号)
kubectl taint nodes node1 dedicated=cert-rotation:NoSchedule-

3.3 容忍 (Toleration) 的语法与配置

容忍定义在 Pod 的 spec.tolerations 字段中。其核心语法如下:

apiVersion: v1
kind: Pod
metadata:
  name: cert-rotation-pod
spec:
  tolerations:
  - key: "dedicated"
    operator: "Equal"
    value: "cert-rotation"
    effect: "NoSchedule"
  containers:
  - name: cert-rotator
    image: my-cert-rotator:latest

容忍字段详解:

字段 说明 可选值
key 要容忍的污点键 字符串,或为空(当 operator 为 Exists 时)
operator 键与值的匹配逻辑 Equal(默认):必须匹配 key 和 value;
Exists:只要 key 存在即可,忽略 value
value 要容忍的污点值 字符串(当 operator 为 Equal 时必须提供)
effect 要容忍的污点效果 NoSchedule、PreferNoSchedule、NoExecute,或留空(容忍所有效果)
tolerationSeconds 当 effect 为 NoExecute 时,Pod 在被驱逐前可以继续运行的秒数 整数(可选)

3.4 三种污点效果 (Effect) 详解

污点的 Effect 决定了 Pod 不满足容忍时的具体行为。这是整个机制中最关键的部分。

三种效果对比:
效果 (Effect) 行为描述 对已有 Pod 的影响 典型使用场景
NoSchedule 不满足容忍的 Pod 不能 被调度到该节点上。 不影响节点上已有的 Pod。 将特定节点预留给证书轮换作业等专用工作负载。
PreferNoSchedule 调度器会 尽量 避免将不满足容忍的 Pod 调度到该节点上,但不是强制要求。 不影响节点上已有的 Pod。 在资源紧张时优先将非关键 Pod 调度到其他节点,但不强制。
NoExecute 不满足容忍的 Pod 不能 被调度到该节点上,并且节点上 已有的不满足容忍的 Pod 会被驱逐。 会驱逐 节点上所有不满足容忍的 Pod。 节点故障隔离、节点维护前强制清空非关键负载。
注意: NoExecute 效果最为严厉。在证书轮换作业中,如果使用 NoExecute 污点,必须确保轮换作业 Pod 声明了对应的容忍,否则它也会被驱逐,导致轮换失败。

3.5 污点与容忍的工作流程 (SVG)

下图展示了带有 NoSchedule 污点的节点如何通过容忍机制筛选 Pod:

污点与容忍调度流程 污点与容忍调度流程 (NoSchedule 效果) 普通 Pod 无容忍声明 容忍 Pod 声明了对应容忍 K8s 调度器 检查污点与容忍 目标节点 Taint: dedicated=cert-rotation:NoSchedule ✗ 拒绝调度 ✓ 允许调度 说明: 只有声明了与节点污点匹配的容忍的 Pod,才能被调度到该节点上。不满足容忍的 Pod 会被调度器拒绝。

3.6 多污点与多容忍的匹配逻辑

在实际场景中,一个节点可以同时设置多个污点,一个 Pod 也可以声明多个容忍。调度器遵循以下匹配逻辑:

  1. 逐条检查:调度器会检查节点上的每一个污点。
  2. 容忍匹配:对于节点上的每一个污点,Pod 必须至少有一个容忍与之匹配(key、value、effect 都匹配,或使用 Exists 操作符匹配 key)。
  3. 全通过原则:只有当 Pod 容忍了节点上的 所有 污点时,Pod 才能被调度到该节点上。只要有一个污点未被容忍,调度器就会根据该污点的 Effect 执行相应操作。
示例: 如果节点有两个污点:dedicated=cert-rotation:NoSchedule 和 maintenance=true:NoExecute,那么 Pod 必须同时容忍这两个污点,才能被调度并稳定运行在该节点上。

3.7 证书轮换作业中的典型应用 (SVG)

在证书轮换场景中,我们通常使用 NoSchedule 效果来确保只有轮换作业 Pod 能够进入特定节点,避免其他工作负载干扰:

证书轮换作业的节点准入控制 证书轮换作业的节点准入控制 证书轮换专用节点 Taint: purpose=cert-rotation:NoSchedule 普通业务 Pod 无容忍 → 被拒绝 证书轮换 Pod 有容忍 → 被准入 通过污点与容忍,证书轮换作业可以独占特定节点,避免资源竞争和调度干扰,确保轮换过程的安全与稳定。

3.8 关键总结

  • 污点 是节点的属性,用于排斥 Pod;容忍 是 Pod 的属性,用于声明对污点的“免疫”。
  • NoSchedule 是最常用的效果,适合证书轮换作业的专用节点隔离。
  • NoExecute 效果会驱逐已有 Pod,适用于节点维护或故障隔离场景。
  • Pod 必须容忍节点上的 所有 污点,才能被调度到该节点上。