跳到正文
复制成功
请遵守本站许可
报告
章节_文章 // 现场报告

文章编号: RL-TAINTS与T

2026.09.26

Taints 与 Tolerations:节点污点与容忍

Chavy
Chavy
#Kubernetes#调度#Taints#Tolerations
档案

摘要:梳理 NoSchedule、PreferNoSchedule 与 NoExecute 的区别,掌握污点与容忍的匹配规则、容忍时间,以及与节点亲和性的配合。

本节学习 Kubernetes 节点调度中非常重要的一组机制:污点(Taints)与容忍度(Tolerations)。

  • NodeSelector:根据节点标签选择节点。
  • Node Affinity:根据节点标签进行灵活调度。
  • Pod Affinity:让 Pod 靠近指定 Pod。
  • Pod Anti-Affinity:让 Pod 远离指定 Pod。
  • Topology Spread:控制 Pod 在不同拓扑域中的分布。

这些机制主要解决的是:

Pod 应该被调度到哪里?

而 Taints 与 Tolerations 主要解决:

哪些 Pod 可以进入某个节点?

这是两种不同的调度思路。


一、什么是 Taints 与 Tolerations?#

1. Taints:节点污点#

Taint(污点)是设置在 Node 上的一种调度限制。

它的作用是:

阻止不具备相应容忍条件的 Pod 被调度到该节点。

例如:

有一个专门用于数据库的节点:

PRTCL // TEXT
Node-1:普通业务节点
Node-2:普通业务节点
Node-3:数据库专用节点

我们希望:

  • Node-1、Node-2 可以运行普通业务。
  • Node-3 只运行数据库业务。
  • 普通 Web Pod 不允许进入 Node-3。

可以给 Node-3 添加污点:

PRTCL // BASH
Terminal window
kubectl taint nodes Node-3 dedicated=database:NoSchedule

此时:

flowchart TB
    N0["Node-3"]
    N1["dedicated=database:NoSchedule"]
    N2["普通 Pod 无法调度进入"]
    N0 --> N1
    N1 --> N2

2. Tolerations:容忍度#

Toleration(容忍度)是设置在 Pod 上的一种配置。

它表示:

Pod 能够容忍具有指定污点的节点。

例如:

数据库 Pod 配置:

PRTCL // YAML
tolerations:
- key: dedicated
operator: Equal
value: database
effect: NoSchedule

这样数据库 Pod 就能够容忍:

PRTCL // TEXT
dedicated=database:NoSchedule

从而允许进入 Node-3。

注意:

容忍污点不等于一定会调度到该节点。

它只代表 Pod 不会因为这个污点而被排斥。仍然需要满足节点资源、亲和性等其他调度条件。

3. Taints 与 Tolerations 的关系#

flowchart TB
    subgraph G0["没有容忍度的普通 Pod"]
        direction TB
        N0["Web Pod<br/>无法容忍污点"]
    end
    subgraph G1["具有容忍度的数据库 Pod"]
        direction TB
        N1["Database Pod<br/>能够容忍污点"]
    end
    N2["Node-3<br/>dedicated=database:NoSchedule<br/>拒绝不匹配的 Pod<br/>允许通过污点检查"]
    N0 --x|"拒绝不匹配的 Pod"| N2
    N1 -->|"允许通过污点检查"| N2

记忆:

  • Taint 设置在 Node 上。
  • Toleration 设置在 Pod 上。
  • Taint 是排斥条件。
  • Toleration 是容忍条件。

二、Taint 的组成结构#

Taint 由三个部分组成:

PRTCL // TEXT
key=value:effect

例如:

PRTCL // TEXT
dedicated=database:NoSchedule

三个部分分别是:

部分示例含义
keydedicated污点键
valuedatabase污点值
effectNoSchedule污点效果

其中 effect 非常重要。

Kubernetes 有三种主要污点效果:

  1. NoSchedule
  2. PreferNoSchedule
  3. NoExecute

三、Taint Effect:NoSchedule、PreferNoSchedule 与 NoExecute#

