9、k8s亲和性与污点容忍度
2026/9/4 18:19:12 网站建设 项目流程

1、Affity亲和性

在k8s中亲和性有两种:节点亲和性(node affinity)和Pod亲和性(pod affinity)。

1.1. 节点亲和性(Node Affinity)

定义
节点亲和性用于指定Pod与节点之间的关系,使Pod倾向于在具有特定标签或节点特征的节点上运行。

适用场景

  • 资源需求
    当某个Pod对计算资源(如CPU、内存)或其他特定硬件资源(如GPU)有特定需求时,可以使用节点亲和性将它调度到具有相应资源的节点上。这有助于优化资源利用和性能。

  • 逻辑分组
    当需要将相关的Pod分组部署到特定节点上时,可以使用节点亲和性。例如,在分布式系统中,某个节点需要承担特定的角色或任务,可以使用节点亲和性将相关的Pod调度到该节点上,以便实现逻辑上的分组和管理。

  • 特定硬件或软件要求
    当某个Pod需要依赖特定的硬件设备或软件环境时,可以使用节点亲和性将它调度到具备所需条件的节点上。例如,某个Pod需要与具有特定硬件加速器的节点进行通信,可以使用节点亲和性将它调度到具备所需硬件的节点上。

1.1.1 requiredDuringSchedulingIgnoredDuringExecution(硬亲和性)

新创建一个pod-aff.yaml配置,然后填入以下内容

apiVersion: v1 # Kubernetes API 版本 v1 kind: Pod # 资源类型为 Pod metadata: # 元数据部分 name: demo-pod # Pod 名称 namespace: default # 所属命名空间(默认) labels: # 标签集合,用于筛选和分组 app: busybox-tomcat # 应用标签 env: pro # 环境标签(生产环境) spec: # Pod 规格定义 affinity: # 亲和性配置 nodeAffinity: # 节点亲和性 requiredDuringSchedulingIgnoredDuringExecution: # 硬亲和性:调度时必须满足,运行时忽略变化 nodeSelectorTerms: # 节点选择器条件列表(多个 term 之间是 OR 关系) - matchExpressions: # 匹配表达式列表(多个表达式之间是 AND 关系) - key: a # 节点标签的键名 operator: In # 操作符:In 表示标签值必须在给定的列表中 values: # 标签值列表 - b # 允许的标签值(即节点必须包含标签 a=b) containers: # 容器列表,定义 Pod 中运行的容器 - name: tomcat # 第一个容器名称 ports: # 容器端口配置 - containerPort: 8080 # 容器内部监听的端口号 image: tomcat:8.5.34-jre8-alpine # 使用的镜像及标签 imagePullPolicy: IfNotPresent # 镜像拉取策略:仅当本地不存在时才拉取 - name: busybox # 第二个容器名称 image: busybox:latest # 使用的镜像及标签 imagePullPolicy: IfNotPresent # 镜像拉取策略同前 command: # 容器启动命令(覆盖镜像默认的 CMD) - "/bin/sh" # 调用 sh 解释器 - "-c" # 执行后续字符串中的命令 - "sleep 36000" # 休眠 36000 秒(即 10 小时),保持容器运行

启动这个pod

kubectl apply -f pod-aff.yaml

当前节点中有任意一个节点拥有a=b标签,就可以把pod调度到有a=b这个标签的节点,很显然我们的k8s集群中没有这样的一个标签,这次调度将会被pending。

执行查看pod详细信息命令,可以看到没有匹配到亲和节点,所以被挂起了

kubectl describe pod demo-pod

现在给k8s-node-1创建这个标签,就可以将这个pod给调度起来

kubectl label nodes k8s-node-1 a=b

1.1.2 preferredDuringSchedulingIgnoredDuringExecution(软亲和性)

顾名思义,软亲和性如果没有满足条件不会挂起,而是直接运行这个pod。如果满足条件则按照条件指定的节点调度pod

apiVersion: v1 # Kubernetes API 版本 v1 kind: Pod # 资源类型为 Pod metadata: # 元数据部分 name: demo-pod # Pod 名称 namespace: default # 所属命名空间(默认) labels: # 标签集合,用于筛选和分组 app: busybox-tomcat # 应用标签 env: pro # 环境标签(生产环境) spec: # Pod 规格定义 affinity: # 亲和性配置 nodeAffinity: # 节点亲和性 preferredDuringSchedulingIgnoredDuringExecution: # 软亲和性:调度时尽量满足,但不强制 - preference: # 偏好设置 matchExpressions: # 匹配表达式列表(多个表达式之间是 AND 关系) - key: a1 # 节点标签的键名 operator: In # 操作符:In 表示标签值必须在给定的列表中 values: # 标签值列表 - b1 # 偏好的标签值(节点包含标签 a1=b1 会被优先调度) weight: 80 # 权重值(范围 1-100),数值越高优先级越高 containers: # 容器列表,定义 Pod 中运行的容器 - name: tomcat # 第一个容器名称 ports: # 容器端口配置 - containerPort: 8080 # 容器内部监听的端口号 image: tomcat:8.5.34-jre8-alpine # 使用的镜像及标签 imagePullPolicy: IfNotPresent # 镜像拉取策略:仅当本地不存在时才拉取 - name: busybox # 第二个容器名称 image: busybox:latest # 使用的镜像及标签 imagePullPolicy: IfNotPresent # 镜像拉取策略同前 command: # 容器启动命令(覆盖镜像默认的 CMD) - "/bin/sh" # 调用 sh 解释器 - "-c" # 执行后续字符串中的命令 - "sleep 36000" # 休眠 36000 秒(即 10 小时),保持容器运行

可以看到我的集群中没有a1=b1的标签,但是k8s还是将pod调度到k8s-node-1节点,不会将这个pod挂起。

1.1.3 硬亲和性 vs 软亲和性对比

特性硬亲和性(required)软亲和性(preferred)
调度行为必须满足条件,否则 Pod 无法调度尽量满足条件,不满足也能调度
关键字requiredDuringSchedulingIgnoredDuringExecutionpreferredDuringSchedulingIgnoredDuringExecution
权重支持不支持支持(1-100),用于优先级排序
适用场景强制约束(如合规性、硬件要求)性能优化(如就近部署、资源偏好)

1.2. Pod亲和性(Pod Affinity)

定义
Pod亲和性用于指定Pod之间的关系,使它们倾向于在同一节点或具有相似特征的节点上运行。

适用场景

  • 数据本地性
    当两个或多个Pod需要访问相同的本地数据时,可以使用Pod亲和性将它们调度到同一节点上。例如,在分布式数据库中,多个数据库实例需要访问相同的数据卷或存储,可以通过Pod亲和性将它们调度到同一节点上,减少网络传输延迟。

  • 互为依赖
    当两个或多个Pod之间存在依赖关系,需要相互通信或协同工作时,可以使用Pod亲和性将它们调度到同一节点上。例如,在微服务架构中,某个服务需要与特定的缓存服务进行交互,可以使用Pod亲和性将它们调度到同一节点上,提高性能和减少网络开销。

  • 服务发现和负载均衡
    在需要实现服务发现和负载均衡的场景中,可以使用Pod亲和性将属于同一服务的多个实例调度到同一节点或相近的节点上。这样可以提高服务的可用性、降低延迟,并简化负载均衡配置。

1.2.1 requiredDuringSchedulingIgnoredDuringExecution(硬亲和性)

pod硬亲和性可以将两个pod同时调度到同一个节点,即tomcat-pod被调度到哪个节点,则busy-box也会被调度到同一个节点,我下面的例子中tomcat-pod被调度到node2节点,然后busy-box根据pod亲和性也会被调度到node2节点。

创建tomcat-pod.yaml

apiVersion: v1 # Kubernetes API 版本 v1 kind: Pod # 资源类型为 Pod metadata: # 元数据部分 name: tomcat-pod # Pod 名称 namespace: default # 所属命名空间(默认) labels: # 标签集合,用于筛选和分组 app: first # 应用标签,busybox 将通过此标签找到 tomcat Pod env: pro # 环境标签(生产环境) spec: # Pod 规格定义 containers: # 容器列表,定义 Pod 中运行的容器 - name: tomcat # 容器名称 ports: # 容器端口配置 - containerPort: 8080 # 容器内部监听的端口号 image: tomcat:8.5.34-jre8-alpine # 使用的镜像及标签 imagePullPolicy: IfNotPresent # 镜像拉取策略:仅当本地不存在时才拉取

创建busybox-pod.yaml

拓扑域键名:hostname 表示节点级别,即要求调度到同一节点

topologyKey: kubernetes.io/hostname

apiVersion: v1 # Kubernetes API 版本 v1 kind: Pod # 资源类型为 Pod metadata: # 元数据部分 name: busybox-pod # Pod 名称 namespace: default # 所属命名空间(默认) labels: # 标签集合,用于筛选和分组 app: busybox # 应用标签 env: pro # 环境标签(生产环境) spec: # Pod 规格定义 affinity: # 亲和性配置 podAffinity: # Pod 亲和性(与 Pod 的调度位置偏好相关) requiredDuringSchedulingIgnoredDuringExecution: # 硬亲和性:调度时必须满足,运行时忽略变化 - labelSelector: # 标签选择器,用于选择目标 Pod matchExpressions: # 匹配表达式列表(多个表达式之间是 AND 关系) - {key: app, operator: In, values: ["first"]} # 数组形式:选择标签 app=first 的 Pod 作为亲和目标 topologyKey: kubernetes.io/hostname # 拓扑域键名:hostname 表示节点级别,即要求调度到同一节点 containers: # 容器列表,定义 Pod 中运行的容器 - name: busybox # 容器名称 image: busybox:latest # 使用的镜像及标签 imagePullPolicy: IfNotPresent # 镜像拉取策略:仅当本地不存在时才拉取 command: # 容器启动命令(覆盖镜像默认的 CMD) - "/bin/sh" # 调用 sh 解释器 - "-c" # 执行后续字符串中的命令 - "sleep 36000" # 休眠 36000 秒(即 10 小时),保持容器运行

部署与验证命令

# 1. 给k8s-node-1和k8s-node-2加上标签 kubectl label nodes k8s-node-1 k8s-node-2 app=first env=pro # 2. 先启动 tomcat Pod(作为亲和性目标) kubectl apply -f tomcat-pod.yaml # 3. 等待 tomcat Pod 处于 Running 状态 kubectl get pod tomcat-pod -w # 4. 再启动 busybox Pod(会自动调度到 tomcat 所在节点) kubectl apply -f busybox-pod.yaml # 5. 验证两个 Pod 是否在同一节点(查看 NODE 列是否相同) kubectl get pods -o wide # 6. 查看 Pod 调度事件(确认亲和性生效) kubectl describe pod busybox-pod | grep -A 5 "Events"

1.2.2 preferredDuringSchedulingIgnoredDuringExecution(软亲和性)

tomcat-pod.yaml配置

apiVersion: v1 # Kubernetes API 版本 v1 kind: Pod # 资源类型为 Pod metadata: # 元数据部分 name: tomcat-pod # Pod 名称 namespace: default # 所属命名空间(默认) labels: # 标签集合,用于筛选和分组 app: first # 应用标签,busybox 将通过此标签找到 tomcat Pod env: pro # 环境标签(生产环境) spec: # Pod 规格定义 containers: # 容器列表,定义 Pod 中运行的容器 - name: tomcat # 容器名称 ports: # 容器端口配置 - containerPort: 8080 # 容器内部监听的端口号 image: tomcat:8.5.34-jre8-alpine # 使用的镜像及标签 imagePullPolicy: IfNotPresent # 镜像拉取策略:仅当本地不存在时才拉取

busybox-pod.yaml配置

