Kubernetes的汙點和容忍(下篇)

程式設計一生發表於2019-03-20

背景

繼上一篇《Kubernetes的汙點和容忍(上篇)》,這是https://kubernetes.io/docs/concepts/configuration/taint-and-toleration/ 譯文的下半部分。

經常看外文文件或書籍多了,會產生一個問題:“不方便溝通。”不太會用大家習慣的表述方式來闡述一個問題。所以需要定期看一些中文書籍來學習「行話」。

 

譯文

使用場景

汙點和容忍是一種讓Pod不被排程到指定node或者是把不該在某個node上執行的Pod踢掉的靈活方法。下面列舉一些使用場景。

  • 指定node:如果想為特殊的使用者指定一組node,可以新增一個汙點到這組node上(執行命令: kubectl taint nodes nodename dedicated=groupName:NoSchedule)。然後新增對應的容忍到這個Pod上(這個最容易實現的方法是寫一個客戶端准入控制器)。帶有相應容忍的Pod就可以像被排程到叢集中其他node一樣被排程到帶有相應汙點的node上。

  • 特殊硬體的node:在一個有一小組特殊硬體(例如GPU)的叢集中,更希望將沒有特殊硬體需求的Pod不排程到這些node上,留出空間給後來的需要這些特殊硬體的Pod。這個通過給特殊硬體打上汙點(例如:kubectl taint nodes nodename special=true:NoSchedule or kubectl taint nodes nodename special=true:PreferNoSchedule),然後新增相應的容忍到Pod上來實現。在這些使用場景,最容易實現的方法是使用客戶端准入控制器來實現。例如,推薦使用Extended Resources 來代表特殊硬體,將帶有擴充套件資源名的硬體打上汙點。然後執行ExtendedResourceToleration准入控制器. 現在,由於這些node已經被打上汙點了,沒有容忍的Pod不會被排程到上面。但是當你提交了一個需要擴充套件資源的Pod,ExtendedResourceToleration准入控制器會自動的新增正確的容忍到Pod上,Pod就可以被排程到這個特殊硬體的node上了。這會確保這些特殊硬體的node是需要相應的硬體的,並且不需要手動給Pod新增容忍。

  • 基於汙點的驅逐(beta版本特性):下面我們會介紹當node發生故障時基於單個Pod配置的驅逐行為。

基於驅逐的汙點

早期我們提到了NoExecute汙點的effect會影響已經在node上執行的Pod。

  • 不能容忍汙點的Pod會被立即驅逐。

  • Pod上的容忍沒有指定tolerationSeconds會好好的呆在node上。

  • Pod上的容忍帶有tolerationSeconds的會在node上停留指定的時間。

另外,Kubernets 1.6 引入了代表node問題的汙點(在1.6版本是alpha版試用)。換句話說,node控制器當某種條件成立的時候會自動的給node打上汙點。下面是其中內建的汙點:

  • node.kubernetes.io/not-ready:node不是ready狀態。對應於node的condition ready=false.

  • node.kubernetes.io/unreachable:node controller與node失聯了。對應於node的condition ready=unknown

  • node.kubernetes.io/out-of-disk:node磁碟空間不足了。

  • node.kubernetes.io/network-unavailable:node的網斷了

  • node.kubernets.io/unschedulable:node不是可排程狀態

  • node.cloudprovider.kubernetes.io/uninitalized:kubelet是由外部雲提供商提供的時候,剛開始的時候會打上這個汙點來標記還未被使用。當cloud-controller-manager控制器初始化完這個node,kubelet會自動移除這個汙點。

在1.13版本中,「基於汙點的驅逐」特性被提升至beta版,並且被預設開啟。因為這些汙點會被自動新增到node控制器(或kubelet)中。而之前的常使用的邏輯:基於condition中ready狀態來驅逐pod也被禁用了。

注意:

為了維持在node故障時對存在的Pod驅逐做限流,系統實際上是用限速的方法來新增汙點的。這種措施防止了master與node腦裂而產生的大規模驅逐Pod的場景。

這個beta版本特性再結合tolerationSeconds,可以使得pod指定當node節點出現問題的時候一個pod能在node上呆多久。

舉個例子:

一個有很多本地狀態的應用可能想在產生網路腦裂的時候還能在node上呆很久。這樣是希望腦裂會恢復,從而避免pod被驅逐。為了達到這個目的,可以這樣用:

 

Kubernetes會自動給pod新增容忍:node.kubernetes.io/not-ready 實效是tolerationSeconds=300。但是如果使用者自己給這個pod新增了node.kubernets.io/not-ready的容忍,使用者的配置不會被覆蓋。

類似的,它也會自動給pod新增容忍:node.kubernetes.io/unreachable 實效是tolerationSeconds=300。但是如果使用者自己給這個pod新增了node.kubernetes.io/unreahable,使用者的配置不會被覆蓋。

這種自動新增容忍機制確保了預設pod如果宿主機發生故障在5分鐘之內不會被自動驅逐。這兩個預設的容忍都是https://github.com/kubernetes/kubernetes/tree/master/plugin/pkg/admission/defaulttolerationseconds (DefaultTolerationSeconds admission controller)這個控制元件來新增的。

DaemonSet的pod會預設新增一個NoExecute不帶有tolerationSeconds的容忍:

  • node.kubernetes.io/unreachable

  • node.kubernetes.io/not-ready

這種方式確保了DaemonSet的Pod在發生故障的時候永遠不會被驅逐。

condition驅動的汙點

在版本1.12中,「condition驅動的汙點」特性被提升到beta版,node的生命週期控制器自動的建立condition相應的汙點。類似的,排程器並不檢查node的condition,而是檢查汙點。這種方式是用來保證node的condition不會影響已經排程到這臺node的Pod。使用者可以用新增合適的容忍來忽視node的一些問題(condition是其中的代表)。在這個版本中「condition驅動的汙點」只是打上了effect=NoSchedule的汙點。而在1.13版本中才將effect=NoExcute作為beta版預設開啟。

從Kubernetes1.8版本開始,DaemonSet控制器自動的新增了NoSchedule容忍到所有的daemon執行緒來避免DaemonSets中斷。

  • node.kubernetes.io/memory-pressure

  • node.kubernetes.io/disk-pressure

  • node.kubernetes.io/out-of-disk(只對重要的pod生效)

  • node.kubernetes.io/unschedulable(1.10版本後生效)

  • node.kubernetes.io/network-unavailable(只針對主機網路)

新增這些容忍確保了向後相容,使用者可以隨意對DaemonSets新增容忍。

相關閱讀

《兩地書》--K8s基礎知識

Kubernetes的汙點和容忍(上篇)

Kubernetes的汙點和容忍(下篇)

作者是一個有美國矽谷、日本東京工作經驗,十二年堅持一線寫程式碼的程式媛。堅持原創文章。歡迎技術交流!

相關文章