1. NoSchedule:禁止调度#

PRTCL // BASH
Terminal window
kubectl taint nodes worker-1 \
dedicated=database:NoSchedule

含义:

没有对应容忍度的 Pod,不允许被调度到该节点。

例如:

flowchart TB
    N0["Node-1"]
    N1["Web Pod:没有容忍度"]
    N2["DB Pod:有对应容忍度"]
    N3["拒绝调度"]
    N4["允许通过污点检查"]
    N0 --> N1
    N0 --> N2
    N1 --> N3
    N2 --> N4

注意:

NoSchedule 主要影响新 Pod 的调度。

如果某个 Pod 在添加污点之前已经运行在节点上,它不会仅仅因为添加了 NoSchedule 就自动被驱逐。

这是非常重要的区别。

2. PreferNoSchedule:尽量避免调度#

PRTCL // BASH
Terminal window
kubectl taint nodes worker-1 \
dedicated=database:PreferNoSchedule

含义:

Scheduler 尽量避免将不具备对应容忍度的 Pod 调度到该节点。

但是:

如果没有其他合适节点,仍然可能调度到这个节点。

它属于软性限制。

例如:

PRTCL // TEXT
Node-1:PreferNoSchedule 污点
Node-2:CPU 不足
Node-3:CPU 不足

如果 Node-1 是唯一可用节点,Pod 仍可能被调度到 Node-1。

3. NoExecute:禁止调度并驱逐#

PRTCL // BASH
Terminal window
kubectl taint nodes worker-1 \
dedicated=database:NoExecute

这是三种效果中限制最强的一种。

它有两个作用:

  1. 阻止不容忍该污点的新 Pod 被调度到节点。
  2. 驱逐已经运行在该节点、但不容忍该污点的 Pod。

例如:

flowchart TB
    N0["Node-1"]
    N1["Web Pod:没有容忍度"]
    N2["DB Pod:有容忍度"]
    N3["驱逐"]
    N4["保留"]
    N0 --> N1
    N0 --> N2
    N1 --> N3
    N2 --> N4

注意:

NoExecute 不仅影响后续调度,还会影响已有 Pod。

4. 三种 Effect 对比#

Effect新 Pod已运行 Pod
NoSchedule不允许不匹配的 Pod 调度不主动驱逐
PreferNoSchedule尽量避免调度不主动驱逐
NoExecute不允许不匹配的 Pod 调度驱逐不匹配的 Pod

CKA 高频考点

记忆口诀:

  • NoSchedule:不让进。
  • PreferNoSchedule:尽量不让进。
  • NoExecute:不让进,还要清出去。

四、Tolerations 配置详解#

接下来学习如何让 Pod 容忍节点污点。

1. Equal:精确匹配#

假设节点存在污点:

PRTCL // TEXT
dedicated=database:NoSchedule

Pod 配置:

PRTCL // YAML
apiVersion: v1
kind: Pod
metadata:
name: mysql
spec:
tolerations:
- key: dedicated
operator: Equal
value: database
effect: NoSchedule
containers:
- name: mysql
image: mysql:8.0

解释:

参数含义
key匹配污点的键
operatorEqual
value匹配污点的值
effect匹配污点效果

只有污点的 key、value、effect 都符合规则时,才会被容忍。

2. Exists:只要求键存在#

如果不关心污点的 value,只要 key 和 effect 匹配即可,可以使用 Exists。

例如:

PRTCL // YAML
tolerations:
- key: dedicated
operator: Exists
effect: NoSchedule

可以容忍:

PRTCL // TEXT
dedicated=database:NoSchedule
dedicated=redis:NoSchedule
dedicated=storage:NoSchedule

但是不能容忍:

PRTCL // TEXT
gpu=nvidia:NoSchedule

因为 key 不同。

3. Exists 与 Equal 对比#

对比EqualExists
匹配 key是是
匹配 value是否
匹配 effect指定时需要匹配指定时需要匹配
灵活程度精确更宽泛

4. 空 key 的 Exists#

还有一个特殊用法:

