Kubernetes :Taints(污點)和Tolerations(容忍)

目錄

Taint

基本用法

effect 的取值

NoExecute 

Toleration

基本用法

Toleration 幾個特殊情況:

key 爲空並且 operator 等於 Exists

effect 爲空

TolerationSeconds

多污點與多容忍配置

kubernetes 內置taint行爲

Taints(污點)和Tolerations(容忍)示例

專用節點

具有特殊硬件的節點

基於 taint 的驅逐


  • Taint(污點)和 Toleration(容忍)可以作用於 node 和 pod 上,其目的是優化 pod 在集羣間的調度,它們相互配合,可以用來避免 pod 被分配到不合適的節點上。
  • 不同於Kubernetes 親和性調度---是描述 pod 的屬性,來聲明此 pod 希望調度到哪類 nodes
  •  Taint(污點) 剛好相反,它是node 的一個屬性,允許 node 主動排斥 pod 的調度。
  • 對應的 k8s 又給 pod 新增了配套屬性 toleration(容忍) ,用於表示這些 pod 可以(但不強制要求)被調度到具有相應 taints 的 nodes 上。這兩者經常一起搭配,來確保不將 pod 調度到不合適的 nodes

Taint

基本用法

  • 設置污點: kubectl taint node [node] key=value:[effect]
    其中 [effect] 可取值:[ NoSchedule | PreferNoSchedule | NoExecute ]:
    • NoSchedule :一定不能被調度。
    • PreferNoSchedule:儘量不要調度。
    • NoExecute:不僅不會調度,還會驅逐 Node 上已有的 Pod。
  • 去除污點:kubectl taint node [node] key:[effect]-

effect 的取值

下面對 effect 的值作下簡單說明:

  • NoSchedule:如果一個 pod 沒有聲明容忍這個 Taint,則系統不會把該 Pod 調度到有這個 Taint 的 node 上
  • PreferNoSchedule:NoSchedule 的軟限制版本,如果一個 Pod 沒有聲明容忍這個 Taint,則系統會盡量避免把這個 pod 調度到這一節點上去,但不是強制的。
  • NoExecute:定義 pod 的驅逐行爲,以應對節點故障。

NoExecute 

NoExecute 這個 Taint 效果對節點上正在運行的 pod 有以下影響:

  • 沒有設置 Toleration 的 Pod 會被立刻驅逐
  • 配置了對應 Toleration 的 pod,如果沒有爲 tolerationSeconds 賦值,則會一直留在這一節點中
  • 配置了對應 Toleration 的 pod 且指定了 tolerationSeconds 值,則會在指定時間後驅逐

從 kubernetes1.6 版本開始引入了一個 alpha 版本的功能,即把節點故障標記爲 Taint(目前只針對 node unreachable 及 node not ready,相應的 NodeCondition "Ready" 的值爲 Unknown 和 False)。

激活 TaintBasedEvictions 功能後(在–feature-gates 參數中加入 TaintBasedEvictions=true),NodeController 會自動爲 Node 設置 Taint,而狀態爲 "Ready" 的 Node 上之前設置過的普通驅逐邏輯將會被禁用。

注意,在節點故障情況下,爲了保持現存的 pod 驅逐的限速設置,系統將會以限速的模式逐步給 node 設置 Taint,這就能防止在一些特定情況下(比如 master 暫時失聯)造成的大量 pod 被驅逐的後果。這一功能兼容於 tolerationSeconds,允許 pod 定義節點故障時持續多久才被逐出。

NoExecute 效應由 TaintBasedEviction 控制, TaintBasedEviction 是 Beta 版功能,自 Kubernetes 1.13 起默認啓用。

Toleration

基本用法

你可以在PodSpec中爲容器設定容忍標籤。以下兩個容忍標籤都與上面的 kubectl taint 創建的污點“匹配”, 因此具有任一容忍標籤的Pod都可以將其調度到“ node1”上:

tolerations:
- key: "key"
  operator: "Equal"
  value: "value"
  effect: "NoSchedule"
tolerations:
- key: "key"
  operator: "Exists"
  effect: "NoSchedule"

再看下 PodSpec 配置 Tolerations,其中的 key、value、effect 與 Node Taint 設置需要保持一致,operator 支持兩類:

  • operator 的值爲 Exists,這時無需指定 value

  • operator 的值爲 Equal 並且 value 相等(如果不指定 operator,則默認值爲 Equal)

Toleration 幾個特殊情況:

key 爲空並且 operator 等於 Exists

  • 表示匹配了所有的 keys,values 和 effects。換句話說就是容忍了所有的 taints。
tolerations:
- operator: "Exists"

effect 爲空

  • 則表示匹配所有的 effects(NoSchedule、PreferNoSchedule、NoExecute)
tolerations:
- key: "key"
  operator: "Exists"

TolerationSeconds

該值與 effect 爲 NoExecute 配套使用。用來指定在 node 添加了 effect = NoExecute 的 taint 後,能容忍該 taint 的 pods 可停留在 node 上的時間。
例如:

tolerations: 
- key: "key1"
  operator: "Equal"
  value: "value1"
  effect: "NoExecute"
  tolerationSeconds: 3600

表示如果這個 pod 已經運行在 node 上並且該 node 添加了一個對應的 taint,那麼這個 pod 將會在 node 上停留 3600 秒後纔會被驅逐。但是如果 taint 在這個時間前被移除,那麼這個 pod 也就不會被驅逐了。

多污點與多容忍配置

