為什麼需要資源管理#
Kubernetes 是一個跨多個節點(Node)的叢集管理平台,每個節點都可以視為一台具備固定運算資源的主機。要讓平台上的容器穩定運作,叢集必須清楚掌握整體資源使用狀況,並依照需求把資源合理分配給每一個容器:
- 確保容器在生命週期內擁有足以運作的資源。
- 避免某些低度使用的容器長時間獨佔資源造成浪費。
- 在優先度與公平性之間取得平衡,盡可能提高利用率。
為此,Kubernetes 提供了兩種資源宣告方式 — 資源請求(Request)與資源限制(Limit),讓我們在 Pod spec 中指定每個容器需要多少資源、最多能用到多少。
Request 與 Limit 是什麼#
Request#
- 容器啟動時所要求的最小資源量,是排程器決定 Pod 要被放到哪個節點的依據。
- 只有當節點上「可分配資源 ≥ Request」時,Pod 才會被排到該節點上執行。
Limit#
- 容器在執行期間可以使用的資源上限。
- 若設定為
0,代表不對該資源設限,容器可以一路用上去。
兩者之間的關係#
容器宣告的 Request 必須大於等於 0,且不能超過節點可分配的容量:
0 <= request <= Node AllocatableLimit 則必須大於等於 Request,理論上沒有上限:
request <= limit <= Infinity可宣告的資源類型:CPU 與 Memory#
Kubernetes 把底層的硬體資源抽象成幾種計算資源,常用的兩種是 CPU 與記憶體:
- CPU:以「核心(cores)」為計量單位。一個 CPU 大致對應到一個雲端 vCPU 或一條 Hyperthread。
- Memory:以位元組為計量單位,可以使用整數或附帶後綴(E、P、T、G、M、K)的數值表示,例如
200Mi。
Pod 的服務品質:QoS Class#
Pod 建立時,Kubernetes 會根據裡面每個容器的 Request 與 Limit,自動把 Pod 分到三種 QoS Class(Guaranteed/Burstable/BestEffort)之一。這個分類會直接影響系統資源吃緊時,誰會被優先驅逐。
Guaranteed#
當 Pod 內每個容器的 requests.memory 等於 limits.memory,且 requests.cpu 等於 limits.cpu 時,這個 Pod 會被歸類為 Guaranteed:
apiVersion: v1
kind: Pod
metadata:
name: qos-demo
namespace: qos-example
spec:
containers:
- name: qos-demo-ctr
image: nginx
resources:
limits:
memory: "200Mi"
cpu: "700m"
requests:
memory: "200Mi"
cpu: "700m"Burstable#
需要同時滿足兩個條件:
- 不是 Guaranteed Pod。
- Pod 中至少有一個容器設定了 memory 或 cpu 的 Request。
apiVersion: v1
kind: Pod
metadata:
name: qos-demo-2
namespace: qos-example
spec:
containers:
- name: qos-demo-2-ctr
image: nginx
resources:
limits:
memory: "200Mi"
requests:
memory: "100Mi"BestEffort#
當 Pod 內所有容器都沒有設定 Request 與 Limit 時,這個 Pod 會被歸類為 BestEffort:
apiVersion: v1
kind: Pod
metadata:
name: qos-demo-3
namespace: qos-example
spec:
containers:
- name: qos-demo-3-ctr
image: nginx可以透過以下指令查看實際分到的 QoS Class:
kubectl get pod qos-demo-3 --output=yaml輸出中會看到類似結構:
spec:
containers:
...
resources: {}
status:
qosClass: BestEffort不同 QoS Class 的命運#
當系統資源吃緊時,Kubernetes 會依照 QoS Class 決定優先驅逐哪些 Pod:
- BestEffort:優先級最低。記憶體不足時,第一批被清理的就是它們。
- Burstable:擁有最低限度的資源保障,但允許在資源充裕時用到 Limit。當沒有 BestEffort Pod 可以驅逐時,Burstable 會是下一個目標。
- Guaranteed:優先級最高,通常不會被殺掉或限流,除非自己用量超出 Limit,且沒有更低優先級的 Pod 可清理。
小結#
Request 與 Limit 看似只是兩個欄位,背後牽動著 Pod 的命運:
- 設定 Request,是為了讓 Kubernetes 把 Pod 放到擁有足夠資源的節點上。
- 設定 Limit,是為了避免單一容器吃掉整台機器。
- 把 Limit 設得高於 Request,則代表容器「平時保底拿 Request、忙的時候才衝到 Limit」。
掌握這組基本機制,後續才有辦法談 Namespace、LimitRange、ResourceQuota,乃至於依資源指標自動擴縮容(Autoscaling)。
原文出處#
- GitHub:https://github.com/MikeHsu0618/2022-ithelp/tree/main/Day21
- iThome:https://ithelp.ithome.com.tw/articles/10295419