apiVersion: v1 # Kubernetes API 版本 v1 kind: Pod # 资源类型为 Pod metadata: # 元数据部分 name: busybox-pod # Pod 名称 namespace: default # 所属命名空间(默认) labels: # 标签集合,用于筛选和分组 app: busybox # 应用标签 env: pro # 环境标签(生产环境) spec: # Pod 规格定义 affinity: # 亲和性配置 podAffinity: # Pod 亲和性(与 Pod 的调度位置偏好相关) preferredDuringSchedulingIgnoredDuringExecution: # 软亲和性:调度时尽量满足,但不强制 - weight: 80 # 权重值(范围 1-100),数值越高优先级越高,调度器会优先考虑此偏好 podAffinityTerm: # Pod 亲和性条件项 labelSelector: # 标签选择器,用于选择目标 Pod matchExpressions: # 匹配表达式列表(多个表达式之间是 AND 关系) - {key: app, operator: In, values: ["first"]} # 数组形式:选择标签 app=first 的 Pod 作为亲和目标 topologyKey: kubernetes.io/hostname # 拓扑域键名:hostname 表示节点级别,即尽量调度到同一节点 containers: # 容器列表,定义 Pod 中运行的容器 - name: busybox # 容器名称 image: busybox:latest # 使用的镜像及标签 imagePullPolicy: IfNotPresent # 镜像拉取策略:仅当本地不存在时才拉取 command: # 容器启动命令(覆盖镜像默认的 CMD) - "/bin/sh" # 调用 sh 解释器 - "-c" # 执行后续字符串中的命令 - "sleep 36000" # 休眠 36000 秒(即 10 小时),保持容器运行

1.2.3 硬亲和性 vs 软亲和性对比

对比维度硬亲和性(Required)软亲和性(Preferred)
关键字requiredDuringSchedulingIgnoredDuringExecutionpreferredDuringSchedulingIgnoredDuringExecution
调度行为必须满足条件,否则 Pod 无法调度尽量满足条件,不满足也能调度
调度结果找不到符合条件的节点 → Pod 保持 Pending找不到符合条件的节点 → Pod 正常调度到其他节点
权重支持❌ 不支持✅ 支持(1-100)
适用场景强制约束(合规性、硬件要求、数据本地性)性能优化(就近部署、资源偏好、减少延迟)

1.2.4 亲和性选择建议

场景推荐类型原因
合规性要求(如数据本地性)硬亲和性必须满足,否则业务无法运行
高性能计算(GPU 节点)硬亲和性必须调度到有 GPU 的节点
微服务就近部署(减少延迟)软亲和性优先同节点,但非强制
缓存与业务同节点软亲和性提升性能,但降级可用
多可用区容灾反亲和性(硬/软)分散部署,提高可用性

1.2.5反亲和性(硬亲和性)

之前我们创建了tomcat-pod和busybox-pod通过pod的亲和性将这两个pod调度到了同一个节点,现在我们可以使用pod的反亲和性,将这两个pod调度到不同的节点。亲和性调度到同一个节点的好处就是如果这两个服务有依赖关系且互相调用,对延迟敏感就可以使用pod的亲和性调度到同一个节点,避免跨节点访问,反亲和性调度到不同的节点使用场景就是两个服务没有太多的关联关系,且其中一个服务比较消耗资源,必须要分开部署或者具有其它必须分开的场景。

在这个例子中tomcat-pod.yaml配置保持不变,新增一个busybox-pod-ant.yaml即可。

apiVersion: v1 # Kubernetes API 版本 v1 kind: Pod # 资源类型为 Pod metadata: # 元数据部分 name: busybox-pod # Pod 名称 namespace: default # 所属命名空间(默认) labels: # 标签集合,用于筛选和分组 app: busybox # 应用标签 env: pro # 环境标签(生产环境) spec: # Pod 规格定义 affinity: # 亲和性配置 podAntiAffinity: # Pod 反亲和性(与 Pod 的调度位置分散相关) requiredDuringSchedulingIgnoredDuringExecution: # 硬反亲和性:调度时必须满足,运行时忽略变化 - labelSelector: # 标签选择器,用于选择目标 Pod matchExpressions: # 匹配表达式列表(多个表达式之间是 AND 关系) - {key: app, operator: In, values: ["first"]} # 数组形式:避免与标签 app=first 的 Pod 调度到同一节点 topologyKey: kubernetes.io/hostname # 拓扑域键名:hostname 表示节点级别,即要求分散到不同节点 containers: # 容器列表,定义 Pod 中运行的容器 - name: busybox # 容器名称 image: busybox:latest # 使用的镜像及标签 imagePullPolicy: IfNotPresent # 镜像拉取策略:仅当本地不存在时才拉取 command: # 容器启动命令(覆盖镜像默认的 CMD) - "/bin/sh" # 调用 sh 解释器 - "-c" # 执行后续字符串中的命令 - "sleep 36000" # 休眠 36000 秒(即 10 小时),保持容器运行
# 1. 删除 tomcat-pod、busybox-pod kubectl delete pod tomcat-pod busybox-pod --force --grace-period=0 # 2. 先启动 tomcat Pod(作为反亲和性目标) kubectl apply -f tomcat-pod.yaml # 3. 等待 tomcat Pod 处于 Running 状态 kubectl get pod tomcat-pod -w # 4. 再启动 busybox Pod(会自动调度到 tomcat 不同的节点) kubectl apply -f busybox-pod-ant.yaml # 5. 验证两个 Pod 是否在不同节点(查看 NODE 列是否不同) kubectl get pods -o wide # 6. 查看 Pod 调度事件(确认反亲和性生效) kubectl describe pod busybox-pod | grep -A 5 "Events"

