在 Kubernetes 污点(Taint) 和 容忍度(Toleration)是调度机制的一部分,用于控制哪些 Pod 可以被调度到哪些节点(Node)上。它们是 Kubernetes 中用于实现“排斥”逻辑的机制,目的是实现更细粒度的调度控制。
一、污点(Taint)
污点 是添加在 Node 节点 上的,它的作用是 防止 Pod 被调度到该节点上,除非 Pod 有与之“匹配”的 容忍度(Toleration)。
污点的格式:
key=value:effect
例如:
kubectl taint nodes node1 key1=value1:NoSchedule
表示给 node1
添加了一个 key1=value1
的污点,其 effect 为 NoSchedule
。
支持的 Effect 有:
Effect | 含义 |
---|---|
NoSchedule | 不允许新的 Pod 被调度到该节点(除非 Pod 有匹配的容忍度) |
PreferNoSchedule | 尽量不要调度,但不是强制性的 |
NoExecute | 不仅不调度新的 Pod,还会驱逐已经运行在该节点上的、不容忍该污点的 Pod |
二、容忍度(Toleration)
容忍度 是添加在 Pod 上的,它声明 Pod 能够“容忍”某些污点,从而允许调度到有该污点的 Node 上。
容忍度的格式(Pod spec 中的写法):
tolerations:
- key: "key1"
operator: "Equal" # 或 "Exists"
value: "value1"
effect: "NoSchedule"
tolerationSeconds: 3600 # 只对 NoExecute 有效,表示容忍多久
示例:
apiVersion: v1
kind: Pod
metadata:
name: mypod
spec:
tolerations:
- key: "key1"
operator: "Equal"
value: "value1"
effect: "NoSchedule"
这个 Pod 会被允许调度到含有 key1=value1:NoSchedule
污点的 Node 上。
三、示意逻辑图
[Node] 污点:key=value:NoSchedule
↓
Pod 是否包含对应的 toleration?
↓
是 → 可以调度
否 → 拒绝调度
四、典型使用场景
场景 | 描述 |
---|---|
节点资源隔离 | 把 GPU 节点加上污点,只有加了容忍度的 Pod 才能调度过去 |
节点故障隔离 | 当节点状态异常时(比如 memory pressure),K8s 可以自动打上污点,避免新的 Pod 被调度上去 |
临时驱逐 | 使用 NoExecute 驱逐不再适合的 Pod(如临时硬件问题) |
五、总结对比
项目 | 污点(Taint) | 容忍度(Toleration) |
---|---|---|
作用对象 | Node 节点 | Pod |
目的 | 拒绝某些 Pod 被调度上来 | 允许特定 Pod 忽略某些拒绝 |
是强制的吗? | 根据 effect 可强制 | 否,只是声明可以接受某些污点 |
接下来通过一个实战 Demo 来演示 Kubernetes 中 污点(Taint) 和 容忍度(Toleration) 的配合使用
💡 场景设定
我们有两个 Node:node1
和 node2
。
现在我们想让某些特殊 Pod 只能调度到 node1
,其他普通 Pod 则调度不到 node1
上。
✅ 步骤一:给 Node 添加污点
我们在 node1
上添加一个污点,拒绝调度普通 Pod:
kubectl taint nodes node1 special=true:NoSchedule
🔍 验证:
kubectl describe node node1 | grep Taint
输出应包含:
Taints: special=true:NoSchedule
✅ 步骤二:创建一个没有容忍度的 Pod
# pod-normal.yaml
apiVersion: v1
kind: Pod
metadata:
name: pod-normal
spec:
containers:
- name: nginx
image: nginx
运行:
kubectl apply -f pod-normal.yaml
然后查看调度情况:
kubectl get pod pod-normal -o wide
你会发现这个 Pod 不会调度到 node1
上,如果没有其他可用 Node,Pod 会一直处于 Pending
状态。
✅ 步骤三:创建一个带有容忍度的 Pod
# pod-special.yaml
apiVersion: v1
kind: Pod
metadata:
name: pod-special
spec:
tolerations:
- key: "special"
operator: "Equal"
value: "true"
effect: "NoSchedule"
containers:
- name: nginx
image: nginx
运行:
kubectl apply -f pod-special.yaml
查看状态:
kubectl get pod pod-special -o wide
你会看到这个 Pod 会被调度到 node1
,因为它有容忍度。
✅ 步骤四:清除污点
kubectl taint nodes node1 special=true:NoSchedule-