PRTCL // YAML
tolerations:
- operator: Exists
effect: NoSchedule

这里没有指定 key。

表示:

容忍所有 key 的 NoSchedule 污点。

但不会自动容忍其他 effect,例如 NoExecute。

如果同时省略 key 和 effect:

PRTCL // YAML
tolerations:
- operator: Exists

则可以容忍所有污点。

生产环境需要谨慎使用,因为它会让 Pod 失去很多节点污点提供的隔离保护。


五、tolerationSeconds:容忍时间#

这是 NoExecute 中非常重要的参数。

假设:

某个节点发生网络故障,Kubernetes 给节点添加了:

PRTCL // TEXT
node.kubernetes.io/not-ready:NoExecute

如果 Pod 没有容忍这个污点,就会被驱逐。

但是,有时候我们不希望 Pod 立即被驱逐。

例如:

节点只是短暂网络波动,我们希望等待 60 秒,观察节点能否恢复。

这时可以使用:

PRTCL // YAML
tolerations:
- key: node.kubernetes.io/not-ready
operator: Exists
effect: NoExecute
tolerationSeconds: 60

含义:

Pod 可以容忍这个 NoExecute 污点 60 秒。

如果 60 秒后污点仍然存在,Pod 就会被驱逐。

1. 三种情况#

配置行为
不配置 tolerationSeconds对匹配的 NoExecute 污点无限期容忍
tolerationSeconds: 60容忍 60 秒
tolerationSeconds: 0不等待,立即进入驱逐流程

注意:

tolerationSeconds 只适用于 NoExecute,不能用于 NoSchedule 或 PreferNoSchedule。

2. 完整示例#

PRTCL // YAML
apiVersion: v1
kind: Pod
metadata:
name: nginx
spec:
tolerations:
- key: dedicated
operator: Equal
value: database
effect: NoExecute
tolerationSeconds: 60
containers:
- name: nginx
image: nginx:1.27

如果节点存在:

PRTCL // TEXT
dedicated=database:NoExecute

那么:

  • 新创建的 Pod 可以容忍该污点。
  • Pod 已经运行时,可以继续运行 60 秒。
  • 60 秒后,如果污点仍存在,就会进入驱逐流程。

这里需要注意:容忍时间是从 Pod 开始容忍该污点时计算的,不是从 Pod 创建时计算的。


六、一个节点存在多个 Taint 怎么办?#

生产环境中,一个节点可以同时存在多个污点。

例如:

PRTCL // TEXT
worker-1
dedicated=database:NoSchedule
gpu=nvidia:NoSchedule
maintenance=true:NoExecute

现在创建一个 Pod:

PRTCL // YAML
tolerations:
- key: dedicated
operator: Equal
value: database
effect: NoSchedule

这个 Pod 只能容忍:

PRTCL // TEXT
dedicated=database:NoSchedule

但不能容忍:

PRTCL // TEXT
gpu=nvidia:NoSchedule
maintenance=true:NoExecute

因此仍然无法正常调度到该节点。

核心规则:一个 Pod 必须容忍节点上所有会排斥它的污点,才能通过污点检查。

例如:

PRTCL // YAML
tolerations:
- key: dedicated
operator: Equal
value: database
effect: NoSchedule
- key: gpu
operator: Equal
value: nvidia
effect: NoSchedule
- key: maintenance
operator: Equal
value: "true"
effect: NoExecute

这样才同时容忍上述三个污点。

注意:容忍全部污点也不代表 Pod 一定能调度到节点,还需要通过其他调度检查。


七、Taints 与 Node Affinity 如何配合?#

这是生产环境非常重要的知识。

假设我们有一个数据库专用节点:

PRTCL // TEXT
worker-1

我们的需求是:

  1. 普通 Pod 不允许进入。
  2. 数据库 Pod 可以进入。
  3. 数据库 Pod 尽量只运行在专用节点。

仅仅使用 Taints 与 Tolerations,能否实现?

不能完全实现。

因为:

Toleration 只是允许 Pod 进入具有对应污点的节点,但它不会强制 Pod 选择该节点。

