4. 污点(Taint)概念与语法:Taint 的组成与 Effect 类型
污点(Taint)是 Kubernetes 调度体系中用于排斥 Pod 的一种节点属性。它与容忍度(Toleration)配合,形成“节点声明约束 → Pod 声明容忍”的准入控制机制。理解 Taint 的组成与 Effect 类型,是分析调度器瓶颈、设计精细化调度策略的基础。
4.1 Taint 的组成结构
一个完整的 Taint 由三个字段组成,使用 kubectl taint 命令或节点 YAML 的 spec.taints 字段定义:
| 字段 | 名称 | 说明 | 示例值 |
|---|---|---|---|
| Key | 键 | 污点的标识符,类似标签的 Key,可包含前缀(如 node.kubernetes.io/) |
gpu、node.kubernetes.io/unreachable |
| Value | 值 | 污点的具体取值,可为空字符串;用于区分同一 Key 下的不同状态 | true、nvidia-tesla、"" |
| Effect | 效果 | 定义 Pod 不匹配该污点时,调度器或 kubelet 采取的行为 | NoSchedule、PreferNoSchedule、NoExecute |
在 YAML 中,Taint 的完整表达如下:
spec:
taints:
- key: "gpu"
value: "nvidia-tesla"
effect: "NoSchedule"
- key: "node.kubernetes.io/unreachable"
value: ""
effect: "NoExecute"
使用命令行添加污点:
kubectl taint nodes node1 gpu=nvidia-tesla:NoSchedule
kubectl taint nodes node1 node.kubernetes.io/unreachable=:NoExecute
Key 命名规范:Kubernetes 系统级污点使用
node.kubernetes.io/ 前缀,用户自定义污点建议使用有意义的业务前缀(如 infra/、workload/),避免与系统污点冲突。
4.2 Effect 类型详解
Effect 是 Taint 的核心行为定义,决定了调度器与 kubelet 如何处理不匹配该污点的 Pod。三种 Effect 的差异直接影响调度决策与运行中 Pod 的命运。
| Effect 类型 | 调度阶段行为 | 运行中 Pod 行为 | 典型场景 |
|---|---|---|---|
| NoSchedule | 调度器不会将新 Pod 调度到该节点 | 不影响已在运行的 Pod | 节点维护、专用硬件隔离 |
| PreferNoSchedule | 调度器尽量不调度新 Pod 到该节点(软约束) | 不影响已在运行的 Pod | 节点负载均衡、成本优化 |
| NoExecute | 调度器不会将新 Pod 调度到该节点 | 立即驱逐不匹配的已有 Pod(除非设置 tolerationSeconds) |
节点故障、安全隔离、紧急维护 |
NoExecute 的驱逐行为:当节点被添加
NoExecute 污点时,kubelet 会立即驱逐所有不匹配该污点的 Pod。如果 Pod 设置了 tolerationSeconds,则会在指定秒数后驱逐。这是调度器瓶颈分析中需要重点关注的“强制驱逐”场景。
4.3 三种 Effect 的调度决策流程
下图展示了调度器在处理不同 Effect 时的决策路径,以及 kubelet 在 NoExecute 场景下的驱逐逻辑:
4.4 系统内置污点与 Effect 组合
Kubernetes 节点控制器会自动为节点添加系统级污点,这些污点使用 node.kubernetes.io/ 前缀,Effect 通常为 NoExecute 或 NoSchedule:
| 系统污点 Key | Effect | 触发条件 |
|---|---|---|
node.kubernetes.io/not-ready |
NoExecute | 节点状态变为 NotReady |
node.kubernetes.io/unreachable |
NoExecute | 节点控制器无法访问节点 |
node.kubernetes.io/out-of-disk |
NoSchedule | 节点磁盘空间不足 |
node.kubernetes.io/memory-pressure |
NoSchedule | 节点内存压力过高 |
node.kubernetes.io/disk-pressure |
NoSchedule | 节点磁盘 I/O 压力过高 |
node.kubernetes.io/network-unavailable |
NoSchedule | 节点网络不可用 |
node.kubernetes.io/unschedulable |
NoSchedule | 节点被标记为不可调度(kubectl cordon) |
调度器瓶颈分析要点:系统污点(尤其是
not-ready 和 unreachable)的 NoExecute 效果会触发大规模 Pod 驱逐,导致调度器在短时间内收到大量调度请求。这是集群调度瓶颈的常见诱因之一,后续章节将深入分析其影响。
4.5 多污点叠加与调度决策
一个节点可以同时设置多个污点,调度器会逐一检查每个污点。只有当 Pod 容忍了节点上所有污点时,才能被调度到该节点。如果存在任意一个未容忍的 NoSchedule 或 NoExecute 污点,调度器将拒绝该 Pod。
多污点叠加的决策规则:
- NoSchedule + NoSchedule:只要有一个未容忍,调度器拒绝。
- NoSchedule + PreferNoSchedule:未容忍 NoSchedule 则拒绝;未容忍 PreferNoSchedule 则尽量避开。
- NoExecute + 其他:未容忍 NoExecute 则立即驱逐(已有 Pod)或拒绝(新 Pod)。
实践建议:在运维中,建议将
NoSchedule 用于计划内维护(如节点升级),将 NoExecute 用于故障隔离。避免在同一个节点上同时使用多个 NoExecute 污点,以免造成不必要的 Pod 驱逐风暴。