← 返回上一頁
Kubernetes

K8s 污點與容忍度完整解析:從觀念到實戰一次搞懂節點調度控制

本頁目錄

前言

Kubernetes 的調度機制中,污點(Taint)和容忍度(Toleration)是控制 Pod 落在哪些節點上的重要手段。一句話總結:如果 Pod 能容忍某個節點上的污點,它就可以被調度到該節點;不能容忍,就不會被調度過去。

打個比方,就像談戀愛——如果你知道對方的缺點但還是願意接受,那就可以在一起;無法接受的話,就沒辦法了。

核心觀念

污點與容忍度的定義

名詞 定義在 作用
污點(Taint) 節點上 拒絕不具備對應容忍度的 Pod 調度到此節點
容忍度(Toleration) Pod 上 讓 Pod 可以被調度到帶有特定污點的節點

三種排斥等級(Effect)

等級 對新 Pod 的影響 對已存在 Pod 的影響
NoSchedule 不能調度到此節點 不受影響
PreferNoSchedule 盡量不調度,但找不到其他節點時還是會 不受影響
NoExecute 不能調度到此節點 已存在的 Pod 會被驅逐

兩種操作符

操作符 比對方式
Equal key、value、effect 三者完全匹配
Exists 只比對 key 和 effect,value 留空

污點的語法格式:key=value:effect

常見使用場景

場景 1:節點獨佔

叢集中有些機器配備特殊硬體(如 GPU、大記憶體),不希望一般的 Pod 佔用這些節點。做法:

  1. 給特殊節點加上污點
  2. 只有需要這些資源的 Pod 才設定對應的容忍度

場景 2:自動驅逐

K8s 會自動在問題節點上打污點,例如:

內建污點 觸發條件
node.kubernetes.io/not-ready 節點未就緒
node.kubernetes.io/unreachable 節點不可達
node.kubernetes.io/memory-pressure 記憶體不足
node.kubernetes.io/disk-pressure 磁碟空間不足
node.kubernetes.io/network-unavailable 網路不可用

這些污點會使用 NoExecute 等級,導致沒有對應容忍度的 Pod 被驅逐。DaemonSet 控制器會自動忽略這類污點,確保重要的系統 Pod 持續運行。

實戰操作

管理節點污點

# 加入污點
kubectl taint nodes node01 key=value:NoSchedule

# 刪除污點(key 後面加減號)
kubectl taint nodes node01 key:NoSchedule-

# 刪除某 key 的所有污點(不指定 effect)
kubectl taint nodes node01 key-

查看節點資訊

# 查看節點 label
kubectl get nodes --show-labels

# 查看節點詳細資訊(包含 Taints)
kubectl describe node <node-name>

# 加入節點 label
kubectl label node <node-name> special-app=specialwebapp

完整實戰流程

步驟 1:給節點加上污點

kubectl taint nodes k8s-worker-2 question-node=broken-disk:NoSchedule

步驟 2:部署 Pod(不含容忍度)→ Pod 會卡在 Pending

查看原因:kubectl describe pod <pod-name> 會看到 "node(s) had taints that the pod didn't tolerate"

步驟 3:加上容忍度後重新部署 → 調度成功

完整的 Pod YAML:

apiVersion: v1
kind: Pod
metadata:
  name: webapp
  namespace: demo
  labels:
    app: webapp
spec:
  nodeSelector:
    special-app: specialwebapp
  tolerations:
  - key: "question-node"
    operator: "Equal"
    value: "broken-disk"
    effect: "NoSchedule"
  containers:
  - name: webapp
    image: nginx
    ports:
    - containerPort: 80

延遲驅逐:tolerationSeconds

當污點等級是 NoExecute 時,已存在的 Pod 會被立刻驅逐。但你可以用 tolerationSeconds 設定一個寬限時間:

tolerations:
- key: "question-node"
  operator: "Equal"
  value: "broken-disk"
  effect: "NoExecute"
  tolerationSeconds: 3600  # Pod 還能繼續運行 3600 秒

這在節點短暫出問題但可能很快恢復的場景下非常實用。

小結

污點和容忍度是 K8s 調度機制中非常重要的一環。核心規則就一條:Pod 必須容忍節點的污點才能被調度上去。善用 NoSchedulePreferNoScheduleNoExecute 三種等級,搭配節點 label 和 nodeSelector,你就能精確控制 Pod 的調度行為。

分享這篇
X LinkedIn Facebook Hacker News Reddit

發佈留言

發佈留言必須填寫的電子郵件地址不會公開。 必填欄位標示為 *

這個網站採用 Akismet 服務減少垃圾留言。進一步了解 Akismet 如何處理網站訪客的留言資料