為容器和 Pod 分配 CPU 資源

本頁面演示如何為容器分配 CPU 請求(request)和 CPU 限制(limit)。容器不能使用超出所配置限制的 CPU。只要系統有空閒 CPU 時間,容器就能保證獲得其請求的 CPU 量。

準備工作

你需要擁有一個 Kubernetes 叢集,並且 kubectl 命令列工具已配置為與你的叢集通訊。建議在至少有兩個不是控制平面主機的節點的叢集上執行本教程。如果你還沒有叢集,可以使用 minikube 建立一個,或者使用以下 Kubernetes 演練場之一

要檢查版本,請輸入 kubectl version

你的叢集必須至少有 1 個 CPU 可用才能執行任務示例。

本頁面上的某些步驟要求你在叢集中執行 metrics-server 服務。如果 metrics-server 正在執行,你可以跳過這些步驟。

如果你正在執行 Minikube,請執行以下命令以啟用 metrics-server

minikube addons enable metrics-server

要檢視 metrics-server(或其他資源指標 API 提供程式,metrics.k8s.io)是否正在執行,請鍵入以下命令

kubectl get apiservices

如果資源指標 API 可用,則輸出將包含對 metrics.k8s.io 的引用。

NAME
v1beta1.metrics.k8s.io

建立名稱空間

建立一個名稱空間,以便你在本練習中建立的資源與叢集的其餘部分隔離。

kubectl create namespace cpu-example

指定 CPU 請求和 CPU 限制

要為容器指定 CPU 請求,請在容器資源清單中包含 resources:requests 欄位。要指定 CPU 限制,請包含 resources:limits

在本練習中,你將建立一個包含一個容器的 Pod。該容器的請求為 0.5 CPU,限制為 1 CPU。這是 Pod 的配置檔案

apiVersion: v1
kind: Pod
metadata:
  name: cpu-demo
  namespace: cpu-example
spec:
  containers:
  - name: cpu-demo-ctr
    image: vish/stress
    resources:
      limits:
        cpu: "1"
      requests:
        cpu: "0.5"
    args:
    - -cpus
    - "2"

配置檔案的 args 部分提供了容器啟動時的引數。-cpus "2" 引數告訴容器嘗試使用 2 個 CPU。

建立 Pod

kubectl apply -f https://k8s.io/examples/pods/resource/cpu-request-limit.yaml --namespace=cpu-example

驗證 Pod 是否正在執行

kubectl get pod cpu-demo --namespace=cpu-example

檢視 Pod 的詳細資訊

kubectl get pod cpu-demo --output=yaml --namespace=cpu-example

輸出顯示 Pod 中的一個容器的 CPU 請求為 500 milliCPU,CPU 限制為 1 CPU。

resources:
  limits:
    cpu: "1"
  requests:
    cpu: 500m

使用 kubectl top 獲取 Pod 的指標

kubectl top pod cpu-demo --namespace=cpu-example

此示例輸出顯示 Pod 正在使用 974 milliCPU,略低於 Pod 配置中指定的 1 CPU 限制。

NAME                        CPU(cores)   MEMORY(bytes)
cpu-demo                    974m         <something>

回想一下,透過設定 -cpu "2",你配置容器嘗試使用 2 個 CPU,但容器只被允許使用大約 1 個 CPU。容器的 CPU 使用正在受到限制,因為容器試圖使用超出其限制的 CPU 資源。

CPU 單位

CPU 資源以 CPU 單位計量。在 Kubernetes 中,一個 CPU 等同於

  • 1 個 AWS vCPU
  • 1 個 GCP 核心
  • 1 個 Azure vCore
  • 在帶超執行緒的裸金屬 Intel 處理器上,1 個超執行緒

允許分數。請求 0.5 CPU 的容器保證獲得請求 1 CPU 的容器一半的 CPU。你可以使用字尾 m 表示毫。例如,100m CPU、100 milliCPU 和 0.1 CPU 都相同。不允許比 1m 更精細的精度。

CPU 總是以絕對數量而非相對數量來請求;0.1 CPU 在單核、雙核或 48 核機器上都是相同的 CPU 量。

刪除你的 Pod

kubectl delete pod cpu-demo --namespace=cpu-example

指定一個對你的節點來說太大的 CPU 請求

CPU 請求和限制與容器相關聯,但將 Pod 視為具有 CPU 請求和限制是有益的。Pod 的 CPU 請求是 Pod 中所有容器的 CPU 請求之和。同樣,Pod 的 CPU 限制是 Pod 中所有容器的 CPU 限制之和。

Pod 排程基於請求。只有當節點有足夠的 CPU 資源來滿足 Pod 的 CPU 請求時,Pod 才會被排程到該節點上執行。

在本練習中,你將建立一個 Pod,其 CPU 請求非常大,以至於超出了叢集中任何節點的容量。這是一個包含一個容器的 Pod 的配置檔案。該容器請求 100 個 CPU,這很可能超出叢集中任何節點的容量。

apiVersion: v1
kind: Pod
metadata:
  name: cpu-demo-2
  namespace: cpu-example
spec:
  containers:
  - name: cpu-demo-ctr-2
    image: vish/stress
    resources:
      limits:
        cpu: "100"
      requests:
        cpu: "100"
    args:
    - -cpus
    - "2"

建立 Pod

kubectl apply -f https://k8s.io/examples/pods/resource/cpu-request-limit-2.yaml --namespace=cpu-example

檢視 Pod 狀態

kubectl get pod cpu-demo-2 --namespace=cpu-example

輸出顯示 Pod 狀態為 Pending。也就是說,Pod 尚未被排程到任何節點上執行,並將無限期地保持 Pending 狀態

NAME         READY     STATUS    RESTARTS   AGE
cpu-demo-2   0/1       Pending   0          7m

檢視有關 Pod 的詳細資訊,包括事件

kubectl describe pod cpu-demo-2 --namespace=cpu-example

輸出顯示由於節點上的 CPU 資源不足,容器無法排程

Events:
  Reason                        Message
  ------                        -------
  FailedScheduling      No nodes are available that match all of the following predicates:: Insufficient cpu (3).

刪除你的 Pod

kubectl delete pod cpu-demo-2 --namespace=cpu-example

如果你未指定 CPU 限制

如果你未為容器指定 CPU 限制,則會發生以下情況之一:

  • 容器對其可使用的 CPU 資源沒有上限。容器可以使用其執行節點上所有可用的 CPU 資源。

  • 容器正在一個具有預設 CPU 限制的名稱空間中執行,並且容器會自動被分配預設限制。叢集管理員可以使用 LimitRange 來指定 CPU 限制的預設值。

如果你指定了 CPU 限制但未指定 CPU 請求

如果你為容器指定了 CPU 限制但未指定 CPU 請求,Kubernetes 會自動分配一個與限制匹配的 CPU 請求。類似地,如果容器指定了自己的記憶體限制,但未指定記憶體請求,Kubernetes 會自動分配一個與限制匹配的記憶體請求。

CPU 請求和限制的動機

透過配置在你的叢集中執行的容器的 CPU 請求和限制,你可以高效地利用叢集節點上可用的 CPU 資源。透過將 Pod CPU 請求保持在較低水平,你可以使 Pod 有很好的機會被排程。透過將 CPU 限制設定為大於 CPU 請求,你可以實現兩個目的:

  • Pod 可以進行突發活動,利用恰好可用的 CPU 資源。
  • Pod 在突發期間可以使用的 CPU 資源量被限制在合理的範圍內。

清理

刪除你的名稱空間

kubectl delete namespace cpu-example

下一步

致應用開發者

致叢集管理員

上次修改時間:2025 年 4 月 7 日上午 9:46 (PST):更新 v1.33 beta 的 InPlacePodVerticalScaling 文件 (#50290) (c014f72fbb)