Kubernetes 节点污点(Taints)操作验证手册

版本 :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 节点通常有:

bash 复制代码
node-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 资源管理的黄金组合。

相关推荐
菜萝卜子1 小时前
k8s 启动一个redis
redis·容器·kubernetes
音视频牛哥1 小时前
AI时代底层技术链:GPU、云原生与大模型的协同进化全解析
大数据·云原生·kubernetes·音视频·transformer·gpu算力·云原生cloud native
米花町的小侦探2 小时前
Harbor安装
docker·kubernetes
周杰伦_Jay6 小时前
【 Kubernetes(K8s)完全指南】从入门到实战(含命令+配置+表格对比)
云原生·容器·kubernetes
Empty_7778 小时前
K8S-daemonset控制器
云原生·容器·kubernetes
一条懒鱼6669 小时前
K8S-daemonset控制器
云原生·容器·kubernetes
米花町的小侦探10 小时前
Rocky安装k8s
kubernetes
一周困⁸天.10 小时前
K8S-Service资源对象
云原生·容器·kubernetes
菜萝卜子12 小时前
k8s 本地动态存储 Local Path Provisioner 部署
容器·kubernetes