如何訪問 Kubernetes Pod 資源

如何訪問 Kubernetes Pod 資源托哈德的獎勵

開始使用 Kubernetes 時,通常會忘記設定容器資源。 至此,足以保證Docker映像能夠運作並且可以部署到Kubernetes叢集。

但後來該應用程式需要與其他應用程式一起部署在生產叢集中。 為此,您需要為容器分配資源,並確保有足夠的資源來啟動和運行應用程序,並且其他正在運行的應用程式不會遇到問題。

團隊 Mail.ru 的 Kubernetes aaS 翻譯了一篇關於容器資源(CPU & MEM)、請求和資源限制的文章。 您將了解這些設定的好處以及如果不設定它們會發生什麼。

計算資源

我們有兩種類型的資源,具有以下單位:

  • 中央處理器 (CPU) - 核心;
  • 記憶體 (MEM) - 位元組。

為每個容器指定資源。 在以下 Pod YAML 檔案中,您將看到一個資源部分,其中包含請求的資源和限制的資源:

  • 請求的 Pod 資源 = 所有容器請求的資源總和;
  • Pod 資源限制 = 所有 Pod 資源限制的總和。

apiVersion: v1
kind: Pod
metadata:
  name: backend-pod-name
  labels:
    application: backend
spec:
  containers:
    — name: main-container
      image: my-backend
      tag: v1
      ports:
      — containerPort: 8080
      resources:
        requests:
          cpu: 0.2 # REQUESTED CPU: 200m cores
          memory: "1Gi" # REQUESTED MEM: 1Gi
        limits:
          cpu: 1 # MAX CPU USAGE: 1 core
          memory: "1Gi" # MAX MEM USAGE:  1Gi
    — name: other-container
      image: other-app
      tag: v1
      ports:
      — containerPort: 8000
      resources:
        requests:
          cpu: "200m" # REQUESTED CPU: 200m cores
          memory: "0.5Gi" # REQUESTED MEM: 0.5Gi
        limits:
          cpu: 1 # MAX CPU USAGE: 1 core
          memory: "1Gi" # MAX MEM USAGE:  1Gi

請求的資源和有限的資源範例

領域 resources.requested 根據規範,Pod 是用來尋找所需節點的元素之一。 您已經可以為其規劃 Pod 部署。 如何找到合適的節點?

Kubernetes 由多個元件組成,包括主節點或主節點(Kubernetes Control Plane)。 主節點有幾個行程:kube-apiserver、kube-controller-manager 和 kube-scheduler。

kube-scheduler 程序負責檢查新建立的 Pod 並尋找與所有 Pod 請求相符的可能工作節點,包括要求的資源數量。 kube-scheduler 找到的節點清單已排序。 Pod 被調度到分數最高的節點。

如何訪問 Kubernetes Pod 資源紫色 Pod 將放置在哪裡?

在圖中您可以看到 kube-scheduler 應該會調度一個新的紫色 Pod。 Kubernetes 叢集包含兩個節點:A 和 B。如您所見,kube-scheduler 無法在節點 A 上調度 Pod - 可用(未要求)資源與紫色 Pod 的請求不符。 因此,紫色 Pod 請求的 1 GB 內存在節點 A 上不適合,因為可用記憶體為 0,5 GB。 但節點B有足夠的資源。 因此,kube-scheduler 判定紫色 Pod 的目的地是節點 B。

現在我們知道請求的資源如何影響運行 Pod 的節點的選擇。 但邊際資源的影響是什麼?

資源限制是CPU/MEM無法跨越的邊界。 但是,CPU 資源是靈活的,因此達到 CPU 限制的容器不會導致 Pod 退出。 相反,CPU 限制將開始。 如果達到 MEM 使用限制,容器將因 OOM-Killer 而停止,並在 RestartPolicy 設定允許的情況下重新啟動。

請求的資源和最大資源的詳細信息

如何訪問 Kubernetes Pod 資源Docker與Kubernetes之間的資源通信

解釋資源請求和資源限制如何運作的最佳方法是介紹 Kubernetes 和 Docker 之間的關係。 在上圖中,您可以看到 Kubernetes 欄位和 Docker 啟動標誌是如何關聯的。

記憶:要求和限制

containers:
...
 resources:
   requests:
     memory: "0.5Gi"
   limits:
     memory: "1Gi"

如上所述,記憶體以位元組為單位。 基於 Kubernetes 文檔,我們可以將記憶體指定為一個數字。 通常它是一個整數,例如2678——即2678位元組。 您也可以使用後綴 G и Gi,最重要的是要記住它們並不等同。 第一個是十進制,第二個是二進制。 就像k8s文件中提到的例子: 128974848, 129e6, 129M, 123Mi - 它們實際上是等效的。

