Kubernetes 如何高效管理節點的資源

2020-06-18     segmentfault官方

原標題:Kubernetes 如何高效管理節點的資源

本文轉載於SegmentFault社區

作者:iyacontrol

kubelet是Kubernetes中的主要節點組件,它執行許多關鍵任務。Kubelet主要職責在:

  • 向kube-apiserver註冊節點

  • watch kube-apiserver中已經調度完成的Pod,並在Pod被調度完成之後告訴容器運行時(例如Docker)啟動容器

  • 監視運行中的容器並將其狀態報告給kube-apiserver

  • 執行活動性探針並在容器失敗後重新啟動容器

  • 運行由kubelet直接管理的靜態Pod

  • 與Core Metrics Pipeline和容器運行時進行交互以收集容器和節點metrcis

我們在本文中要討論的另一個重要的kubelet任務是,當節點資源耗盡時,「agent」具有將Pods逐出的功能。當計算資源(例如磁碟,RAM或CPU)不足時,kubelet在維護節點穩定性方面起著至關重要的作用。對於Kubernetes管理員來說,了解配置資源超過配額的最佳做法很有用,以使節點資源更靈活,同時保留系統的整體容錯性和關鍵系統進程的穩定性。

Kubelet如何確定資源不足?

如前所述,kubelet可以從節點上驅逐工作負載,以釋放資源來處理其他Pod和/或系統任務,例如容器運行時或kubelet本身。但是,kubelet如何確定資源不足?

Kubelet根據收回信號和收回閾值確定何時回收資源。驅逐信號是系統資源(如內存或存儲器)的當前容量。反過來,驅逐閾值是kubelet應該維護的此資源的最小值。

換句話說,每個驅逐信號都與某個驅逐閾值相關聯,該閾值告訴kubelet何時開始回收資源。目前,支持以下驅逐信號:

  • memory.available — 描述集群內存狀態的信號。內存的默認逐出閾值為100Mi。換句話說,當內存下降到100 Mi時,kubelet開始驅逐Pod。

  • nodefs.available — nodefs是kubelet用於卷,守護程序日誌等的文件系統。默認情況下,如果nodefs.available <10%,則kubelet開始回收節點資源。

  • nodefs.inodesFree — 描述nodefs索引節點內存狀態的信號。默認情況下,如果nodefs.inodesFree <5%,則kubelet將開始驅逐工作負載。

  • imagefs.available — imagefs文件系統是容器運行時使用的可選文件系統,用於存儲容器鏡像和容器可寫層。默認情況下,如果imagefs.available <15%,則kubelet開始驅逐工作負載。

  • imagefs.inodesFree — imagefs索引節點內存的狀態。它沒有默認驅逐閾值。

上述驅逐閾值是非常合理的默認值。但是,用戶可以通過在kubelet二進位文件上設置適當的標誌來配置其自定義逐出閾值。這些用戶定義的閾值可以更改默認的kubelet驅逐行為。

目前,Kubernetes支持硬驅和軟碟機逐閾值。

如果達到硬驅逐閾值,則kubelet將立即開始回收資源,而沒有任何寬限期。相反,軟碟機逐閾值包括用戶定義的寬限期,該寬限期應在kubelet開始回收任何資源之前到期。

您可以使用kubelet二進位文件上的--eviction-hard標誌定義硬驅逐閾值。例如,kubelet-eviction-hard = memory.available <1Gi將告訴kubelet在節點的memory.available低於1Gi時開始回收資源。

如果要在驅逐之前允許寬限期,則可以將-eviction-soft標誌與--eviction-soft-grace-period標誌結合使用。例如,kubelet —- eviction-soft=memory.available<2Gi和kubelet —- eviction-soft-grace-period=1m30s將使驅逐閾值保持90秒,然後觸發驅逐閾值。

用戶還可以通過以秒為單位設置--eviction-max-pod-grace-period來指定允許的最大寬限期。

Kubelet如何回收資源?

Kubelet以用戶Pod的利益為代價來回收資源。它首先嘗試回收未使用的容器鏡像或 dead 的Pod。

如果節點具有專用的imagefs文件系統以及nodefs文件系統,則kubelet會以不同的方式回收節點資源。在這種情況下,如果nodefs達到驅逐閾值,則kubelet會刪除所有已失效的Pod及其容器。相應地,如果imagefs達到驅逐閾值,則kubelet會刪除所有未使用的容器鏡像。

如果沒有使用imagefs,則kubelet首先刪除所有無效的Pod及其容器,然後刪除所有未使用的鏡像。有關此過程的更多信息,請參見Kubernetes文檔

如果回收容器鏡像,失效的Pod和其他資源沒有導致資源匱乏,則kubelet將刪除用戶Pod作為最後的選擇。kubelet根據Pod的QoS等級,Pod優先級和下面討論的許多其他參數,決定退出哪個用戶Pod。在描述此過程之前,讓我們回顧一下Kubernetes中的基本QoS類。

Pod的Qos共分為Guaranteed,Burstable或Best-Effort。

  • Guaranteed : 在Pod的所有容器中都為CPU和RAM設置資源限制和請求,並且它們的值相等。

  • Burstable Pod中一個或多個容器的資源(例如,CPU,RAM)設置了請求和限制的容器,它們不相等。

  • Best-Effort Pod中的容器未設置資源限制。

