Kubernetes容器資源要求-第1部分:內存

瞭解請求,限制

Kubernetes容器資源要求-第1部分:內存

為了讓Kubernetes(K8)可靠地分配您的組件運行所需的資源並充分利用其所在的基礎架構,您應該指定容器資源要求。 當前,您可以為兩種類型的容器資源(內存和CPU)指定兩種類型的需求,請求和限制。 本文旨在解釋這兩種需求的含義以及Docker容器運行時內存的含義。

內存的意義

內存在這裡到底是什麼意思? 簡而言之,它是容器的總駐留集大小(RSS)和頁面緩存使用情況。 在純Docker中,該數字通常包含交換,但是K8會永久代表您禁用交換。

RSS是進程在任何給定時間使用的RAM數量。 對於Java進程,這可以包括多個區域,包括本機堆/非堆區域,線程堆棧和本機內存分配。 RSS受JVM線程配置,線程數和組件行為的影響。

頁緩存是用於從磁盤緩存塊的RAM區域。 出於性能原因,所有I / O通常都通過此緩存執行。 每當您的組件從文件中讀取或寫入文件時,都可以期望將相關的塊緩存在此處。 您讀取或寫入的文件越多,要求就越高。 請注意,內核會將可用的備用內存用於頁面緩存,但是如果其他地方需要,它將回收它-這意味著如果沒有足夠的空間,組件的性能可能會受到影響(取決於其對頁面緩存的性能依賴)。 這裡有一個潛在的難題-Docker的overlayfs存儲驅動程序啟用頁面緩存共享,這意味著訪問同一文件的同一節點上的多個容器共享該文件的相同頁面緩存條目(例如索引或其他共享的內容)。 Docker文檔指出:

計算頁面緩存中的內存非常複雜。 如果不同控制組中的兩個進程都讀取同一文件(最終依賴於磁盤上的相同塊),則將在控制組之間分配相應的內存費用。 很好,但這也意味著當一個cgroup終止時,它可能會增加另一個cgroup的內存使用量,因為它們不再為這些內存頁面分配費用了。

…因此請注意,每個容器的頁面緩存使用情況可能會有所不同,具體取決於與同一節點上運行的其他容器共享哪些文件。

內存請求和限制以字節為單位,但是您可以指定多個後綴。 JVM內存配置使用二進制前綴來表示(例如Xmx1g為1024³字節),因此使用等效的K8s後綴(Gi)作為容器規範的基礎是有意義的。

請求與限制

定義Pod時,可以為其容器指定兩個類別的內存和CPU要求-請求和限制:

<code>

resources

:

requests

:

memory

:

"8Gi"

cpu

:

"4"

limits

:

memory

:

"8Gi"

cpu

:

"4"

/<code>

請求是K8s的概念,用於在底層基礎架構中調度容器:"將容器的容器放置在有足夠資源容納它們的地方"。 限制是可用於容器的資源的硬性上限,這些資源會傳播到基礎容器運行時,我們在這裡假設Docker。 超出限制會導致節流,或者在最壞的情況下會導致容器終止。

您可能會問是否有理由將限制設置為高於要求。 如果您的組件具有穩定的內存佔用空間,則可能不應該這樣做,因為當容器超出其請求時,如果工作節點遇到內存不足的情況,則很可能將其驅逐。 對於CPU,如果請求和限制之間沒有其他容器正在使用的資源,則可以適當地清除請求和限制之間的其他資源。 Burstable QoS類(請參閱下文)允許潛在地更有效地利用基礎資源,但具有更大的不可預測性-例如,與CPU綁定的組件的延遲可能會受到同一工作節點上其他容器的瞬時共置的影響。 如果您不熟悉K8,最好通過設置與請求相同的限制來從"保證的QoS"類入手。

如果省略了對容器的請求,則默認為限制。 如果未設置限制,則默認為0(無界)。

根據請求的存在/配置和限制(從此處開始)採用QoS類:

如果為所有容器中的所有資源設置了限制和可選的請求(不等於0)並且它們相等,則將容器分類為保證。 這些容器被認為是優先級最高的容器,並保證在它們超過其限制之前或者系統處於內存壓力下並且沒有可以撤出的優先級較低的容器時才被殺死。

如果為一個或多個容器中的一個或多個資源設置了請求和可選的限制(不等於0),但請求和限制不相等,則將pod劃分為Burstable。 如果未指定限制,則默認為節點容量。 這些Pod具有某種形式的最小資源保證,但是在可用時可以使用更多資源。 在系統內存壓力下,一旦這些容器超出了它們的請求,並且不存在盡力而為的容器,它們很可能被殺死。

如果未針對所有容器的所有資源設置請求和限制,則該容器被分類為"盡力而為"。 這些Pod將被視為最低優先級。 如果系統內存不足,這些Pod中的進程將首先被殺死。 這些容器可以在節點中使用任何數量的可用內存。

內存限制?

內存限制在K8s看來被認為是不可壓縮的,這意味著它不能被限制。 如果您的容器遇到內存壓力,內核將積極刪除頁面緩存條目以滿足需求,並且最終可能會被Linux內存不足(OOM)殺手殺死。 由於K8s禁用了交換功能(通過將memory-swappiness = 0傳遞給Docker),因此對於錯誤配置而言,這是一個非常寬容的環境。

您應憑經驗確定組件的內存要求,以創建良好的配置; 如果您的組件依賴於良好的頁面緩存效率,請通過容器的資源要求留出適當的開銷。 當然,情況會發生變化,您的組件內存需求將始終如一地-將內存統計信息進行監視和警報作為正常操作功能的一部分。


(本文翻譯自Will Tomlin的文章《Kubernetes Container Resource Requirements — Part 1: Memory》,參考:
https://medium.com/expedia-group-tech/kubernetes-container-resource-requirements-part-1-memory-a9fbe02c8a5f)


分享到:


相關文章: