Kubernetes的污點和容忍(下篇)


背景

繼上一篇《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的污點和容忍(下篇)

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


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM