kubernetes調度之污點(taint)和容忍(toleration)

系列目錄html

節點親和性(affinity),是節點的一種屬性,讓符合條件的pod親附於它(傾向於或者硬性要求).污點是一種相反的行爲,它會使pod抗拒此節點(即pod調度的時候不被調度到此節點)node

污點和容易結合在一塊兒以確保pod不會被調度到不適合的節點上.當一個或者多個污點添加到某個節點上,則意味着此節點不會接受任何不容忍這些污點的pod.Tolerations做用於pod上,容許(但不是必須)pod被調度到有符合的污點(taint)的節點上網絡

概念

可使用kubectl taint爲一個節點(node)添加污點(taint),例如:ide

kubectl taint nodes node1 key=value:NoSchedule

這樣就把鍵爲key,值爲value,效果爲NoSchedule的污點添加到了節點node1上.這樣除非pod有符合的容忍(toleration),不然不會被調度到此節點上測試

能夠經過如下命令刪除剛添加的taintcode

kubectl taint nodes node1 key:NoSchedule-

你能夠在建立pod的yml裏指定一個關於toleration的PodSpec,如下兩個容忍都會匹配前面建立的taint,所以它們中的任意一個建立的pod都會被調度到節點node1htm

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

只有pod的keyeffect都和某一個污點的key與effect匹配,才被認爲是匹配,而且要符合如下情形:blog

  • operatorExists(這種狀況下value不該當指定)
  • operatorEqual 而且value相同

若是operator沒有指定,則默認是Equal生命週期

如下兩種狀況爲特殊狀況:內存

1) 若是key是空(是指key沒有指定,而不是指key爲空字符串),operatorExists則匹配全部的key,valueeffect,也即匹配任何node,

tolerations:
- operator: "Exists"

2) 空的effect匹配全部effect

tolerations:
- key: "key"
  operator: "Exists"

以上會匹配全部key爲key的全部taint節點

前面的示例中使用了NoSchedule類型的effect.此外,也可使用PreferNoSchedule類型的effect,這是一個優先選擇或者軟性版本的NoSchedule,調度系統會盡可能避免調度不容忍這種污點的pod到帶有此污點的節點上,可是並非硬性要求.第三種effect類型:NoExecute會在晚些時候講到

你能夠爲一個節點(node)添加多個污點,也能夠爲一個pod添加多個容忍(toleration).kubernetes處理多個污點(taint)或者多個容忍(toleration)相似於過濾器:起初包含全部污點,而後忽略掉pod匹配的污點,剩下不可被忽略的污點決定此節點對pod的效果,特別地:

1) 若是至少有一個不可忽略的NoSchedule類型的效果(effect),kubernetes不會調度pod到此節點上來.

2) 若是沒有不可忽略的NoSchedule類型的效果(effect),可是至少有一個PreferNoSchedule類型的效果,則kubernetes會嘗試調度pod到此節點上

3) 若是至少有一個NoExecute類型的效果(effect),則此pod會被驅離此節點(固然,前提此pod在此節點上),而且若是pod不在此節點上,也不會被調度到此節點上

所謂驅離是指pod被今後節點上移除,調度到其它節點上

示例,假如你有一個如下類型的節點

kubectl taint nodes node1 key1=value1:NoSchedule
kubectl taint nodes node1 key1=value1:NoExecute
kubectl taint nodes node1 key2=value2:NoSchedule

和如下類型的pod

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

這種狀況下,pod不會被調度到node1上,由於沒有容忍(toleration)來匹配第三個taint.可是若是它運行在此節點上,它仍然能夠繼續運行在此節點上,由於它僅僅不匹配第三個taint.(而第三個taint的效果是NoSchedule,指示不要被調度到此節點)

一般狀況下,一個效果類型爲NoExecutetaint被添加到一個節點上後,全部不容忍此taint的pod會被立刻驅離,容忍的永遠不會被驅離.可是效果類型NoExecute能夠指定一個tolerationSeconds字段來指示當NoExecute效果類型的污點被添加到節點之後,pod仍然能夠繼續在在指定時間內留存在此節點上.

例如:

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

它意味着若是pod運行在一個能夠容忍的節點上,則它能夠繼續運行3600秒,而後被驅離,在此段時間內若是污點被移除,則pod不會被驅離.

以上能夠理解爲有條件容忍,即使匹配也不能一直運行在此節點上,只能在符合條件的時段內運行在此節點上.

實例:

tainttoleration能夠很是靈活地把指示pod不要調度到不合適的節點或者把已經存在的pod驅離節點,如下列舉出一些用例:

  • 專用節點 假如你想讓某些節點供特定的用戶專用,你能夠爲這些節點添加污點,例如:(kubectl taint nodes nodename dedicated=groupName:NoSchedule),而後給專用這些節點的pod添加容忍(toleration),容忍節點污點的pod被容許調度到節點上,固然也能夠調度到集羣中的其它節點上(沒有taint的節點,有taint的必須容忍).若是你想要pod僅被調度到專用的節點,則須要添加標籤(使用前面講到過的親和屬性)