庫伯內特選項 limits.memory 與旗幟相匹配 --memory 來自 Docker。 的情況下 request.memory Docker 沒有箭頭,因為 Docker 不使用該欄位。 你可能會問,這還有必要嗎? 是的,需要。 正如我之前所說,這個領域對 Kubernetes 來說很重要。 根據其中的信息,kube-scheduler 決定在哪個節點上調度 Pod。

如果為請求設定的記憶體不足會發生什麼情況?

如果容器已達到請求記憶體的限制,則 Pod 會被放置在一組 Pod 中,當節點中記憶體不足時,這些 Pod 會停止。

如果您將記憶體限制設定得太低會發生什麼情況?

如果容器超過記憶體限制,它將因 OOM-Killed 而終止。 如果可能的話,將根據 RestartPolicy 重新啟動,預設值為 Always.

如果不指定請求的記憶體會發生什麼?

Kubernetes 將採用該限制值並將其設為預設值。

如果不指定記憶體限制會發生什麼?

容器沒有任何限制;它可以使用任意多的記憶體。 如果他開始使用節點的所有可用內存,那麼 OOM 將殺死他。 如果可能的話,容器將根據 RestartPolicy 重新啟動。

如果不指定記憶體限制會發生什麼?

這是最糟的情況:調度程式不知道容器需要多少資源,這可能會導致節點出現嚴重問題。 在這種情況下,最好對命名空間設定預設限制(由 LimitRange 設定)。 沒有預設限制 - Pod 沒有限制,它可以使用任意多的記憶體。

如果請求的內存超過節點可以提供的內存,Pod 將不會被調度。 重要的是要記住這一點 Requests.memory - 不是最小值。 這是對足以保持容器持續運行的內存量的描述。

通常建議設定相同的值 request.memory и limit.memory。 這可以確保 Kubernetes 不會將 Pod 調度到有足夠記憶體運行 Pod 但不足以運行它的節點上。 請記住:Kubernetes Pod 規劃僅考慮 requests.memorylimits.memory 不考慮。

CPU:請求和限制

containers:
...
 resources:
   requests:
     cpu: 1
   limits:
     cpu: "1200m"

對CPU來說,一切都有點複雜。 回到 Kubernetes 和 Docker 的關係圖,可以看到 request.cpu 對應於 --cpu-shares,而 limit.cpu 與旗幟相匹配 cpus 在 Docker 中。

Kubernetes 請求的 CPU 乘以 1024,即 CPU 週期的比例。 如果您想請求 1 個完整核心,則必須新增 cpu: 1如上圖所示。

請求完整的核心(比例 = 1024)並不意味著您的容器會收到它。 如果您的主機只有一個核心,並且您正在執行多個容器,那麼所有容器必須在它們之間共用可用的 CPU。 這是怎麼發生的? 讓我們看一下圖片。

如何訪問 Kubernetes Pod 資源
CPU 請求 - 單核心系統

讓我們假設您有一個運行容器的單核心主機系統。 媽媽(Kubernetes)烤了一個餡餅(CPU)並想把它分給孩子(容器)。 三個孩子想要整個派(比例 = 1024),另一個孩子想要半個派(512)。 媽媽為了公平起見,做了一個簡單的計算。

# Сколько пирогов хотят дети?
# 3 ребенка хотят по целому пирогу и еще один хочет половину пирога
cakesNumberKidsWant = (3 * 1) + (1 * 0.5) = 3.5
# Выражение получается так:
3 (ребенка/контейнера) * 1 (целый пирог/полное ядро) + 1 (ребенок/контейнер) * 0.5 (половина пирога/половина ядра)
# Сколько пирогов испечено?
availableCakesNumber = 1
# Сколько пирога (максимально) дети реально могут получить?
newMaxRequest = 1 / 3.5 =~ 28%

據計算,三個孩子將獲得核心的28%,而不是全部核心。 第四個孩子將獲得完整核心的 14%,而不是一半。 但如果你有一個多核心系統,情況就會有所不同。

如何訪問 Kubernetes Pod 資源
CPU 請求 - 多核心 (4) 系統

在上圖中,您可以看到三個孩子想要一整個餡餅,一個想要半個。 由於媽媽烤了四個餡餅,所以她的每個孩子都想吃多少就吃多少。 在多核心系統中,處理器資源分佈在所有可用的處理器核心上。 如果一個容器被限制為少於一個完整的 CPU 核心,它仍然可以 100% 使用它。

