Kubernetes 污点(Taints)和容忍度(Tolerations)是用于控制 Pod 调度的机制,它们允许节点拒绝(或接受)具有特定容忍度的 Pod。
污点(Taints)
污点是应用于节点上的键值对,用于阻止 Pod 调度到该节点,除非 Pod 具有匹配的容忍度。
污点的组成
每个污点包含三个部分:
-
Key:污点的键(必需)
-
Value:污点的值(可选)
-
Effect:污点的影响(必需)
污点的影响类型
-
NoSchedule:
- 不会调度新的 Pod 到该节点
- 已存在的 Pod 不受影响
- 适用于专用节点(如 GPU 节点)
-
PreferNoSchedule:
- 尽量不调度新的 Pod 到该节点
- 但如果没有其他可用节点,仍可能调度
- 适用于软性限制
-
NoExecute:
- 不会调度新的 Pod 到该节点
- 已存在的 Pod 如果没有匹配的容忍度,将被驱逐
- 适用于节点维护或故障场景
添加污点
bash# 添加 NoSchedule 污点 kubectl taint nodes node1 key=value:NoSchedule # 添加 NoExecute 污点 kubectl taint nodes node1 key=value:NoExecute # 添加没有值的污点 kubectl taint nodes node1 key:NoSchedule
查看污点
bash# 查看节点的污点 kubectl describe node node1 | grep Taint # 查看所有节点的污点 kubectl get nodes -o custom-columns=NAME:.metadata.name,TAINTS:.spec.taints
删除污点
bash# 删除指定污点 kubectl taint nodes node1 key:NoSchedule- # 删除所有指定键的污点 kubectl taint nodes node1 key-
容忍度(Tolerations)
容忍度是应用于 Pod 上的配置,允许 Pod 调度到具有匹配污点的节点。
容忍度的组成
容忍度包含以下字段:
-
Key:要容忍的污点键
-
Operator:操作符(Equal 或 Exists)
-
Value:要容忍的污点值(当 Operator 为 Equal 时需要)
-
Effect:要容忍的污点影响
-
TolerationSeconds:容忍时间(仅适用于 NoExecute)
容忍度操作符
-
Equal:
- 键和值都必须匹配
- 需要指定 Value
-
Exists:
- 只需要键匹配
- 不需要指定 Value
添加容忍度
yamlapiVersion: v1 kind: Pod metadata: name: my-pod spec: tolerations: - key: "key" operator: "Equal" value: "value" effect: "NoSchedule" containers: - name: my-container image: nginx
容忍度示例
- 容忍特定污点:
yamltolerations: - key: "dedicated" operator: "Equal" value: "gpu" effect: "NoSchedule"
- 容忍所有具有特定键的污点:
yamltolerations: - key: "dedicated" operator: "Exists"
- 容忍所有污点:
yamltolerations: - operator: "Exists"
- 容忍 NoExecute 污点并设置容忍时间:
yamltolerations: - key: "node.kubernetes.io/not-ready" operator: "Exists" effect: "NoExecute" tolerationSeconds: 300
污点和容忍度的匹配规则
-
键匹配:
- 如果容忍度的键为空,则匹配所有污点
- 如果污点的键为空,则不能被任何容忍度匹配
-
操作符匹配:
- Equal:键和值都必须匹配
- Exists:只需要键匹配
-
影响匹配:
- 如果容忍度的影响为空,则匹配所有影响
- 否则,影响必须匹配
常见使用场景
1. 专用节点
为特定用途的节点添加污点,确保只有特定的 Pod 可以调度到这些节点。
bash# 为 GPU 节点添加污点 kubectl taint nodes gpu-node dedicated=gpu:NoSchedule
yaml# 只有 GPU Pod 可以调度到 GPU 节点 apiVersion: v1 kind: Pod metadata: name: gpu-pod spec: tolerations: - key: "dedicated" operator: "Equal" value: "gpu" effect: "NoSchedule" containers: - name: gpu-container image: nvidia/cuda:11.0.3-base-ubuntu20.04
2. 节点维护
使用 NoExecute 污点驱逐 Pod,进行节点维护。
bash# 标记节点为维护状态 kubectl taint nodes node1 maintenance:NoExecute
3. 特殊硬件节点
为具有特殊硬件的节点添加污点,确保只有需要这些硬件的 Pod 可以调度。
bash# 为 SSD 节点添加污点 kubectl taint nodes ssd-node disktype=ssd:NoSchedule
4. 故障节点
Kubernetes 自动为故障节点添加污点,驱逐 Pod。
yaml# Pod 容忍节点故障 tolerations: - key: "node.kubernetes.io/not-ready" operator: "Exists" effect: "NoExecute" tolerationSeconds: 300 - key: "node.kubernetes.io/unreachable" operator: "Exists" effect: "NoExecute" tolerationSeconds: 300
污点和容忍度 vs 亲和性
| 特性 | 污点和容忍度 | 亲和性 |
|---|---|---|
| 作用对象 | 节点和 Pod | 节点和 Pod |
| 作用方向 | 节点拒绝 Pod | Pod 选择节点 |
| 灵活性 | 较低 | 较高 |
| 使用场景 | 专用节点、节点维护 | 性能优化、高可用性 |
最佳实践
-
合理使用污点:避免过度使用污点,可能导致调度失败
-
为专用节点添加污点:确保只有特定的 Pod 可以调度到专用节点
-
设置合理的容忍时间:为 NoExecute 污点设置合理的容忍时间,避免频繁驱逐
-
结合亲和性使用:结合使用污点/容忍度和亲和性,实现更精细的调度控制
-
监控节点状态:监控节点的污点状态,及时处理故障节点
-
文档化污点策略:记录污点和容忍度的使用策略,便于团队协作
-
测试容忍度配置:在非生产环境测试容忍度配置,确保正确性
故障排查
- 查看节点污点:
bashkubectl describe node <node-name>
- 查看 Pod 容忍度:
bashkubectl describe pod <pod-name>
- 检查调度失败原因:
bashkubectl describe pod <pod-name> | grep -A 10 Events
- 查看调度器日志:
bashkubectl logs -n kube-system <scheduler-pod-name>
示例:多节点类型集群
yaml# Master 节点 apiVersion: v1 kind: Node metadata: name: master-node spec: taints: - key: "node-role.kubernetes.io/master" effect: "NoSchedule" # GPU 节点 apiVersion: v1 kind: Node metadata: name: gpu-node spec: taints: - key: "dedicated" value: "gpu" effect: "NoSchedule" # 普通 Pod(可以调度到普通节点) apiVersion: v1 kind: Pod metadata: name: normal-pod spec: containers: - name: nginx image: nginx # GPU Pod(只能调度到 GPU 节点) apiVersion: v1 kind: Pod metadata: name: gpu-pod spec: tolerations: - key: "dedicated" operator: "Equal" value: "gpu" effect: "NoSchedule" containers: - name: gpu-app image: nvidia/cuda:11.0.3-base-ubuntu20.04