一、什么是污点(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-
生产环境不建议执行此操作。生产集群应保持控制平面节点专用,避免工作负载影响集群管理组件的稳定性。
五、注意事项与最佳实践
系统自动添加的污点
Kubernetes 在某些情况下会自动为节点添加污点,例如节点 NotReady 或 Unreachable 时。这类污点会在问题解决后自动移除,一般不需要手动干预。
操作建议
-
先加容忍,后加污点:对于现有的 Pod 和节点,应先将容忍度添加到 Pod,再为节点添加污点,避免在添加容忍前 Pod 被意外驱逐。
-
配合节点亲和性使用:对于专用节点场景,建议将污点/容忍度与节点亲和性(Node Affinity)结合使用——用污点排斥非目标 Pod,用亲和性确保目标 Pod 只调度到这些节点。
-
谨慎使用 NoExecute:
NoExecute会立即驱逐未容忍的 Pod,在生产环境中操作前务必确认影响范围。 -
去污前确认污点完整信息:使用
kubectl describe或kubectl 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 的调度行为,保障集群的稳定运行。