在 Kubernetes (K8s) 的世界裡,調度 (Scheduling) 是一個核心議題。我們之前介紹過的 Node Affinity 是一種「吸引」機制,讓 Pod 可以選擇被調度到特定的 Node 上。
而 Taints (污點) 和 Tolerations (容忍) 則是一種反向的「排斥」機制。
我們可以把它們想像成一個 VIP 休息室:
簡單來說:
只有當 Pod 的 Toleration 與 Node 的 Taint 相匹配時,這個 Pod 才能被調度到該 Node 上。
您可以使用 kubectl taint
指令為 Node 加上或移除 Taint。一個 Taint 由三部分組成:key=value:effect
。
effect
是 Taint 最重要的部分,它定義了排斥行為的嚴格程度:
Effect | 描述 |
---|---|
NoSchedule |
不會將新的 Pod 調度到這個 Node 上,但不影響已經在上面運行的 Pod。 |
PreferNoSchedule |
盡量不要將新的 Pod 調度到這個 Node 上。這是一個「軟性」的限制,如果叢集中沒有其他可用的 Node,Scheduler 仍然可能會使用這個 Node。 |
NoExecute |
不會將新的 Pod 調度到這個 Node 上,並且會驅逐 (Evict) 已經在上面運行的、無法容忍此 Taint 的 Pod。 |
範例:
# 為 node1 加上一個 Taint,效果是 NoSchedule
kubectl taint nodes node1 dedicated=gpu:NoSchedule
# 移除上面加上的 Taint
kubectl taint nodes node1 dedicated=gpu:NoSchedule-
您可以在 Pod 的 spec 中定義 Tolerations,使其能夠被調度到帶有特定 Taint 的 Node 上。
Toleration 的設定需要與 Taint 的 key
、value
和 effect
相對應。operator
則定義了匹配的邏輯。
Operator | 描述 |
---|---|
Equal |
(預設) Toleration 的 key , value , effect 必須與 Taint 完全相等。 |
Exists |
只需要 Toleration 的 key 和 effect 與 Taint 匹配即可,忽略 value 。 |
範例:
apiVersion: v1
kind: Pod
metadata:
name: my-gpu-pod
spec:
containers:
- name: cuda-container
image: nvidia/cuda:11.0-base
tolerations:
# 這個 Toleration 匹配 key=dedicated, value=gpu, effect=NoSchedule 的 Taint
- key: "dedicated"
operator: "Equal"
value: "gpu"
effect: "NoSchedule"
這個 my-gpu-pod
因為擁有正確的 Toleration (VIP 通行證),所以可以被調度到我們剛剛設定的 node1
(VIP 休息室) 上。而其他沒有此 Toleration 的 Pod 則會被 node1
排斥。
NoExecute
的特別之處當 Node 被加上 NoExecute
Taint 時,K8s 會立刻檢查該 Node 上所有運行的 Pod。對於沒有對應 Toleration 的 Pod,會立即將其驅逐。
對於擁有對應 Toleration 的 Pod,您可以額外設定 tolerationSeconds
,讓 Pod 在被驅逐前有一段緩衝時間。
tolerations:
- key: "node.kubernetes.io/unreachable"
operator: "Exists"
effect: "NoExecute"
tolerationSeconds: 300
這個設定意味著:當此 Pod 所在的 Node 變得 unreachable
(失聯) 時,Pod 會繼續在該 Node 上運行 300 秒。如果 300 秒後 Node 仍未恢復,K8s 就會將此 Pod 驅逐,並嘗試在其他健康的 Node 上重建它。
專用節點 (Dedicated Nodes):
這是最常見的用途。您可以為一組需要特殊硬體(如 GPU)或有特殊需求的應用程式(如 CI/CD build jobs)準備專用的 Node。透過為這些 Node 加上 Taint,並只為對應的 Pod 加上 Toleration,可以確保這些 Node 不會被其他無關的應用程式佔用。
隔離控制平面 (Control Plane Isolation):
在一個標準的 K8s 叢集中,Control Plane 節點預設會被加上 Taint,以防止使用者應用程式被調度上去,從而保障叢集核心組件的穩定性。
基於節點狀況的驅逐 (Taint based Evictions):
K8s Controller Manager 會自動為符合特定條件的 Node 加上 Taint。例如,當 Node 失聯時,會被加上 node.kubernetes.io/unreachable
Taint;當 Node 記憶體壓力過大時,會被加上 node.kubernetes.io/memory-pressure
Taint。這些 Taint 預設的 effect
都是 NoExecute
,用來觸發自動驅逐機制,以維護應用的高可用性。
總結來說,Taints 和 Tolerations 提供了一種強大的機制,讓叢集管理者可以更精細地控制 Pod 的調度策略,將特定的工作負載引導到合適的 Node 上,或將其從不合適的 Node 上排斥出去。