我这里tomcat-pod调度到node2,busybox-pod调度到node1,但是busybox-pod一直处于创建容器状态,并没有真的启动,这时候执行命令查看busybox-pod详细信息

kubectl describe pod busybox-pod | grep -A 5 "Events"

这是 Calico 网络插件出现了认证问题,导致 Pod 无法正常创建网络沙箱。这与 Pod 的亲和性配置无关,而是集群网络组件的问题。

根本原因:Calico 的 Kubernetes API 认证失败,通常是因为:

  1. Calico 的 ServiceAccount 权限不足

  2. Calico 配置的 kubeconfig 证书失效或过期

  3. Calico 的 etcd 或 Kubernetes API 连接配置错误

需要重启Calico pod

# 删除 Calico Pod,它们会自动重建 kubectl delete pods -n kube-system -l k8s-app=calico-node kubectl delete pods -n kube-system -l k8s-app=calico-kube-controllers # 等待 Pod 重新启动 kubectl get pods -n kube-system -w | grep calico

然后再查看pod状态就OK了

kubectl get pods -o wide

busybox-pod正常启动,且被调度到node1节点

1.2.6反亲和性(软亲和性)

如果您需要软反亲和性(尽量分散,但不强制),可以使用以下配置:

busybox-pod-ant.yaml 配置如下:

apiVersion: v1 # Kubernetes API 版本 v1 kind: Pod # 资源类型为 Pod metadata: # 元数据部分 name: busybox-pod # Pod 名称 namespace: default # 所属命名空间(默认) labels: # 标签集合,用于筛选和分组 app: busybox # 应用标签 env: pro # 环境标签(生产环境) spec: # Pod 规格定义 affinity: # 亲和性配置 podAntiAffinity: # Pod 反亲和性(与 Pod 的调度位置分散相关) preferredDuringSchedulingIgnoredDuringExecution: # 软反亲和性:调度时尽量满足,但不强制 - weight: 80 # 权重值(范围 1-100),数值越高优先级越高 podAffinityTerm: # Pod 亲和性条件项 labelSelector: # 标签选择器,用于选择目标 Pod matchExpressions: # 匹配表达式列表(多个表达式之间是 AND 关系) - {key: app, operator: In, values: ["first"]} # 数组形式:尽量不与标签 app=first 的 Pod 调度到同一节点 topologyKey: kubernetes.io/hostname # 拓扑域键名:hostname 表示节点级别,即尽量分散到不同节点 containers: # 容器列表,定义 Pod 中运行的容器 - name: busybox # 容器名称 image: busybox:latest # 使用的镜像及标签 imagePullPolicy: IfNotPresent # 镜像拉取策略:仅当本地不存在时才拉取 command: # 容器启动命令(覆盖镜像默认的 CMD) - "/bin/sh" # 调用 sh 解释器 - "-c" # 执行后续字符串中的命令 - "sleep 36000" # 休眠 36000 秒(即 10 小时),保持容器运行

1.2.3 反亲和性硬性vs 反亲和性软性对比

对比维度硬反亲和性(Required)软反亲和性(Preferred)
关键字requiredDuringSchedulingIgnoredDuringExecutionpreferredDuringSchedulingIgnoredDuringExecution
调度行为必须分散,否则 Pod 无法调度尽量分散,无法分散也能调度
调度结果找不到其他节点 → Pod 保持 Pending找不到其他节点 → Pod 正常调度到同一节点
权重支持❌ 不支持✅ 支持(1-100)
适用场景高可用强制要求、容灾合规性能优化、资源均衡、尽力而为的分散

