在ACK叢集中,如果您希望將已申請但未使用的資源分派給低優先順序應用,可以啟用動態資源超賣功能。動態資源超賣可以即時收集節點的真實負載資料,量化叢集中已指派但未使用的CPU和記憶體資源,為BestEffort作業提供資源並保證BestEffort作業之間的資源公平性。
為了協助您更好地理解本文檔並使用本功能,推薦您參見Kubernetes官方文檔瞭解Pod Qos類、為容器和 Pod 分配記憶體資源等概念。
為什麼需要啟用動態資源超賣
Kubernetes會參考Pod的Qos類(Guaranteed、Burstable和BestEffort)來管理單機容器的資源品質,例如OOM優先順序控制等。
為了提高應用穩定性,應用管理員在部署應用時會預留相當數量的資源Buffer來應對上下遊鏈路的負載波動。這會導致在大部分時間段內,容器的Request會遠高於實際的資源使用率。為了提升叢集資源使用率,叢集管理員可能會考慮提交一些BestEffort的低優任務,利用那些已指派但未使用的資源,實現對叢集資源的超賣。但這種傳統模式存在以下缺點。
系統無法根據節點當前的實際負載情況來決定是否為BE任務提供更多資源,導致即使某些節點實際負載已經很高,但由於BE任務沒有資源容量約束,仍然會被調度到節點上運行。
BE任務之間缺乏公平性保證,任務所需的資源規格不同,但無法在Pod描述中聲明。
為瞭解決上述問題,ACK提供了將可動態超賣的資源量化的能力。ack-koordinator組件支援收集節點真實的負載資料,以標準擴充資源的形式即時更新到Kubernetes的節點元資訊中。低優的BE任務可以在Request和Limit中聲明所需的超賣資源量,ACK調度器會參考其資源需求分配節點,併合理設定cgroup資源隔離參數,保障應用能夠合理使用資源。
為體現與原生資源類型的差異性,ack-koordinator使用Batch的概念描述該部分超賣資源,CPU和記憶體資源對應分別為batch-cpu和batch-memory。如下圖所示,Reclaimed資源代表可動態超賣的資源量,Buffered代表預留的資源Buffer、Usage代表實際已使用的資源量。
費用說明
ack-koordinator組件本身的安裝和使用是免費的,不過需要注意的是,在以下情境中可能產生額外的費用:
前提條件
已建立ACK叢集Pro版,請參見建立ACK Pro版叢集。
已安裝ack-koordinator組件,且組件版本為0.8.0及以上,請參見ack-koordinator。
操作步驟
您可以通過ConfigMap在叢集維度開啟動態資源超賣功能,然後在Pod的YAML檔案中通過Labelkoordinator.sh/qosClass
聲明Pod對應的QoS類,並在Request和Limit中添加對應的Batch資源配置,讓Pod使用動態超賣的資源。
1、開啟動態資源超賣
您可以通過ConfigMap開啟動態資源超賣功能,也可以在ConfigMap中配置相關參數,例如節點資源的預留係數、計算節點資源容量的策略等,實現更靈活的超賣資源管理。
參見以下ConfigMap,建立configmap.yaml檔案。
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" }
您可以修改ConfigMap中的配置項,實現對batch-cpu和batch-memory資源的靈活管理。
參數說明
參數
格式
含義
enable
Boolean
是否開啟節點Batch資源的動態更新,關閉時Batch資源量會被重設為
0
。預設值為false
。metricAggregateDurationSeconds
Int
Batch資源最小更新頻率,單位為秒。通常建議使用預設值,60秒。
cpuReclaimThresholdPercent
Int
計算節點batch-cpu資源容量時的預留係數。預設值為
65
,單位為百分比。memoryReclaimThresholdPercent
Int
計算節點
batch-memory
資源容量時的預留係數。預設值為65
,單位為百分比。memoryCalculatePolicy
String
計算節點batch-memory資源容量時的策略。
"usage"
:預設值,表示會按照高優先順序Pod的記憶體真實使用量計算可用的batch-memory資源,包括節點未申請的資源以及已申請但未使用的資源量。"request"
:會按照高優先順序Pod的記憶體Request計算可用的batch-memory資源,僅包括節點未申請的資源。
計算可用的動態超賣資源量
根據Pod Request計算Batch記憶體可用資源
查看命名空間kube-system下是否存在ConfigMap
ack-slo-config
。存在:使用PATCH方式進行更新,避免幹擾ConfigMap中其他配置項。
kubectl patch cm -n kube-system ack-slo-config --patch "$(cat configmap.yaml)"
不存在:執行以下命令建立ConfigMap。
kubectl apply -f configmap.yaml
2、為應用Pod申請Batch資源
配置完成後,根據節點當前可用的Batch資源總量,您可以在Pod YAML檔案的metadata
欄位中通過Labelkoordinator.sh/qosClass
來聲明Pod對應的QoS類,並在Request和Limit中聲明所需的資源。
對於未指定koordinator.sh/qosClass
的Pod,ack-koordinator將遵循Kubernetes原生的QoS類來配置,其中BestEffort類型的Pod為BE
、其他QoS類的Pod為LS
。
執行以下命令,查看節點當前可用的Batch資源總量。
# 將$nodeName替換為要查詢的目標節點名稱。 kubectl get node $nodeName -o yaml
預期輸出:
# 節點資訊。 status: allocatable: # 單位為千分之一核,以下表示50核。 kubernetes.io/batch-cpu: 50000 # 單位為位元組,以下表示50 GB。 kubernetes.io/batch-memory: 53687091200
建立Pod並申請Batch資源。
重要若您通過Deployment或其它類型的工作負載提交了Pod,請在
template.metadata
欄位下進行配置。同一個Pod不能同時申請Batch資源和普通的CPU或Memory資源。Koordinator組件會根據節點當前的實際負載來動態調整可為Pod分配的Batch資源。極少數情況下,kubelet同步節點狀態資訊可能存在一定的延遲,導致Pod因資源不足而調度失敗。此時,請刪除並重建該Pod。
受Kubernetes的約束,擴充資源必須為整數格式,因此batch-cpu資源需要以千分之一核為單位進行配置。
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資源的BE Pod。部署完成後,通過在單機端的cgroup分組中查看BE Pod資源限制的生效情況,驗證配置是否成功。
執行以下命令,查看節點當前可用的Batch資源總量。
kubectl get node $nodeName -o yaml
預期輸出:
# 節點資訊。 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: registry-cn-beijing.ack.aliyuncs.com/acs/stress:v1.0.4 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
相關操作
通過Prometheus查看Batch資源使用方式
ACK叢集整合了阿里雲Prometheus,提供Prometheus監控大盤。您可以在ACK控制台查看Batch資源的使用方式。
登入Container Service管理主控台,在左側導覽列選擇叢集。
在叢集列表頁面,單擊目的地組群名稱,然後在左側導覽列,選擇 。
單擊成本分析/資源最佳化頁簽,然後單擊在離線混部頁簽。
您可以在在離線混部頁簽查看詳細資料,包括叢集以及單個節點的Batch總量和已申請量。更多資訊,請參見基礎監控。
若您自建了Prometheus大盤,也可以參見下述指標查看混部資源資料情況。
# 節點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"}
常見問題
當前已通過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-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),ack-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