ack-koordinator提供動態資源超賣功能,通過對節點負載資料的即時收集,可以充分挖掘叢集中已指派但未使用的資源量,以實現對叢集資源的動態超賣。本文主要介紹如何使用動態資源超賣功能。
前提條件
僅支援ACK Pro版叢集。具體操作,請參見建立ACK Pro版叢集。
已安裝ack-koordinator(原ack-slo-manager)。具體操作,請參見ack-koordinator。
費用說明
ack-koordinator組件本身的安裝和使用是免費的,不過需要注意的是,在以下情境中可能產生額外的費用:
背景資訊
在Kubernetes系統中,Kubelet通過參考Pod的QoS等級來管理單機容器的資源品質,例如OOM(Out of Memory)優先順序控制等。Pod的QoS層級分為Guaranteed、Burstable和BestEffort。QoS層級並不是顯式定義,而是取決於Pod配置的Request和Limit(CPU、記憶體)。
為了提高穩定性,應用管理員在提交Guaranteed和Burstable這兩類Pod時會預留相當數量的資源Buffer來應對上下遊鏈路的負載波動,在大部分時間段,容器的Request會遠高於實際的資源使用率。為了提升叢集資源使用率,應用管理員會提交一些QoS為BestEffort的低優任務,來充分使用那些已指派但未使用的資源,實現對叢集資源的超賣,其缺點如下:
節點可容納低優任務的資源量沒有任何參考,即使節點實際負載已經很高,由於BestEffort任務在資源規格上缺少容量約束,仍然會被調度到節點上運行。
BestEffort任務間缺乏公平性保證,任務資源規格存在區別,但無法在Pod描述上體現。
針對以上問題,ACK的差異化SLO(Service Level Objectives)提供了將這部分資源量化的能力。將上圖中的紅線定義為Usage,藍線到紅線預留部分資源定義為Buffered,綠色覆蓋部分定義為Reclaimed。
如下圖所示,Reclaimed資源代表可動態超賣的資源量。ack-koordinator會根據節點真實負載情況動態更新,並以標準擴充資源的形式即時更新到K8s的Node元資訊中。低優的BestEffort任務可以通過在Request和Limit中定義的Reclaimed資源配置來使用這部分資源,這部分配置同時也會體現在節點側的資源限制參數上,保證BestEffort作業之間的公平性。
為體現與原生資源類型的差異性,ack-koordinator使用“Batch”優先順序的概念描述該部分超賣資源,以下簡稱batch-cpu和batch-memory。
使用限制
組件 | 版本要求 |
Kubernetes | ≥v1.18 |
≥0.8.0 | |
Helm版本 | ≥v3.0 |
操作步驟
使用以下命令,查看當前Batch資源總量。
查看前請確保對應配置已經開啟,詳見步驟3中的描述。
# 將$nodeName替換為要查詢的目標節點名稱。 kubectl get node $nodeName -o yaml
預期輸出:
#Node status: allocatable: # 單位為千分之一核,以下表示50核。 kubernetes.io/batch-cpu: 50000 # 單位為位元組,以下表示50 GB。 kubernetes.io/batch-memory: 53687091200
建立Pod並申請Batch資源。在Label中指定QoS等級,並在Request和Limit中添加對應的Batch資源配置,即可讓Pod使用動態超賣資源,具體樣本如下。
#Pod metadata: labels: # 必填,標記為低優先順序Pod。 koordinator.sh/qosClass: "BE" spec: containers: - resources: requests: # 單位為千分之一核,如下表示1核。 kubernetes.io/batch-cpu: "1k" # 單位為位元組,如下表示1 GB。 kubernetes.io/batch-memory: "1Gi" limits: kubernetes.io/batch-cpu: "1k" kubernetes.io/batch-memory: "1Gi"
申請Batch資源需注意:
若您通過Deployment或其它類型工作負載提交Pod,只需在對應的模板欄位中參照上述樣本,採用相同格式填寫即可。同一個Pod不能同時申請Batch資源和普通的CPU或Memory資源。
由於節點的Batch資源總量根據當前實際負載動態計算得到,在邊界情況下可能會因Kubelet未及時同步而被拒絕,此時您可以直接將被拒絕的Pod進行刪除。
受K8s的約束,擴充資源必須以整數形式表達,因此
batch-cpu
資源需要以千分之一核為單位進行配置。
管理動態超賣資源。
節點的Batch容量根據實際的資源使用率情況動態計算得到,CPU和記憶體維度預設的計算過程可以按如下公式簡單推導:
nodeBatchAllocatable = nodeAllocatable * thresholdPercent - podUsage(non-BE) - systemUsage
計算公式中各因子的含義如下:
nodeAllocatable:節點可分配資源總量。
thresholdPercent:預留水位比例。
podUsage(non-BE):高優先順序Pod的資源用量,即非BE類型Pod的資源使用量。
systemUsage:節點系統資源真實用量。
同時,對於記憶體維度資源超賣,ack-koordinator還支援按請求量(Request)計算,具體配置參考後文有關memoryCalculatePolicy的描述,公式如下。其中
podRequest(non-BE)
表示高優先順序Pod的資源請求量,即非BE類型Pod的資源請求量(Request)之和。nodeBatchAllocatable = nodeAllocatable * thresholdPercent - podRequest(non-BE) - systemUsage
公式中的thresholdPercent為可配置參數,通過修改ConfigMap中的配置項可以實現對資源的靈活管理,配置樣本及詳細說明如下。
apiVersion: v1 kind: ConfigMap metadata: name: ack-slo-config namespace: kube-system data: colocation-config: | { "enable": true, "metricAggregateDurationSeconds": 60, "cpuReclaimThresholdPercent": 60, "memoryReclaimThresholdPercent": 70, "memoryCalculatePolicy": "usage" }
欄位名稱
格式
含義
enable
Boolean
表示是否開啟節點Batch資源的動態更新,關閉時Batch資源量會被重設為
0
。預設值為false
。metricAggregateDurationSeconds
Int
Batch資源最小更新頻率,單位為秒。通常建議保持為1分鐘不必修改。
cpuReclaimThresholdPercent
Int
計算節點
batch-cpu
資源容量時的預留係數。預設值為65
,單位為百分比。memoryReclaimThresholdPercent
Int
計算節點
batch-memory
資源容量時的預留係數。預設值為65
,單位為百分比。memoryCalculatePolicy
String
計算節點batch-memory資源容量時的策略。
"usage"
:預設值,表示batch-memory記憶體資源按照高優先順序Pod的記憶體真實用量計算,包括了節點未申請的資源,以及已申請但未使用的資源量。"request"
:表示batch-memory記憶體資源按照高優先順序Pod的記憶體請求量計算,僅包括節點未申請的資源。
說明ack-koordinator在單機端提供了針對Batch資源的壓制和驅逐能力,包括彈性資源限制、容器記憶體QoS和容器L3 Cache及記憶體頻寬隔離,能夠有效避免低優的BestEffort容器帶來的幹擾問題。
查看命名空間
kube-system
下是否存在ConfigMapack-slo-config
。若存在ConfigMap
ack-slo-config
,請使用PATCH方式進行更新,避免幹擾ConfigMap中其他配置項。kubectl patch cm -n kube-system ack-slo-config --patch "$(cat configmap.yaml)"
若不存在ConfigMap
ack-slo-config
,請執行以下命令進行建立Configmap。kubectl apply -f configmap.yaml
(可選)通過Prometheus查看Batch資源使用方式。
如果您首次使用該功能的大盤,請確保動態資源超賣大盤已經升級到最新版本。關於升級的具體操作,請參見相關操作。
通過ACK控制台Prometheus監控查看Batch資源使用方式的具體操作如下:
登入Container Service管理主控台,在左側導覽列選擇叢集。
在叢集列表頁面,單擊目的地組群名稱,然後在左側導覽列,選擇 。
在Prometheus監控頁面,單擊成本分析/資源最佳化頁簽,然後單擊在離線混部頁簽。
您可以在在離線混部頁簽查看詳細資料,包括叢集以及單個節點的Batch總量和已申請量。更多資訊,請參見基礎監控。
# 節點batch-cpu可分配總量。 koordlet_node_resource_allocatable{resource="kubernetes.io/batch-cpu",node="$node"} # 節點batch-cpu已指派量。 koordlet_container_resource_requests{resource="kubernetes.io/batch-cpu",node="$node"} # 節點batch-memory可分配總量。 kube_node_status_allocatable{resource="kubernetes.io/batch-memory",node="$node"} # 節點batch-memory已指派量。 koordlet_container_resource_requests{resource="kubernetes.io/batch-memory",node="$node"}
使用範例
使用以下命令,查看節點Reclaimed資源總量。
查看前請確保對應配置已經開啟,詳見步驟3中的描述。
kubectl get node $nodeName -o yaml
預期輸出:
#Node資訊 status: allocatable: # 單位為千分之一核,以下表示50核。 kubernetes.io/batch-cpu: 50000 # 單位為位元組,以下表示50 GB。 kubernetes.io/batch-memory: 53687091200
使用以下YAML內容,建立名為be-pod-demo.yaml檔案。
apiVersion: v1 kind: Pod metadata: lables: koordinator.sh/qosClass: "BE" name: be-demo spec: containers: - command: - "sleep" - "100h" image: polinux/stress imagePullPolicy: Always name: be-demo resources: limits: kubernetes.io/batch-cpu: "50k" kubernetes.io/batch-memory: "10Gi" requests: kubernetes.io/batch-cpu: "50k" kubernetes.io/batch-memory: "10Gi" schedulerName: default-scheduler
使用以下命令,部署be-pod-demo作為目標評測應用。
kubectl apply -f be-pod-demo.yaml
在單機端的cgroup分組中查看BE Pod資源限制的生效情況。
使用以下命令,查看CPU資源限制參數。
cat /sys/fs/cgroup/cpu,cpuacct/kubepods.slice/kubepods-besteffort.slice/kubepods-besteffort-pod4b6e96c8_042d_471c_b6ef_b7e0686a****.slice/cri-containerd-11111c202adfefdd63d7d002ccde8907d08291e706671438c4ccedfecba5****.scope/cpu.cfs_quota_us
預期輸出:
#容器對應的CPU Cgroup為50核。 5000000
使用以下命令,查看Memory資源限制參數。
cat /sys/fs/cgroup/memory/kubepods.slice/kubepods-besteffort.slice/kubepods-besteffort-pod4b6e96c8_042d_471c_b6ef_b7e0686a****.slice/cri-containerd-11111c202adfefdd63d7d002ccde8907d08291e706671438c4ccedfecba5****.scope/memory.limit_in_bytes
預期輸出:
#容器對應的Memory Cgroup為10 GB。 10737418240
常見問題
當前已通過ack-slo-manager的舊版本協議使用了動態資源超賣功能,升級為ack-koordinator後是否繼續支援?
舊版本的動態資源超賣協議包括兩部分:
在Pod的Annotation中填寫的
alibabacloud.com/qosClass
。在Pod的Request和Limit中填寫的
alibabacloud.com/reclaimed
。
ack-koordinator相容以上舊版本協議,並在ACK Pro調度器中統一計算新舊版本協議的資源申請量和可用量。您可將組件無縫升級至ack-koordinator。
ack-koordinator對舊版本協議的相容期限截止至2023年07月30日。強烈建議您將原協議資源欄位及時升級到新版本。
ACK Pro調度器和ack-koordinator對各版本協議的適配如下。
ACK調度器版本 | ack-koordinator版本(ack-slo-manager) | alibabacloud.com協議 | koordinator.sh協議 |
≥1.18且<1.22.15-ack-2.0 | ≥0.3.0 | 支援 | 不支援 |
≥1.22.15-ack-2.0 | ≥0.8.0 | 支援 | 支援 |
應用使用了Batch資源後,記憶體資源用量突然變得更高是什麼原因?
對於在Pod資源限制Limit中配置了kubernetes.io/batch-memory
的應用(簡稱batch limit),koordinator會等待容器建立後根據batch limit在節點上為其設定cgroup限制參數。由於部分應用在啟動時會根據容器cgroup參數自動申請記憶體,若應用在cgroup的memory.limit參數設定前就啟動完成,其記憶體的真實用量可能會超過batch limit。而受作業系統約束,這時容器的記憶體cgroup參數將無法設定成功,直至其真實用量降低至batch limit以下才會設定成功。
對於這種情況,我們建議適當修改應用配置參數,控制其記憶體真實用量在batch limit以下,或在應用啟動指令碼中首先檢查記憶體限制參數,確認設定完成後再啟動,確保應用的記憶體用量得到合理限制,避免出現OOM等情況。
在容器內執行以下命令,可以查看記憶體資源限制參數。
# 單位為位元組
cat /sys/fs/cgroup/memory/memory.limit_in_bytes
1048576000