1.2.4 使用场景对比

场景推荐类型原因示例
金融/医疗系统硬反亲和性合规要求,必须跨节点/可用区部署银行核心系统、医疗病历系统
关键业务高可用硬反亲和性避免单点故障,保证业务连续性数据库、消息队列、注册中心
微服务多副本软反亲和性优先分散,但资源不足时可以容忍Web 应用、API 网关
资源均衡软反亲和性尽量分散负载,但不强制批处理任务、CI/CD 构建
跨可用区容灾硬反亲和性必须分散到不同可用区异地多活、灾备系统
开发测试环境软反亲和性资源有限时优先保证 Pod 运行测试环境、临时任务
StatefulSet 部署硬反亲和性每个副本必须在不同节点Kafka、Elasticsearch 集群

1.2.5 亲和性 vs 反亲和性对比

对比维度Pod 亲和性(Affinity)Pod 反亲和性(Anti-Affinity)
关键字podAffinitypodAntiAffinity
调度行为吸引:尽量/必须与目标 Pod 在同一节点排斥:尽量/必须不与目标 Pod 在同一节点
适用场景就近部署、减少延迟、缓存与业务同节点高可用、容灾、避免单点故障
配置语法与反亲和性对称与亲和性对称

1.2.6 常用拓扑域类型

topologyKey说明分散粒度
kubernetes.io/hostname按节点分散最细粒度(节点级别)
topology.kubernetes.io/zone按可用区分散中等粒度(机房级别)
topology.kubernetes.io/region按地域分散最大粒度(地域级别)

1.2.7 选择决策树

是否需要保证 Pod 必须分散在不同节点?

├── 是(合规/高可用要求)
│ └── 使用硬反亲和性(requiredDuringSchedulingIgnoredDuringExecution)
│ ├── 节点数足够 → 正常调度,成功分散
│ └── 节点数不足 → Pod Pending,无法调度

└── 否(性能优化/资源均衡)
└── 使用软反亲和性(preferredDuringSchedulingIgnoredDuringExecution)
├── 节点数足够 → 优先分散,效果好
└── 节点数不足 → 退而求其次,允许同节点

1.2.8 最佳实践

环境推荐配置理由
生产环境(关键应用)硬反亲和性 + 多副本保证高可用,避免单点故障
生产环境(非关键应用)软反亲和性提升可用性,但不过度消耗资源
开发测试环境软反亲和性或不用资源有限,保证 Pod 能运行
StatefulSet 有状态应用硬反亲和性每个副本独立节点,保证稳定性
Deployment 无状态应用软反亲和性均衡分布,提高资源利用率

2、污点和容忍度

污点是节点上定义的键值属性,用于拒绝 Pod 调度;容忍度是 Pod 上定义的键值属性,用于声明能容忍哪些污点。只有 Pod 的容忍度匹配节点的污点时,Pod 才能被调度到该节点。

概念定义位置作用关系
污点(Taints)节点(Node)标记节点,拒绝不匹配的 Pod 调度节点主动排斥 Pod
容忍度(Tolerations)Pod声明 Pod 能够容忍哪些污点Pod 主动申请豁免

节点打污点(Taint) → 拒绝不容忍的 Pod

Pod 设置容忍度(Toleration)→ 匹配污点 → 允许调度

不容忍的 Pod → 被拒绝调度(Pending)

2.1 污点与亲和性的区别

污点是节点"挑 Pod",亲和性是 Pod"挑节点",两者配合使用可实现精细的调度控制。

对比维度污点(Taints)节点亲和性(NodeAffinity)
定义位置节点Pod
作用节点拒绝Pod(排斥)Pod选择节点(吸引)
方向节点 → Pod(反向选择)Pod → 节点(正向选择)
主要用途隔离节点、专用节点按标签选择节点

2.2污点完整字段结构

kubectl taint nodes <节点名称> <键>=<值>:<污点效果>

污点由三个字段组成:

字段说明是否必填示例
键(Key)污点的标识符✅ 必填node-type,disk,gpu
值(Value)污点的具体值✅ 必填(配合键使用)production,ssd,nvidia
污点效果(Effect)定义 Pod 不匹配时的行为✅ 必填NoSchedule,PreferNoSchedule,NoExecute

