Kubernetes通过污点(Taint)与容忍度(Toleration)机制控制Pod调度:节点设污点(key=value:effect)排斥不匹配Pod,Pod配容忍度以“持证上岗”;effect含NoSchedule(拒新调度)、NoExecute(拒新+驱逐现存Pod)、PreferNoSchedule(软性避开)。
要让 Pod 调度到特定节点,或阻止某些 Pod 调度到不合适的节点,Kubernetes 提供了污点(Taint)与容忍度(Toleration)机制——它不是“让 Pod 去哪”,而是“节点说:不欢迎谁,除非你有通行证”。配置关键在于两步:给节点打污点,再给 Pod 加对应容忍。
给节点添加污点
污点定义在节点上,格式为 key=value:effect,其中 effect 决定排斥力度:
-
NoSchedule:新 Pod 不会调度上来(已运行的不受影响),适合长期专用节点,比如 GPU 节点
-
NoExecute:不仅拒绝新 Pod,还会驱逐当前不满足容忍的 Pod,常用于维护或故障隔离
-
PreferNoSchedule:软性限制,调度器尽量避开,但资源紧张时仍可能调度
常用命令示例:
- 标记某节点仅供数据库使用:kubectl taint nodes node-db database=primary:NoSchedule
- 临时下线维护节点:kubectl taint nodes node-maint maintenance=ongoing:NoExecute
- 查看节点当前污点:kubectl describe node node-db | grep Taints
- 移除污点(注意末尾加减号):kubectl taint nodes node-db database=primary:NoSchedule-
为 Pod 配置容忍度
容忍写在 Pod 的 spec.tolerations 字段中,需与节点污点的 key、value 和 effect 匹配。支持两种匹配方式:
-
Equal:精确匹配三要素(key/value/effect),最常用
-
Exists:只校验 key 和 effect,忽略 value,适合通配场景(如容忍所有 maintenance 类污点)
示例配置(YAML 片段):
tolerations:- key: "database" operator: "Equal" value: "primary" effect: "NoSchedule"
若想让 Pod 容忍任意 effect 的 database 污点,可省略 value 并改用 Exists:
tolerations:- key: "database" operator: "Exists" effect: "NoSchedule"
组合使用更可靠
单个 Pod 可声明多个容忍,应对节点存在多个污点的情况;同样,一个节点也可设置多个污点。调度器会逐条检查:只要有一个污点找不到匹配容忍,Pod 就不会被调度过去。
- 例如节点同时有 gpu=true:NoSchedule 和 region=cn-north:NoExecute,Pod 必须同时容忍二者才能调度成功
- 容忍中的 tolerationSeconds 字段仅对 NoExecute 生效,表示容忍失效后多久开始驱逐(单位秒)
- 注意:容忍不能绕过资源不足、端口冲突等其他调度约束,它只解决污点这一项过滤条件
排查调度失败常见原因
当 Pod 卡在 Pending 状态,先确认是否因污点被拒:
- 运行 kubectl get pods -o wide 查看是否无节点分配
- 执行 kubectl describe pod <pod-name>,重点看 Events 中类似 "0/5 nodes are available: 3 node(s) had taint {key:val:effect}, that the pod didn't tolerate." 的提示
- 对比 kubectl describe node <node-name> 中的 Taints 与 Pod spec 中的 tolerations 是否完全一致(包括大小写、空格、effect 类型)