我們可以對 node 設置多個 taints,當然也可以在 pod 配置相同個數的 tolerations。影響調度和運行的具體行爲,我們可以分爲以下幾類:

  • 如果至少有一個 effect == NoSchedule 的 taint 沒有被 pod toleration,那麼 pod 不會被調度到該節點上。
  • 如果所有 effect == NoSchedule 的 taints 都被 pod toleration,但是至少有一個 effect == PreferNoSchedule 沒有被 pod toleration,那麼 k8s 將努力嘗試不把 pod 調度到該節點上。
  • 如果至少有一個 effect == NoExecute 的 taint 沒有被 pod toleration,那麼不僅這個 pod 不會被調度到該節點,甚至這個節點上已經運行但是也沒有設置容忍該污點的 pods,都將被驅逐。

kubernetes 內置taint行爲

kubernetes 1.6 版本,node controller 會跟進系統情況自動設置 node taint 屬性。
內置 taint key 如下:

  • node.kubernetes.io/not-ready: 節點尚未就緒
  • node.kubernetes.io/unreachable: 節點無法被訪問
  • node.kubernetes.io/unschedulable: 節點不可調度
  • node.kubernetes.io/out-of-disk: 節點磁盤不足
  • node.kubernetes.io/memory-pressure: 節點有內存壓力
  • node.kubernetes.io/disk-pressure: 節點有磁盤壓力
  • node.kubernetes.io/network-unavailable: 節點網絡不可用
  • node.kubernetes.io/pid-pressure: 節點有 pid 壓力
  • node.cloudprovider.kubernetes.io/uninitialized: 雲節點未初始化
  • node.cloudprovider.kubernetes.io/shutdown: 雲節點已下線

kubernetes 會通過 DefaultTolerationSeconds admission controller 爲創建的 pod 添加兩個默認的 toleration: node.kubernetes.io/not-ready 和 node.kubernetes.io/unreachable並且設置 tolerationSeconds = 300。當然這個默認配置,用戶可以自行覆蓋。
這些自動添加的默認配置,確保 node 出現問題後,pod 可以繼續在 node 上停留 5 分鐘。

DefaultTolerationSeconds admission controller 設置的 tolerationSeconds 值,也可以由用戶指定。
具體參考: https://github.com/kubernetes/kubernetes/blob/master/plugin/pkg/admission/defaulttolerationseconds/admission.go

還有一個默認行爲,就是 DaemonSet。

所有 DaemonSet 創建的 pod 都會添加兩個 toleration: node.alpha.kubernetes.io/unreachable 和 node.alpha.kubernetes.io/notReady。設置 effect = NoExecute,並且不指定 tolerationSeconds
目的是確保在 node 出現 unreachable 或 notReady 的問題時,DaemonSet Pods 永遠不會被驅逐。

Taints(污點)和Tolerations(容忍)示例

專用節點

如果你希望將一組節點專用於特定的用戶,那可以將這些節點設置 taints,

 kubectl taint nodes nodename dedicated=groupName:NoSchedule

然後給這些應用的 pod 加入相應的 toleration,則帶有合適 toleration 的 pod 就會被允許同使用其他節點一樣使用有 taint 的節點。

如果你希望節點被專用並且確保服務僅使用這批節點,那麼你還應該向這些 node 打上指定的標籤 (dedicated=groupName),並且爲對應的 pods 設置 NodeAffinity,以控制 pods 只能跑到這批節點上。

具有特殊硬件的節點

有部分帶有特殊硬件的節點,比如 GPU、FPGA 等,要確保不將不需要專用硬件的 pods 調度到這些節點。也可以和 專有節點 一樣的方式設置 taints:

kubectl taint nodes test special=true:NoSchedule  
kubectl taint nodes test special=true:PreferNoSchedule

然後在 pod 中利用對應的 toleration 來保障特定的 pod 能夠使用特定的硬件。然後同樣的,我們也可以使用標籤或者其他的一些特徵來判斷這些 pod,將其調度到這些特定硬件的服務器上。

建議還可以通過 Extended Resources 和 ExtendedResourceToleration admission controller 來更方便的調度依賴特殊硬件的 pods,而不需要手動添加容器的 toleration

基於 taint 的驅逐

之前說到,在節點故障時,可以通過 TaintBasedEvictions 功能自動將節點設置 Taint,然後將 pod 驅逐。

但是在一些場景下,比如說網絡故障造成的 master 與 node 失聯,而這個 node 上運行了很多本地狀態的應用即使網絡故障,也仍然希望能夠持續在該節點上運行,期望網絡能夠快速恢復,從而避免從這個 node 上被驅逐。Pod 的 Toleration 可以這樣定義:

tolerations:  
- key: "node.alpha.kubernetes.io/unreachable"
  operator:"Exists" 
  effect: "NoExecute"  
  tolerationSeconds: 6000
對於 Node 未就緒狀態,可以把 key 設置爲 node.alpha.kubernetes.io/notReady
  • 如果沒有爲 pod 指定 node.alpha.kubernetes.io/noReady 的 Toleration,那麼 Kubernetes 會自動爲 pod 加入 tolerationSeconds=300 的 node.alpha.kubernetes.io/notReady 類型的 toleration。
  • 如果沒有爲 pod 指定 node.alpha.kubernetes.io/unreachable 的 Toleration,那麼 Kubernetes 會自動爲 pod 加入 tolerationSeconds=300 的 node.alpha.kubernetes.io/unreachable 類型的 toleration。

這些系統自動設置的 toleration 用於在 node 發現問題時,能夠爲 pod 確保驅逐前再運行 5min。這兩個默認的 toleration 由 Admission Controller "DefaultTolerationSeconds" 自動加入。

參考鏈接:https://kubernetes.io/zh/docs/concepts/configuration/taint-and-toleration/

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章