此QoS模型由kubelet在其Pod排序方案中隱式使用。通常,kubelet使用以下規則對驅逐候選人進行排名:

  • Pod是否超出其資源請求。在Kubernetes中,Pod是根據其請求而不是限制進行調度的。因此,保證所有容器和Pod都具有它們所請求的RAM / CPU數量。但是,如果沒有設置限制,並且Pod超出了其資源請求,則在保證Pod或某些系統任務需要受限資源的情況下,可以終止或限制該Pod。在某些情況下,甚至那些消耗少於要求量的Pod也會被殺死。例如,當系統任務內存嚴重不足並且沒有較低優先級的Pod被殺死時。

  • 按Pod優先級排列。如果沒有Pod超出其請求,則kubelet會檢查Pod Priority。它將嘗試先驅逐優先級較低的Pod。注意:在Kubernetes 1.14中,Pod的優先級和搶占式遷移到了GA。從1.11開始默認啟用它們。您可以在本文中了解有關Pod Priority的更多信息。

根據這些規則,kubelet會按以下順序驅逐用戶Pod:

  • 驅逐的第一個候選對象是Best-Effort 和/或 Burstable的Pod,其受限資源的使用超出了請求。如果有多個此類Pod,則kubelet會按優先級對它們進行排序,然後將資源消耗按指定的請求進行排序。

  • 最後驅逐了資源使用量低於請求的Guaranteed 和 Burstable Pods的Pod。但是,如果某些系統任務(如kubelet或Docker)需要更大的資源,並且節點上沒有Best-EffortPod,則kubelet可以驅逐消耗量低於其請求量的Guaranteed Pod。在這種情況下,它將首先以最低優先級驅逐Guaranteed 和 Burstable Pods。

最低驅逐收回

如果kubelet回收的資源量很小,則系統可以反覆達到驅逐閾值。這不是理想的行為,因為它可能導致不良的調度決策和Pods頻繁驅逐。為了避免這種情況,用戶可以使用kubelet二進位文件上的-eviction-minimum-reclaim標誌設置每個資源的最小回收級別。

例如,查看下面的kubelet配置:

--eviction-hard=memory.available< 1Gi,nodefs.available< 2Gi,imagefs.available< 200Gi --eviction-minimum-reclaim=memory.available= 0Mi,nodefs.available= 1Gi,imagefs.available= 2Gi

—- eviction-minimum-reclaim設置可確保回收後可用的nodefs最小存儲量為3Gi,可用的imagefs最小存儲量為202 Gi。因此,以上配置可確保系統具有足夠的可用資源,以避免非常頻繁地達到收回閾值。

資源匱乏的處理配置不當可能遇到的另一個潛在問題是節點條件的波動。當kubelet收到逐出信號時,後者會映射到相應的節點條件。例如,當達到memory.available逐出閾值時,kubelet將MemoryPressure節點條件分配給該節點。此條件與相應的污點關聯,該污點可防止在具有MemoryPressure節點條件的節點上調度新Pod。

但是,如果您使用具有較長寬限期的軟碟機逐閾值,則節點條件可能會在寬限期內在true和false之間振蕩。這可能會導致驅逐不確定性,並因此導致不良的調度決策。為避免這種情況,您可以在kubelet上使用-- eviction-pressure-transition-period標誌,該標誌定義kubelet在滿足驅逐條件之前必須等待多長時間。

一個簡單的資源短缺處理方案

現在,我們將說明如何為K8s集群配置資源不足的處理。讓我們想像一個簡單的場景,其中僅考慮節點RAM。假設我們節點的內存容量為10 Gi RAM。我們希望為內核,kubelet,Docker等系統守護進程保留總內存的10%。我們還希望驅逐Pods,使其占用95%的內存。

使用默認逐出閾值啟動kubelet,並且沒有系統保留。我們需要在kubelet上顯式設置幾個標誌,以啟用所需的行為。

為了實現我們的目標,我們需要在kubelet上設置以下標誌:

eviction-hard=memory.available< 500Mi system-reserved=memory= 1.5Gi

如您所見,系統保留設置為1.5Gi,儘管直觀上應將其設置為10%= 1Gi。但是,「系統保留」應包括驅逐閾值(1Gi + .5Gi)覆蓋的內存量。

根據配置K8s集群的方式,可以不同地設置kubelet標誌。例如,如果計劃使用Kops配置K8s集群,請運行kops edit cluster $NAME以使用集群配置打開編輯器。如果是VI編輯器,則按「 I」進入插入模式以編輯文件。上述資源不足處理策略的kubelet標誌應如下所示:

kubelet:eviction-hard=memory.available < 500Misystem-reserved= memory= 1.5Gi

結論

在本文中,我們討論了一些有用的Kubernetes管理實踐,用於在Kubernetes中自定義kubelet超出資源的管理。該平台允許管理員設置自定義逐出閾值和逐出寬限期,以決定哪些條件被視為對節點穩定性有害。但是,有了這種自由,就要承擔很多責任。Kubernetes附帶了合理的資源短缺管理默認設置。因此,在將驅逐閾值設置得太高或將驅逐寬限期設置得太長時,您應保持謹慎。

文章來源: https://twgreatdaily.com/zh-my/vVs4xnIBiuFnsJQV9ArK.html

Flutter 知識點

2020-08-10