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:
3.6 多污点与多容忍的匹配逻辑
在实际场景中,一个节点可以同时设置多个污点,一个 Pod 也可以声明多个容忍。调度器遵循以下匹配逻辑:
- 逐条检查:调度器会检查节点上的每一个污点。
- 容忍匹配:对于节点上的每一个污点,Pod 必须至少有一个容忍与之匹配(
key、value、effect都匹配,或使用Exists操作符匹配key)。 - 全通过原则:只有当 Pod 容忍了节点上的 所有 污点时,Pod 才能被调度到该节点上。只要有一个污点未被容忍,调度器就会根据该污点的
Effect执行相应操作。
示例: 如果节点有两个污点:
dedicated=cert-rotation:NoSchedule 和 maintenance=true:NoExecute,那么 Pod 必须同时容忍这两个污点,才能被调度并稳定运行在该节点上。
3.7 证书轮换作业中的典型应用 (SVG)
在证书轮换场景中,我们通常使用 NoSchedule 效果来确保只有轮换作业 Pod 能够进入特定节点,避免其他工作负载干扰:
3.8 关键总结
- 污点 是节点的属性,用于排斥 Pod;容忍 是 Pod 的属性,用于声明对污点的“免疫”。
- NoSchedule 是最常用的效果,适合证书轮换作业的专用节点隔离。
- NoExecute 效果会驱逐已有 Pod,适用于节点维护或故障隔离场景。
- Pod 必须容忍节点上的 所有 污点,才能被调度到该节点上。