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 资源管理的黄金组合。

相关推荐
A-刘晨阳6 小时前
K8S 部署 CoreDNS 之 DNS 域名获取
运维·云原生·容器·kubernetes·dns·coredns
久绊A20 小时前
春节前云平台运维深度巡检-实操经验
运维·安全·容器·kubernetes·云平台
!chen21 小时前
银河麒麟v11 kubeadm部署k8s v1.35.0高可用集群
云原生·容器·kubernetes
DB!!!21 小时前
自学Kubernestes(k8s)Day1 -- 核心基础概念
云原生·容器·kubernetes
陈陈CHENCHEN1 天前
【Kubernetes】多集群管理实践 - kubeconfig
kubernetes
hwj运维之路1 天前
超详细ubuntu22.04部署k8s1.28高可用(二)【结合ingress实现业务高可用】
运维·云原生·容器·kubernetes
切糕师学AI1 天前
.NET Core Web 中的健康检查端点(Health Check Endpoint)
前端·kubernetes·.netcore
Cyber4K1 天前
【Kubernetes专项】K8s 控制器 DaemonSet 从入门到企业实战应用
云原生·容器·kubernetes
切糕师学AI1 天前
RKE(Rancher Kubernetes Engine) 是什么?
云原生·容器·kubernetes·rancher
龙飞051 天前
Kubernetes 排障实战:PVC 一直 Pending 的原因与解决方案
运维·学习·云原生·容器·kubernetes