為容器和 Pod 指派 CPU 資源
此頁面說明如何為容器指派 CPU 請求和 CPU 限制。容器使用的 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 中的一個容器具有 500 milliCPU 的 CPU 請求和 1 CPU 的 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 來表示毫(milli)。例如,100m CPU、100 毫 CPU 和 0.1 CPU 都是相同的。不允許精確度高於 1m。
CPU 始終以絕對量請求,而不是相對量;在單核、雙核或 48 核機器上,0.1 的 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 的組態檔,該 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