簡化上述計算可以理解 CPU 如何在容器之間分配。 當然,除了容器本身之外,還有其他行程也會使用CPU資源。 當一個容器中的程序空閒時,其他容器可以使用其資源。 CPU: "200m" 對應於 CPU: 0,2,這意味著一個核心的大約 20%。

現在讓我們談談 limit.cpu。 Kubernetes 限制的 CPU 乘以 100。結果是容器每 100 µs 可以使用的時間量(cpu-period).

limit.cpu 匹配 Docker 標誌 --cpus。 這是舊的新組合 --cpu-period и --cpu-quota。 透過設定它,我們指示在限制開始之前容器可以最大使用多少可用CPU資源:

  • CPU的 - 組合 cpu-period и cpu-quota. cpus = 1.5 相當於設定 cpu-period = 100000 и cpu-quota = 150000;
  • CPU週期 - 時期 CPU CFS調度器,預設100微秒;
  • CPU配額 - 內在的微秒數 cpu-period,它以容器為界。

如果安裝的 CPU 不足,會發生什麼事?

如果容器所需的數量超過其已安裝的數量,它將從其他進程中竊取 CPU。

如果您將 CPU 限制設定得太低會發生什麼情況?

由於CPU資源是可調的,因此會開啟節流。

如果不指定 CPU 請求會發生什麼?

與記憶體一樣,請求值等於限制。

如果不指定 CPU 限制會發生什麼?

容器將根據需要使用盡可能多的 CPU。 如果在命名空間中定義了預設 CPU 策略 (LimitRange),則此限制也適用於容器。

如果您不指定請求或 CPU 限制,會發生什麼情況?

與內存一樣,這是最壞的情況。 調度程序不知道您的容器需要多少資源,這可能會導致節點出現嚴重問題。 為了避免這種情況,您需要為命名空間設定預設限制(LimitRange)。

請記住:如果您要求的 CPU 多於節點可以提供的 CPU,則 Pod 將不會被調度。 Requests.cpu - 不是最小值,而是足以啟動 Pod 並且正常工作的值。 如果應用程式不執行複雜的計算,最好的選擇是安裝 request.cpu <= 1 並根據需要啟動盡可能多的副本。

請求的資源的理想數量或資源限制

我們了解到計算資源的限制。 現在是時候回答這個問題了:「我的 Pod 需要多少資源才能運行應用程式而不出現任何問題? 理想的量是多少?

不幸的是,這些問題沒有明確的答案。 如果您不知道應用程式如何運作或需要多少 CPU 或內存,最好的選擇是為應用程式提供大量內存和 CPU,然後運行效能測試。

除了效能測試之外,還要在一週的監控中監控應用程式的行為。 如果圖表顯示您的應用程式消耗的資源少於您要求的資源,您可以減少要求的 CPU 或記憶體量。

舉個例子看看這個 Grafana 儀表板。 它顯示請求的資源或資源限制與目前資源使用情況之間的差異。

結論

請求和限制資源有助於維持 Kubernetes 叢集的健康運作。 正確的限製配置可以最大限度地降低成本並保持應用程式始終運行。

簡而言之,有以下幾點要記住:

  1. 請求的資源是在啟動時(當 Kubernetes 計劃託管應用程式時)考慮的配置。 相反,限制資源在運行時非常重要——當應用程式已經在節點上運行時。
  2. 與記憶體相比,CPU 是一種受管制的資源。 如果沒有足夠的CPU,你的Pod將不會關閉並且節流機制將開啟。
  3. 請求的資源和資源限制不是最小值和最大值! 透過定義所請求的資源,您可以確保應用程式在運行時不會出現問題。
  4. 一個好的做法是將記憶體請求設定為等於記憶體限制。
  5. 好的安裝請求 CPU <=1,如果應用程式不執行複雜的計算。
  6. 如果您要求的資源多於節點上可用的資源,則 Pod 將永遠不會調度到該節點。
  7. 若要確定請求的資源/資源限制的正確數量,請使用負載測試和監控。

我希望這篇文章可以幫助您理解資源限制的基本概念。 您將能夠將這些知識應用到您的工作中。

祝你好運!

還有什麼要讀的:

  1. SRE 可觀察性:命名空間與指標結構.
  2. 90 多種 Kubernetes 有用工具:部署、管理、監控、安全等.
  3. 我們在 Telegram 中圍繞 Kubernetes 的頻道.

來源: www.habr.com

添加評論