一、前言:Node 不是你想上就能上
在 Kubernetes 中,Pod 默认会被调度器随机分配到集群中满足资源条件的节点上。但有些节点是我们不希望普通工作负载随意调度过去的,比如:
- 专属 GPU 节点
- 高风险测试节点
- 存储密集型节点
- 预留给系统级组件的节点(如 kube-proxy、CoreDNS)
这时候,仅靠 Node Affinity 还不够,因为 Affinity 是**“想去哪儿” ,而不是“不能去哪儿”**。
所以就需要 Kubernetes 提供的Taints(污点)与 Tolerations(容忍)机制,它们是调度控制的“防守型”策略。
二、基本概念:什么是 Taints 与 Tolerations?
| 名称 | 作用说明 |
|---|---|
| Taint(污点) | 加在 Node 上,用于拒绝调度普通 Pod |
| Toleration(容忍) | 加在 Pod 上,用于允许调度到带有特定污点的 Node 上 |
简单理解就是:
节点上贴上“我不欢迎你”的标签(taint),只有带“通行证”的 Pod(toleration)才能进去。
三、Taint 配置语法与示例
kubectl taint nodes node1 key=value:NoSchedule
该命令给 node1 添加一个 taint,含义是:
- key=value 是识别这个污点的标识;
- NoSchedule 表示 不允许 没有容忍这个污点的 Pod 被调度上来。
Taint 有三种 effect:
| Effect | 含义 |
|---|---|
| NoSchedule | 明确禁止没有容忍的 Pod 被调度到此节点 |
| PreferNoSchedule | 尽量避免调度,非强制(调度器会尽量不选,但可以选) |
| NoExecute | 不仅不调度,还会驱逐当前没有容忍的 Pod(驱逐机制) |
四、Toleration 配置示例
在 Pod 或 Deployment 中加 tolerations:
tolerations:
- key: "key"
operator: "Equal"
value: "value"
effect: "NoSchedule"
这表示该 Pod 容忍了 key=value:NoSchedule 的污点,可以被调度到该 Node。
operator 的两种值:
- Equal:key/value 必须匹配
- Exists:只要 key 存在就可以,不关心 value
五、实战应用场景详解
1️⃣ GPU 节点隔离调度
只允许特定模型训练任务调度到 GPU 节点:
kubectl taint nodes gpu-node gpu=true:NoSchedule
然后为模型训练的 Pod 加 toleration:
tolerations:
- key: "gpu"
operator: "Equal"
value: "true"
effect: "NoSchedule"
✅ 普通业务 Pod 无法调度到 GPU 节点
✅ 模型训练任务独享 GPU,避免干扰
2️⃣ 节点维护时驱逐业务 Pod
维护一个节点前,给其打上如下 taint:
kubectl taint node node2 maintenance=true:NoExecute
这会立即驱逐所有没有对应容忍的 Pod!
如果你希望某些系统组件(如监控 Agent)依然能待在此节点,可以加上:
tolerations:
- key: "maintenance"
operator: "Equal"
value: "true"
effect: "NoExecute"
tolerationSeconds: 3600
tolerationSeconds 表示容忍时长,超时仍会被驱逐。
3️⃣ 与 Affinity 联合调度控制
Taint 是限制调度、Affinity 是引导调度。
比如你想让日志收集 Pod:
- 只运行在 node-role=logging 的节点;
- 这些节点对普通 Pod 有污点保护;
你可以这样做:
- 给节点打 taint:
kubectl taint nodes log-node log-role=true:NoSchedule
- Pod 中加 toleration + affinity:
tolerations:
- key: "log-role"
operator: "Equal"
value: "true"
effect: "NoSchedule"
affinity:
nodeAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
nodeSelectorTerms:
- matchExpressions:
- key: node-role
operator: In
values:
- logging
两者结合,实现了精准的调度意图。
六、常见误区与调试技巧
❌ 误区一:加了 toleration 就一定能调度上去?
不一定。Toleration 只是让 Pod 能“通过门禁”,但最终能不能调度上,还得满足资源条件、NodeSelector、Affinity 等条件。
❌ 误区二:污点没删除,Pod 为什么又调度上来了?
说明 Pod 有匹配的 toleration,或者是 PreferNoSchedule 类型污点,非强制。
✅ 调试技巧:
- 查看节点 taint:
kubectl describe node <node-name>
- 查看 Pod 调度失败原因:
kubectl describe pod <pod-name>
关注 Events 信息,调度失败原因会清晰提示。
七、总结:Taint 和 Toleration 是什么样的人设?
如果把调度器比作派送快递的小哥:
- Taint 是收件人门口贴的告示:“非本小区禁止入内”;
- Toleration 是你出示的证件:“我是物业授权的快递”;
- Affinity 是你导航设置的“优先派送到xx小区”。
只有合理使用这三种手段,才能构建出真正稳定、可控的 Kubernetes 集群调度体系。