為容器和 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 使用低於 1.0 的另一個可能解釋是節點可能沒有足夠的 CPU 資源可用。回想一下,本練習的先決條件要求你的叢集至少有 1 個 CPU 可用。如果你的容器在一個只有 1 個 CPU 的節點上執行,那麼無論為容器指定的 CPU 限制是多少,容器都不能使用超過 1 個 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