例如:

数据库 Pod 具有:

PRTCL // YAML
tolerations:
- key: dedicated
operator: Equal
value: database
effect: NoSchedule

如果其他普通节点也满足调度条件,数据库 Pod 仍然可能被调度到普通节点。

所以需要同时使用:

  • Taints:拒绝不符合要求的 Pod。
  • Tolerations:允许指定 Pod 通过污点检查。
  • Node Affinity:让指定 Pod 选择专用节点。

1. 节点配置#

添加标签:

PRTCL // BASH
Terminal window
kubectl label node worker-1 \
workload=database

添加污点:

PRTCL // BASH
Terminal window
kubectl taint node worker-1 \
dedicated=database:NoSchedule

2. 数据库 Pod 配置#

PRTCL // YAML
apiVersion: v1
kind: Pod
metadata:
name: mysql
spec:
nodeSelector:
workload: database
tolerations:
- key: dedicated
operator: Equal
value: database
effect: NoSchedule
containers:
- name: mysql
image: mysql:8.0

现在形成了完整的调度控制:

数据库专用节点调度

worker-1 标签:workload=database 污点:dedicated=database

普通 Web Pod 拒绝 没有数据库污点容忍度

MySQL Pod 允许 具有 Toleration 和 NodeSelector

这就是生产环境中经常使用的专用节点隔离方案。


八、Kubernetes 默认污点#

这是理解 Kubernetes 节点调度机制的重要知识。

实际上,Kubernetes 自己也会根据节点状态添加污点。

例如:

Taint含义
node.kubernetes.io/not-ready节点未就绪
node.kubernetes.io/unreachable节点不可达
node.kubernetes.io/memory-pressure节点内存压力
node.kubernetes.io/disk-pressure节点磁盘压力
node.kubernetes.io/pid-pressure节点 PID 资源压力
node.kubernetes.io/network-unavailable节点网络不可用
node.kubernetes.io/unschedulable节点不可调度

这些污点会影响 Pod 的调度或驱逐。

1. 查看节点污点#

PRTCL // BASH
Terminal window
kubectl describe node worker-1

找到:

PRTCL // TEXT
Taints:

也可以使用:

PRTCL // BASH
Terminal window
kubectl get nodes \
-o custom-columns=NAME:.metadata.name,TAINTS:.spec.taints

2. Control Plane 节点为什么不能运行普通 Pod?#

很多人安装 Kubernetes 后会发现:

PRTCL // BASH
Terminal window
kubectl get nodes

控制平面节点显示 Ready,但普通 Pod 通常不会被调度到上面。

原因是 Kubernetes 通常会为 Control Plane 节点设置默认污点:

PRTCL // TEXT
node-role.kubernetes.io/control-plane:NoSchedule

这个污点用于防止普通工作负载进入控制平面节点。

查看:

PRTCL // BASH
Terminal window
kubectl describe node <control-plane 节点名称 >

3. 如何允许普通 Pod 进入 Control Plane?#

可以删除污点:

PRTCL // BASH
Terminal window
kubectl taint nodes <control-plane 节点名称 > \
node-role.kubernetes.io/control-plane:NoSchedule-

删除后,普通 Pod 就可能被调度到该节点。

注意:

生产环境一般不建议随意删除控制平面节点的默认污点,因为控制平面组件需要稳定的 CPU、内存和运行环境。


九、DaemonSet 为什么经常能够容忍系统污点?#

这里有一个容易被忽略的问题:

如果节点出现了:

PRTCL // TEXT
node.kubernetes.io/not-ready:NoExecute

那么为什么某些系统级 DaemonSet Pod 仍然可能存在于这个节点上?

原因之一是:

Kubernetes 的 DaemonSet Controller 会自动为 DaemonSet Pod 添加一些内置容忍度。

常见的包括:

PRTCL // YAML
tolerations:
- operator: Exists
effect: NoSchedule
- operator: Exists
effect: NoExecute

这样做是为了让节点级系统组件可以运行在具有某些污点的节点上。

