版本 :v1.0
适用 Kubernetes 版本 :v1.20+
目标:掌握污点(Taint)与容忍(Toleration)的配置、验证与排错
一、什么是节点污点(Taint)?
污点(Taint) 是 Kubernetes 节点上的一种标记,用于 排斥不满足条件的 Pod 。只有带有对应 容忍(Toleration) 的 Pod 才能被调度到该节点。
核心作用:
- 防止普通 Pod 调度到 Master 节点(默认行为)
- 专用节点(如 GPU 节点、日志节点)只运行特定工作负载
- 节点维护期间临时驱逐新 Pod
污点格式:
ruby
<key>=<value>:<effect>
| Effect(效果) | 说明 |
|---|---|
NoSchedule |
新 Pod 不会被调度到该节点(已运行的不受影响) |
PreferNoSchedule |
尽量不调度(软策略,非强制) |
NoExecute |
不仅拒绝新 Pod,还会驱逐已运行的不匹配 Pod |
二、操作前准备
环境要求:
- 已部署 Kubernetes 集群(至少 1 master + 1 worker)
kubectl已配置并具备管理员权限- 至少一个可操作的 Worker 节点(如
worker-01)
查看当前节点污点(基准状态):
swift
kubectl describe node <node-name> | grep Taints
# 或
kubectl get nodes -o jsonpath='{range .items[*]}{.metadata.name}{"\t"}{.spec.taints}{"\n"}{end}'
默认情况下,Master 节点通常有:
bashnode-role.kubernetes.io/control-plane:NoSchedule
三、操作步骤与验证
✅ 场景 1:为节点添加污点(NoSchedule)
目标:阻止普通 Pod 调度到 worker-01
步骤 1:添加污点
ini
kubectl taint node worker-01 dedicated=gpu:NoSchedule
说明:给
worker-01添加污点,key=dedicated, value=gpu, effect=NoSchedule
步骤 2:验证污点已生效
perl
kubectl describe node worker-01 | grep Taints
# 输出应包含:
# Taints: dedicated=gpu:NoSchedule
步骤 3:部署普通 Pod(预期:不会调度到 worker-01)
yaml
# test-pod.yaml
apiVersion: v1
kind: Pod
metadata:
name: test-pod
spec:
containers:
- name: nginx
image: nginx:alpine
restartPolicy: Never
arduino
kubectl apply -f test-pod.yaml
kubectl get pod test-pod -o wide
✅ 预期结果 :
Pod 被调度到 其他无污点的节点 ,不会出现在 worker-01
✅ 场景 2:为 Pod 添加容忍(Toleration)
目标:让特定 Pod 可以调度到带污点的节点
步骤 1:创建带容忍的 Pod
yaml
# gpu-pod.yaml
apiVersion: v1
kind: Pod
metadata:
name: gpu-pod
spec:
containers:
- name: busybox
image: busybox
command: ["sleep", "3600"]
tolerations:
- key: "dedicated"
operator: "Equal"
value: "gpu"
effect: "NoSchedule"
restartPolicy: Never
步骤 2:部署并验证
arduino
kubectl apply -f gpu-pod.yaml
kubectl get pod gpu-pod -o wide
✅ 预期结果 :
Pod 成功调度到 worker-01
💡 注意:容忍必须 完全匹配 key、value、effect(除非使用
operator: Exists)
✅ 场景 3:测试 NoExecute 效果(驱逐已运行 Pod)
目标:验证 NoExecute 会驱逐不匹配的现有 Pod
步骤 1:先在 worker-01 上运行一个普通 Pod
css
# 强制调度到 worker-01(通过 nodeName)
kubectl run debug-pod --image=busybox --command -- sleep 3600 --dry-run=client -o yaml | \
kubectl apply -f -
kubectl patch pod debug-pod -p '{"spec":{"nodeName":"worker-01"}}'
确认 Pod 在 worker-01 上运行:
arduino
kubectl get pod debug-pod -o wide
步骤 2:添加 NoExecute 污点
ini
kubectl taint node worker-01 maintenance=true:NoExecute
步骤 3:观察 Pod 状态
arduino
kubectl get pod debug-pod -w
✅ 预期结果 :
debug-pod 在几秒内被 终止(Terminated) ,状态变为 Evicted 或直接消失。
⚠️ 注意:如果 Pod 有
tolerationSeconds,会延迟驱逐(见高级用法)
✅ 场景 4:移除污点
目标:恢复节点正常调度
ini
# 移除指定污点
kubectl taint node worker-01 dedicated=gpu:NoSchedule-
# 移除所有污点(谨慎!)
kubectl taint node worker-01 dedicated-
kubectl taint node worker-01 maintenance-
🔑 语法:在污点后加
-表示删除
验证:
perl
kubectl describe node worker-01 | grep Taints
# 应显示:Taints: <none>
四、高级用法
1. 容忍所有污点(慎用!)
vbnet
tolerations:
- operator: "Exists"
该 Pod 可调度到 任何节点,包括 Master(常用于 DaemonSet 如 Calico、Fluentd)
2. 延迟驱逐(tolerationSeconds)
vbnet
tolerations:
- key: "node.kubernetes.io/unreachable"
operator: "Exists"
effect: "NoExecute"
tolerationSeconds: 300 # 节点失联后 5 分钟再驱逐
3. 多污点容忍
vbnet
tolerations:
- key: "dedicated"
value: "gpu"
effect: "NoSchedule"
- key: "env"
value: "prod"
effect: "NoExecute"
五、典型应用场景
| 场景 | 污点设置 | 用途 |
|---|---|---|
| Master 节点保护 | node-role.kubernetes.io/control-plane:NoSchedule |
防止业务 Pod 占用控制平面资源 |
| GPU 专用节点 | nvidia.com/gpu=true:NoSchedule |
只运行 AI/ML 任务 |
| 日志/监控节点 | role=logging:NoSchedule |
专用于 Fluentd、Prometheus |
| 节点维护 | maintenance=true:NoExecute |
临时驱逐所有非关键 Pod |
六、故障排查指南
❌ 问题 1:Pod 一直 Pending,事件显示 "0/3 nodes are available: 3 node(s) had taint..."
原因:所有节点都有污点,但 Pod 没有对应容忍。
解决:
- 检查节点污点:
kubectl describe node - 为 Pod 添加正确
tolerations - 或移除不必要的污点
❌ 问题 2:Pod 被意外驱逐
原因 :节点被添加了 NoExecute 污点,且 Pod 无容忍。
解决:
- 检查近期是否执行了
kubectl taint ...:NoExecute - 为关键 Pod 添加容忍 +
tolerationSeconds - 使用
kubectl describe pod <name>查看 Events
❌ 问题 3:污点无法删除
现象 :执行 kubectl taint node xxx key=value:effect- 报错
原因:value 或 effect 不匹配。
解决:
- 先
kubectl describe node确认完整污点字符串 - 删除时必须 完全一致(包括 value 和 effect)
示例:
ini
# 如果污点是:dedicated=gpu:NoSchedule
# 必须这样删:
kubectl taint node worker-01 dedicated=gpu:NoSchedule-
七、附录:常用命令速查
| 操作 | 命令 |
|--------------|------------------------------------------------------------|---------------|
| 查看节点污点 | `kubectl describe node | grep Taints` |
| 添加污点 | kubectl taint node <name> key=value:effect |
| 删除污点 | kubectl taint node <name> key=value:effect- |
| 删除所有某 key 污点 | kubectl taint node <name> key- |
| 查看 Pod 容忍 | kubectl get pod <name> -o jsonpath='{.spec.tolerations}' |
八、总结
- 污点(Taint) 是节点的"排斥规则",容忍(Toleration) 是 Pod 的"通行证"。
NoSchedule影响调度,NoExecute还会驱逐已有 Pod。- 生产环境中,合理使用污点可实现 节点隔离、资源专用、安全加固。
- 操作后务必 验证调度行为,避免业务中断。
✅ 最佳实践 :
对专用节点打污点 + 为对应工作负载配容忍,是 Kubernetes 资源管理的黄金组合。