kubernetes 污点(Taint)与容忍度(Toleration)

一、什么是污点(Taint)与容忍度(Toleration)

在 Kubernetes 中,污点(Taint) 是节点(Node)的属性,用于排斥一类特定的 Pod。容忍度(Toleration) 则是 Pod 的属性,表示 Pod 能够“容忍”某个污点,从而可以被调度到带有该污点的节点上。

污点和容忍度是 “排斥” 机制,与节点亲和性(Node Affinity)的 “吸引” 机制正好相反。

污点的三要素

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

组成部分 说明
Key(键) 污点的标识符
Value(值) 可选,进一步描述污点
Effect(效果) 定义了调度器对未容忍 Pod 的行为

Effect 的三种类型

Effect 含义
NoSchedule 不允许 Pod 调度到该节点,已有 Pod 不受影响
PreferNoSchedule 尽量避免调度新 Pod 到该节点,但不强制
NoExecute 不仅不允许新 Pod 调度,还会驱逐已运行但未容忍的 Pod

二、如何“去污”:移除节点上的污点

“去污”就是移除节点上的污点,使用 kubectl taint 命令,在末尾加上一个减号 - 即可。

基本语法

kubectl taint nodes <节点名称> <key>:<effect>-

常见操作示例

1. 移除指定的单个污点

kubectl taint nodes node1 key1=value1:NoSchedule-

注意:必须完整匹配 key、value 和 effect。

2. 移除指定 key 的所有污点(不指定 value 和 effect)

kubectl taint nodes node1 key1-

这条命令会移除节点 node1 上所有 key 为 key1 的污点,无论其 value 和 effect 是什么。

3. 结合标签选择器批量去污

kubectl taint node -l environment=production dedicated:NoSchedule-

通过 -l 标签选择器,可以批量对满足条件的节点执行去污操作。

4. 对所有节点去污

kubectl taint nodes --all key1:NoSchedule-

使用 --all 参数可作用于集群中的所有节点。

5. 移除 control-plane 污点(允许普通 Pod 调度到控制平面节点)

kubectl taint nodes --all node-role.kubernetes.io/control-plane-

在测试或开发集群中,通常希望移除控制平面节点(control-plane)上的污点,使其可以调度普通工作负载。此命令会移除所有节点上 key 为 node-role.kubernetes.io/control-plane 的污点。注意:在生产环境中不建议这样做,控制平面节点应尽量保持专用。


三、查看节点上的污点

在执行去污操作之前,通常需要先查看节点当前的污点情况。

方法一:使用 kubectl describe

kubectl describe nodes node1 | grep Taints

输出示例:Taints: key1=value1:NoSchedule

方法二:使用 kubectl get 加 JSONPath

kubectl get nodes -o jsonpath="{range .items[*]}{.metadata.name}:{' '}{range .spec.taints[*]}{.key}={.value}:{.effect},{' '}{end}{'\n'}{end}"

适合脚本自动化处理。

方法三:使用 jq 格式化输出

kubectl get nodes -o=json | jq -r '.items[] | .metadata.name + "\t" + (if .spec.taints then (.spec.taints | map(.key + "=" + (.value // "") + ":" + .effect) | join(", ")) else "No taints" end)'

输出更清晰易读。

方法四:使用 -o yaml 输出并过滤

kubectl get node -o yaml | grep taint -A 10

直接以 YAML 格式输出所有节点的完整信息,然后通过 grep 过滤出与污点相关的行。-A 10 表示同时显示匹配行之后的 10 行,方便查看每个污点的完整 key、value 和 effect 信息。适合快速查看所有节点污点概况。


四、典型应用场景

1. 节点维护与升级

维护前添加污点防止新 Pod 调度:

kubectl taint nodes node1 maintenance:NoSchedule

维护完成后去污,恢复调度:

kubectl taint nodes node1 maintenance:NoSchedule-

2. 紧急隔离问题节点

当节点发生故障或安全事件时,使用 NoExecute 快速驱逐所有 Pod:

kubectl taint nodes node1 emergency:NoExecute

问题解决后去污恢复:

kubectl taint nodes node1 emergency:NoExecute-

3. 专用节点(如 GPU 节点)

为 GPU 节点添加污点,确保只有特定的 Pod 能使用:

kubectl taint nodes node-gpu gpu=exclusive:NoSchedule

4. 开发/测试环境:让控制平面节点可调度

Kubernetes 默认会给控制平面节点(control-plane)添加污点,防止普通 Pod 调度上去。
在开发或测试集群中,节点资源有限,通常需要移除该污点让控制平面节点也能运行工作负载:

# 查看控制平面节点的污点
kubectl get node -o yaml | grep taint -A 10

# 移除所有节点的 control-plane 污点
kubectl taint nodes --all node-role.kubernetes.io/control-plane-

:warning: 生产环境不建议执行此操作。生产集群应保持控制平面节点专用,避免工作负载影响集群管理组件的稳定性。


五、注意事项与最佳实践

:warning: 系统自动添加的污点

Kubernetes 在某些情况下会自动为节点添加污点,例如节点 NotReadyUnreachable 时。这类污点会在问题解决后自动移除,一般不需要手动干预。

:light_bulb: 操作建议

  1. 先加容忍,后加污点:对于现有的 Pod 和节点,应先将容忍度添加到 Pod,再为节点添加污点,避免在添加容忍前 Pod 被意外驱逐。

  2. 配合节点亲和性使用:对于专用节点场景,建议将污点/容忍度与节点亲和性(Node Affinity)结合使用——用污点排斥非目标 Pod,用亲和性确保目标 Pod 只调度到这些节点。

  3. 谨慎使用 NoExecuteNoExecute 会立即驱逐未容忍的 Pod,在生产环境中操作前务必确认影响范围。

  4. 去污前确认污点完整信息:使用 kubectl describekubectl get 确认污点的完整 key、value 和 effect,避免匹配错误。


六、命令速查表

操作 命令
添加污点 kubectl taint nodes <node> <key>=<value>:<effect>
移除指定污点 kubectl taint nodes <node> <key>=<value>:<effect>-
移除某 key 的所有污点 kubectl taint nodes <node> <key>-
查看节点污点 kubectl describe nodes <node> | grep Taints
查看所有节点污点(YAML 方式) kubectl get node -o yaml | grep taint -A 10
批量去污(按标签) kubectl taint node -l <label>=<value> <key>:<effect>-
全部节点去污 kubectl taint nodes --all <key>:<effect>-
移除 control-plane 污点 kubectl taint nodes --all node-role.kubernetes.io/control-plane-

掌握污点的添加与移除,是 Kubernetes 节点运维和调度管理的基本功。合理运用污点机制,可以有效控制 Pod 的调度行为,保障集群的稳定运行。