Kubernetes taint & toleration

1、概述

前一篇文章講解了 Kubernetes 親和性調度, 所涉及的內容都是描述 pod 的屬性,來聲明此 pod 但願調度到哪類 nodes。而本文介紹的 Taint(污點) 恰好相反,它是node 的一個屬性,容許 node 主動排斥 pod 的調度。
對應的 k8s 又給 pod 新增了配套屬性 toleration(容忍) ,用於表示這些 pod 能夠(但不強制要求)被調度到具備相應 taints 的 nodes 上。
這二者常常一塊兒搭配,來確保不將 pod 調度到不合適的 nodes。node

看下 taint & toleration 結構體,下面足點介紹時會涉及相關字段。git

type Taint struct {
    Key string
    Value string
    Effect TaintEffect
    // add taint 的時間點
    // 只有 Effect = NoExecute, 該值纔會被 nodeController 寫入
    TimeAdded *metav1.Time
}

type Toleration struct {
    Key string
    Operator TolerationOperator
    Value string
    Effect TaintEffect
    // 容忍時間
    TolerationSeconds *int64
}

type TaintEffect string

const (
    TaintEffectNoSchedule TaintEffect = "NoSchedule"
    TaintEffectPreferNoSchedule TaintEffect = "PreferNoSchedule"
    TaintEffectNoExecute TaintEffect = "NoExecute"
)

type TolerationOperator string

const (
    TolerationOpExists TolerationOperator = "Exists"
    TolerationOpEqual  TolerationOperator = "Equal"
)

2、Taint

咱們能夠對 node 設置多個 taints,固然也能夠在 pod 配置相同個數的 tolerations。影響調度和運行的具體行爲,咱們能夠分爲如下幾類:github

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

3、Toleration

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

  • Exists: 這個配置下,不須要指定 value。
  • Equal: 須要配置 value 值。(operator 的默認值)

有幾個特殊狀況:網絡

  • 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 上的時間。
例如:ide

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

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

來個比較形象的圖,描述下:
taint & tolerationcode

該圖參考: Taints and tolerations, pod and node affinities demystified · Banzai Cloud

4、內置行爲

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

  • 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-readynode.kubernetes.io/unreachable,而且設置 tolerationSeconds = 300。固然這個默認配置,用戶能夠自行覆蓋。
這些自動添加的默認配置,確保 node 出現問題後,pod 能夠繼續在 node 上停留 5 分鐘。內存

DefaultTolerationSeconds admission controller 設置的 tolerationSeconds 值,也能夠由用戶指定。
具體參考: https://github.com/kubernetes...

還有一個默認行爲,就是 DaemonSet。
全部 DaemonSet 建立的 pod 都會添加兩個 toleration: node.alpha.kubernetes.io/unreachablenode.alpha.kubernetes.io/notReady。設置 effect = NoExecute,而且不指定 tolerationSeconds
目的是確保在 node 出現 unreachable 或 notReady 的問題時,DaemonSet Pods 永遠不會被驅逐。

示例

  • 專用節點

    • 若是你但願將一組節點專用於特定的用戶,那能夠將這些節點設置 taints: kubectl taint nodes nodename dedicated=groupName:NoSchedule, 而後爲 pods 設置對應的 tolerations。
    • 若是你但願節點被專用而且確保服務僅使用這批節點,那麼你還應該向這批節點設置 labels (dedicated=groupName),而且爲對應的 pods 設置 NodeAffinity,以控制 pods 只能跑到這批節點上。
  • 具備特殊硬件的節點

    • 有部分帶有特殊硬件的節點,好比 GPU、FPGA 等,要確保不將不須要專用硬件的 pods 調度到這些節點。也能夠和 專有節點 同樣的方式設置 taints:kubectl taint nodes nodename special=true:NoSchedulekubectl taint nodes nodename special=true:PreferNoSchedule。建議還能夠經過 Extended ResourcesExtendedResourceToleration admission controller 來更方便的調度依賴特殊硬件的 pods,而不須要手動添加容器的 toleration
  • 基於 taint 的驅逐

    • 前面也提到了,能夠經過 NoExecute taint 來驅逐節點上已經運行的 pods。

5、參考資料

相關文章
相關標籤/搜索