pod的親和性是以pod爲中心的,而節點的污點則是以節點爲中心.想要使pod被調度到指定節點,須要親和屬性,想要節點排斥非專用pod,則須要使用taint,同時使用親和性和污點能夠保證專用節點被特定pod專用,特定pod僅使用專用節點

  • 配有特殊硬件的節點 在一個集羣中,有部分節點包含特殊硬件(例如特殊GPU),理想的狀況是把讓不須要特殊硬件的pod不被調度到這些節點上以便爲可能須要特殊硬件的節點留存空間,這種狀況下就能夠用給指定節點添加污點(taint)的方法來實現效果.(例如kubectl taint nodes nodename special=true:NoSchedule or kubectl taint nodes nodename special=true:PreferNoSchedule),而後給須要使用特殊硬件的pod添加符合的容忍(toleration).

  • 基於taint的驅離策略(測試功能),當節點出現問題時,把不容忍的pod驅離.

基於taint的驅離策略

前面咱們提到過NoExecute效果類型的taint,它將對已經存在於此節點上的pod產生效果:

  • 不容忍此taint的pod會被立刻驅離

  • 容忍此taint可是沒有指定tolerationSeconds的pod將會永遠運行在此節點

  • 容忍此taint可是包含tolerationSeconds屬性的節點將會在此節點上留存指定時間(雖然容忍,可是是有條件的,僅在一段時間內容忍)

第三點的言外之意即爲即使容忍,可是超過容忍時間後仍然會被驅離

此外,kubernetes 1.6引入了對節點問題的展現.也就是說當知足了特定條件,節點控制器會自動爲符合條件的節點添加taint,如下是一些內置的taint

  • node.kubernetes.io/not-ready,節點尚未準備好,對應節點狀態Ready值爲false

  • node.kubernetes.io/unreachable,節點控制器沒法觸及節點,對應節點狀態ready值爲Unknown

  • node.kubernetes.io/out-of-disk,磁盤空間不足

  • node.kubernetes.io/memory-pressure,節點存在內存壓力

  • node.kubernetes.io/disk-pressure,節點磁盤存在壓力

  • node.kubernetes.io/network-unavailable,節點網絡不可用

  • node.kubernetes.io/unschedulable,節點不可被調度

  • node.cloudprovider.kubernetes.io/uninitialized

在kubernetes 1.13版本,基於污點的驅離策略提高到beta級別而且默認開啓,所以污點被node控制器(kubelete)自動添加,而且普通的以節點的Ready狀態爲基礎的驅離策略被禁用.

這項beta功能,加上tolerationSeconds,容許節點來指定仍然能夠留存長時間即使節目有一種或者多種匹配的問題

例如:一個包含多種本地狀態的應用在節點發生網絡分裂狀況時但願仍然能夠留存一點時間,指望在指定的時段內網絡能恢復正常以免被驅離.這種狀況下容忍此節點的pod編排以下

tolerations:
- key: "node.kubernetes.io/unreachable"
  operator: "Exists"
  effect: "NoExecute"
  tolerationSeconds: 6000

請注意,若是用戶沒有在pod的配置中指定node.kubernetes.io/not-ready,則kubernetes會自動爲pod配置加上node.kubernetes.io/not-ready tolerationSeconds=300屬性.一樣地,若是沒有配置,則自動添加node.kubernetes.io/unreachable tolerationSeconds=300

DaemonSet類型的pod建立時自動爲如下兩種類型的taint添加NoExecute效果類型而且沒有tolerationSeconds

  • node.kubernetes.io/unreachable

  • node.kubernetes.io/not-ready

這確保即使節點出現問題,DaemonSet也不會被驅離.

有條件節點taint

在kubernetes 1.12版,有條件爲節點添加taint(TaintNodesByCondition)特徵被提高爲beta級別,節點生命週期控制器會自動根據節點的狀態爲節點添加taint.一樣地調度器不檢測node的狀態,而是檢測node 的污點(taint).這確保node的狀態不影響哪些pod能夠調度到此node上,用戶能夠選擇經過添加相應的容忍(toleration)來忽略node的指定的問題(經過node的狀態體現).注意TaintNodesByCondition僅添加NoSchedule類型的污點.NoExecute效果類型由TaintBasedEviction控制(此功能爲1.13版本的beta功能)

從kubernetes 1.8開始,DaemonSet controller自動如下類型的爲全部的daemon添加NoSchedule效果類型的容忍(toleration),來防止DeamonSet分裂

  • node.kubernetes.io/memory-pressure

  • node.kubernetes.io/disk-pressure

  • node.kubernetes.io/out-of-disk (only for critical pods)

  • node.kubernetes.io/unschedulable (1.10 or later)

  • node.kubernetes.io/network-unavailable (host network only)

添加了這些類型的容忍是爲了向後兼容,你能夠爲DaemonSet添加任意類型的容忍

相關文章
相關標籤/搜索