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 场景下的驱逐逻辑:

Taint Effect 调度决策流程 节点存在 Taint NoSchedule PreferNoSchedule NoExecute 调度器拒绝新 Pod 已有 Pod 不受影响 调度器尽量避开 资源不足时仍可调度 调度器拒绝新 Pod 检查已有 Pod 容忍 有容忍 → 保留 无容忍 → 驱逐 关键区别 NoSchedule 只影响新 Pod;PreferNoSchedule 是软约束;NoExecute 同时影响新 Pod 和已有 Pod

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 驱逐风暴。