2.3 污点效果(Effect)详解

Effect说明对已运行 Pod 的影响对未调度 Pod 的影响
NoSchedule硬性排斥不影响已运行的 Pod不容忍则无法调度
PreferNoSchedule软性排斥不影响已运行的 Pod不容忍则尽量不调度
NoExecute驱逐型排斥驱逐已运行且不容忍的 Pod不容忍则无法调度

2.4 示例演示

2.4.1 NoSchedule(硬性排斥)

# 给节点打污点:不容忍则无法调度 kubectl taint nodes k8s-node-1 node-type=production:NoSchedule # 查看节点污点 kubectl describe node k8s-node-1 | grep Taints # 输出:Taints: node-type=production:NoSchedule

2.4.2 PreferNoSchedule(软性排斥)

# 给节点打污点:尽量不调度,但资源不足时允许 kubectl taint nodes k8s-node-2 disk=ssd:PreferNoSchedule

2.4.3 NoExecute(驱逐型排斥)

# 给节点打污点:不容忍的 Pod 会被驱逐 kubectl taint nodes k8s-node-3 maintenance=true:NoExecute # 查看效果:已运行的 Pod 会被驱逐 kubectl get pods -o wide # 不容忍该污点的 Pod 状态变为 Pending 或重新调度到其他节点

2.4.4 污点完整操作命令

# 1. 添加污点 kubectl taint nodes k8s-node-1 gpu=nvidia:NoSchedule # 2. 查看节点所有污点 kubectl describe node k8s-node-1 | grep Taints # 或 kubectl get nodes k8s-node-1 -o json | jq '.spec.taints' # 3. 查看所有节点的污点 kubectl get nodes -o json | jq '.items[].spec.taints' # 4. 删除污点(在键后面加 -) kubectl taint nodes k8s-node-1 gpu:NoSchedule- # 5. 删除指定值的污点 kubectl taint nodes k8s-node-1 gpu=nvidia:NoSchedule- # 6. 更新污点(覆盖) kubectl taint nodes k8s-node-1 gpu=amd:NoSchedule --overwrite

2.4.5 污点对应的 Pod 容忍度(Tolerations)

tolerations: - key: "gpu" # 匹配污点的键 operator: "Equal" # 匹配操作符:Equal 或 Exists value: "nvidia" # 匹配污点的值(operator=Equal 时必填) effect: "NoSchedule" # 匹配污点的效果 tolerationSeconds: 3600 # 可选,驱逐前的容忍时间(仅 NoExecute 有效)

匹配规则

操作符规则示例
Equal键、值、效果必须完全匹配污点gpu=nvidia:NoSchedule→ 容忍key: gpu, value: nvidia, effect: NoSchedule
Exists只要键和效果匹配即可,忽略值污点gpu=nvidia:NoSchedule→ 容忍key: gpu, effect: NoSchedule

2.4.6 特殊容忍度(容忍所有污点)

系统级别的pod基本上都是容忍所有污点

tolerations: - operator: "Exists" # 匹配所有污点,忽略键、值、效果

2.4.7 生产环境典型使用场景

场景污点配置说明
GPU 专用节点kubectl taint nodes gpu-node gpu=nvidia:NoSchedule只允许需要 GPU 的 Pod 调度
维护节点kubectl taint nodes node-01 maintenance=true:NoExecute驱逐所有非维护 Pod
生产环境隔离kubectl taint nodes prod-node env=production:NoSchedule只允许生产 Pod 调度
SSD 优选节点kubectl taint nodes ssd-node disk=ssd:PreferNoSchedule优先调度,非必须

2.4.8 查看污点对应 Pod 是否容忍

# 1. 查看节点污点 kubectl describe node k8s-node-1 | grep Taints # 2. 查看 Pod 容忍度 kubectl describe pod my-pod | grep -A 5 Tolerations # 3. 查看 Pod 调度结果 kubectl get pods -o wide # 4. 查看调度失败原因 kubectl describe pod my-pod | grep -A 5 Events

污点核心字段:Key + Value + Effect,三者组合决定节点的"排斥策略"和 Pod 的"容忍能力"。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询