例如:

  • 网络插件。
  • 节点监控 Agent。
  • 日志采集 Agent。
  • 存储节点组件。

但要注意:

这只是帮助 DaemonSet Pod 通过相关污点检查,不代表节点资源、镜像、网络等问题都会自动解决。

可以查看某个 DaemonSet Pod:

PRTCL // BASH
Terminal window
kubectl get pod <pod-name> -o yaml

搜索:

PRTCL // YAML
tolerations:

你会发现它可能具有多个自动添加的容忍规则。


十、Taints 与 Tolerations 实际操作命令#

这部分是 CKA 必须熟练掌握的命令。

1. 给节点添加污点#

PRTCL // BASH
Terminal window
kubectl taint nodes worker-1 \
dedicated=database:NoSchedule

2. 查看节点污点#

PRTCL // BASH
Terminal window
kubectl describe node worker-1

或者:

PRTCL // BASH
Terminal window
kubectl get nodes \
-o custom-columns=NAME:.metadata.name,TAINTS:.spec.taints

3. 修改污点#

先删除旧污点:

PRTCL // BASH
Terminal window
kubectl taint nodes worker-1 \
dedicated=database:NoSchedule-

再添加新污点:

PRTCL // BASH
Terminal window
kubectl taint nodes worker-1 \
dedicated=redis:NoSchedule

4. 删除污点#

PRTCL // BASH
Terminal window
kubectl taint nodes worker-1 \
dedicated=database:NoSchedule-

注意末尾的 - 表示删除对应污点。

5. 查看 Pod 容忍度#

PRTCL // BASH
Terminal window
kubectl get pod nginx -o yaml

查看:

PRTCL // YAML
spec:
tolerations:

6. 查看 Pod 调度失败原因#

PRTCL // BASH
Terminal window
kubectl describe pod nginx

重点关注:

PRTCL // TEXT
Events:
Warning FailedScheduling

例如:

PRTCL // TEXT
0/3 nodes are available:
1 node(s) had untolerated taint
2 Insufficient cpu

表示:

  • 一个节点存在 Pod 无法容忍的污点。
  • 两个节点 CPU 资源不足。

十一、CKA 高频易错点#

知识点正确理解
Taint 设置在哪里?Node
Toleration 设置在哪里?Pod
Toleration 是否强制调度到节点?不会
NoSchedule 是否驱逐已有 Pod?不会
PreferNoSchedule 是否绝对禁止调度?不会
NoExecute 是否驱逐已有 Pod?会驱逐不容忍的 Pod
tolerationSeconds 用在哪里?NoExecute
Exists 是否需要匹配 value?不需要
一个节点能有多个污点吗?可以
Pod 必须容忍所有排斥性污点吗?是
如何删除污点?命令末尾添加 -

特别记住:

Taints 是节点的排斥机制,Tolerations 是 Pod 的容忍机制,Node Affinity 是 Pod 的主动选择机制。

三者配合才能实现完整的节点调度隔离。


十二、本节知识体系总结#

Taints 与 Tolerations

flowchart TB
    N0["Node:Taint<br/>给节点设置污点,限制 Pod 进入"]
    N1["NoSchedule<br/>禁止调度"]
    N2["PreferNoSchedule<br/>尽量避免"]
    N3["NoExecute<br/>禁止并驱逐"]
    N4["Pod:Tolerations<br/>允许 Pod 容忍指定污点"]
    N0 --> N1
    N0 --> N2
    N0 --> N3
    N4 -.->|"容忍指定污点"| N0

关键参数

参数作用
key污点键
value污点值
effect污点效果
Equal精确匹配
Exists存在指定键即可
tolerationSecondsNoExecute 容忍时间
归档于 2026.09.26
// 档案结束
Classified
章节_06
协议编号: CC-BY-NC-SA-4.0

Taints 与 Tolerations:节点污点与容忍

作者:Chavy发布日期:2026.09.26

基于 CC BY-NC-SA 4.0

© 2026 Chavy
Powered by Astro