1. 引言
在管理 Kubernetes 集群时,理解 Pod 的调度机制是至关重要的。Taint(污点) 是实现节点调度控制的关键机制之一。它能“排斥”不符合容忍(Toleration)条件的 Pod,从而实现更精细的调度控制。
本文将介绍如何通过 kubectl
命令设置、查看和移除节点上的 Taint,帮助你更好地掌握 Kubernetes 的节点管理能力。我们会从基础命令讲起,逐步深入到高级查询与自动化脚本的使用。
2. 理解 Kubernetes Taint
Taint 是节点上的一个属性,用于阻止某些 Pod 被调度到该节点上,除非这些 Pod 明确设置了对应的 Toleration。
一个 Taint 通常由三个部分组成:
- Key(键):用于标识这个 Taint 的名称。
- Value(值):可选,用于进一步描述该 Taint。
- Effect(效果):定义了调度器在遇到未容忍的 Pod 时应采取的行为。
Effect 的三种类型:
Effect | 含义说明 |
---|---|
NoSchedule |
不允许调度新 Pod 到该节点(已有 Pod 不受影响) |
PreferNoSchedule |
尽量避免调度新 Pod 到该节点,但不强制 |
NoExecute |
不仅不允许新 Pod 调度,还会驱逐已经在该节点上运行但未容忍的 Pod |
✅ 示例:设置 Taint
$ kubectl taint nodes node1 app=blue:NoSchedule
node/node1 tainted
上述命令为节点 node1
添加了一个 Taint,表示只有设置了对应 Toleration 的 Pod 才能被调度到该节点。
3. Taint 的典型应用场景
3.1. 专用节点调度
在某些场景中,我们希望某些节点仅用于特定用途,比如 GPU 计算、数据库服务等。通过 Taint 可以有效隔离这些节点:
$ kubectl taint nodes node-gpu gpu=exclusive:NoSchedule
这样,只有设置了 gpu=exclusive
Toleration 的 Pod 才能调度到 node-gpu
节点。
3.2. 节点维护与升级
在节点维护期间,我们可以通过 Taint 控制节点的可用性:
- **使用
NoSchedule
**:防止新 Pod 调度进来,已有 Pod 保持运行。 - **使用
NoExecute
**:驱逐已有未容忍 Pod,彻底清空节点。
# 维护期间防止新 Pod 调度
$ kubectl taint nodes node1 maintenance:NoSchedule
# 硬件更换时驱逐所有 Pod
$ kubectl taint nodes node1 hardware:NoExecute
3.3. 紧急隔离节点
当节点发生安全事件或严重故障时,快速隔离节点可以防止影响扩散:
$ kubectl taint nodes node1 emergency:NoExecute
这样可以立即驱逐未容忍的 Pod,防止故障扩散。
4. 使用 kubectl 查看节点 Taint
4.1. 基础查看命令
使用 kubectl describe nodes
可以快速查看节点的 Taint 信息:
$ kubectl describe nodes node1
...
Taints: app=blue:NoSchedule
...
⚠️ 注意:该命令输出信息较多,适合临时查看,不适合自动化处理。
5. 高级 kubectl 查询技巧
5.1. JSON + JSONPath 查询
适合脚本处理,提取节点和 Taint 信息:
$ kubectl get nodes -o jsonpath="{range .items[*]}{.metadata.name}:{' '}{range .spec.taints[*]}{.key}={.value}:{.effect},{' '}{end}{'\n'}{end}"
输出示例:
node1: app=blue:NoSchedule,
node2: gpu=exclusive:NoSchedule,
node3:
5.2. 使用 jq 格式化输出
$ kubectl get nodes -o=json | jq -r '.items[] | .metadata.name + "\t" + (if .spec.taints then (.spec.taints | map(.key + "=" + (.value // "") + ":" + .effect) | join(", ")) else "No taints" end)'
输出示例:
node1 app=blue:NoSchedule, gpu=exclusive:PreferNoSchedule
node2 No taints
node3 storage=high:NoExecute
5.3. 查看所有节点的 Taint 键
$ kubectl get nodes -o=jsonpath='{range .items[*]}{.metadata.name}{"\t"}{.spec.taints[*].key}{"\n"}{end}'
输出示例:
node1 app
node2 gpu
node3
5.4. 按特定 Taint 过滤节点
$ kubectl get nodes -o go-template='{{range $item := .items}}{{with $nodename := $item.metadata.name}}{{range $taint := $item.spec.taints}}{{if and (eq $taint.key "node-role.kubernetes.io/master") (eq $taint.effect "NoSchedule")}}{{printf "%s\n" $nodename}}{{end}}{{end}}{{end}}{{end}}'
输出示例:
master-node
5.5. 自定义列输出(适合审计)
$ kubectl get nodes -o custom-columns=NAME:.metadata.name,ARCH:.status.nodeInfo.architecture,KERNEL:.status.nodeInfo.kernelVersion,TAINTS:.spec.taints
输出示例:
NAME ARCH KERNEL TAINTS
node1 amd64 4.19.0-6-amd64 [{"key":"app","value":"blue","effect":"NoSchedule"}]
node2 amd64 4.19.0-6-amd64 [{"key":"gpu","value":"exclusive","effect":"NoSchedule"}]
node3 amd64 4.19.0-6-amd64 []
5.6. 使用 Go 模板自定义输出
$ kubectl get nodes -o go-template='{{range .items}}{{.metadata.name}}{{"\t"}}{{range .spec.taints}}{{.key}}={{.value}}:{{.effect}}{{"\t"}}{{end}}{{"\n"}}{{end}}'
输出示例:
master-11 node-role.kubernetes.io/master=NoSchedule
master-12 node-role.kubernetes.io/master=NoSchedule
master-13 node-role.kubernetes.io/master=NoSchedule
6. 多租户集群中的 Taint 平衡
在多租户 Kubernetes 集群中,使用 Taint 可以实现租户间的资源隔离:
$ kubectl get nodes -o custom-columns='NAME:.metadata.name,TAINTS:.spec.taints,ALLOCATABLE_CPU:.status.allocatable.cpu,ALLOCATABLE_MEM:.status.allocatable.memory'
输出示例:
NAME TAINTS ALLOCATABLE_CPU ALLOCATABLE_MEM
node1 [{"key":"tenantA","effect":"NoSchedule"}] 8 32Gi
node2 [{"key":"tenantB","effect":"NoSchedule"}] 16 64Gi
node3 [] 4 16Gi
通过这种方式,我们可以清晰地看到每个节点的资源分配与隔离策略,便于进行资源调度和审计。
7. 自动化调整 Taint
以下是一个 Bash 脚本示例,根据节点 CPU 使用率自动添加或移除 Taint:
#!/bin/bash
NODE_NAME="node1"
CPU_USAGE=$(kubectl top node $NODE_NAME --no-headers | awk '{print $2}' | sed 's/%//')
if [ $CPU_USAGE -gt 90 ]; then
kubectl taint nodes $NODE_NAME high_cpu_usage:NoSchedule --overwrite
else
kubectl taint nodes $NODE_NAME high_cpu_usage:NoSchedule-
fi
✅ 使用方式:
chmod +x taint-nodes.sh
./taint-nodes.sh
✅ 自动执行(通过 cron):
*/5 * * * * /home/user/taint-nodes.sh >> /var/log/taint-nodes.log 2>&1
8. 移除 Taint
要移除一个节点上的 Taint,使用 -
表示删除:
# 移除带 Effect 的 Taint
$ kubectl taint nodes node1 key1=value1:NoSchedule-
# 仅移除 Key(忽略 Value 和 Effect)
$ kubectl taint nodes node1 key1-
⚠️ 注意:移除 Taint 后,未设置 Toleration 的 Pod 也可以被调度到该节点。
9. 总结
本文介绍了 Kubernetes 中 Taint 的设置、查看与移除方法,并通过多个 kubectl
命令演示了从基础到高级的使用技巧。掌握这些内容,可以帮助你在生产环境中更好地控制 Pod 的调度行为,实现资源隔离、节点维护和自动化管理。
✅ 关键点回顾:
- Taint 是节点调度控制的重要机制
- Effect 有三种类型:
NoSchedule
、PreferNoSchedule
、NoExecute
- 可通过
kubectl taint
设置和移除 Taint - 使用
kubectl describe
、jsonpath
、jq
、go-template
等方式灵活查看 Taint - 可结合脚本实现自动化调度控制
掌握这些技能,能显著提升你在 Kubernetes 集群管理中的效率与灵活性。