在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-koordinator是非託管組件,安裝後將佔用Worker節點資源。您可以在安裝組件時配置各模組的資源申請量。
ack-koordinator預設會將資源畫像、精細化調度等功能的監控指標以Prometheus的格式對外透出。若您配置組件時開啟了ACK-Koordinator開啟Prometheus監控指標選項並使用了阿里雲Prometheus服務,這些指標將被視為自訂指標併產生相應費用。具體費用取決於您的叢集規模和應用數量等因素。建議您在啟用此功能前,仔細閱讀阿里雲PrometheusPrometheus 執行個體計費,瞭解自訂指標的免費額度和收費策略。您可以通過用量查詢,監控和管理您的資源使用方式。
前提條件
已建立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資源的靈活管理。
參數說明
參數
格式
說明
enableBoolean
是否開啟節點Batch資源的動態更新。關閉時,Batch資源量會被重設為
0。預設值為false。metricAggregateDurationSecondsInt
系統在多長時間周期內彙總一次指標資料,以決定是否需要更新或調整Batch資源,單位為秒。通常建議使用預設值,60秒。
cpuReclaimThresholdPercentInt
計算節點batch-cpu資源容量時的預留係數。關於如何計算可動態超賣的CPU資源量,請參見計算可用的動態超賣資源量。預設值為
65,單位為百分比。memoryReclaimThresholdPercentInt
計算節點batch-memory資源容量時的預留係數。關於如何計算可動態超賣的記憶體資源量,請參見計算可用的動態超賣資源量。預設值為
65,單位為百分比。memoryCalculatePolicyString
計算節點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中聲明所需的資源。
執行以下命令,查看節點當前可用的Batch資源總量。
# 將$nodeName替換為要查詢的目標節點名稱。 kubectl get node $nodeName -o yaml預期輸出:
# 節點資訊。 status: allocatable: # 單位為毫核,1核=1000毫核,如下表示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核=1000毫核,如下表示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: # 單位為毫核,1核=1000毫核,如下表示50核。 kubernetes.io/batch-cpu: 50000 # 單位為位元組,以下表示50 GB。 kubernetes.io/batch-memory: 53687091200使用以下YAML內容,建立名為be-pod-demo.yaml檔案。
apiVersion: v1 kind: Pod metadata: labels: 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管理主控台,在左側導覽列選擇叢集列表。
在叢集列表頁面,單擊目的地組群名稱,然後在左側導覽列,選擇。
單擊其他頁簽,然後單擊Kubernetes Reclaimed Resource頁簽。
可在此頁簽查看叢集混部的資源收益,以及叢集、節點和Pod維度混部資源容量資料。詳細資料,請參見啟用在離線混部監控。
若自建了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的記憶體資源限制未生效?
問題原因
為應用Pod在limit欄位中配置kubernetes.io/batch-memory(簡稱Batch Limit)後,ack-koordinator會在容器建立後根據Batch Limit在節點上為其設定Cgroup限制參數。
部分應用在啟動時會根據容器Cgroup參數自動申請記憶體。但如果應用啟動速度過快,在Cgroup的memory.limit參數生效前就完成了啟動,其記憶體的真實用量可能會超出Batch Limit。而作業系統不會立即縮減該進程的記憶體使用量,從而導致容器的記憶體Cgroup參數無法生效。只有在容器真實用量首次降低至Batch Limit值以下後,該參數才會生效。
解決方案
為避免此問題導致 OOM 等情況,建議採用以下任一方案:
調整應用配置:手動設定應用的記憶體參數(如 Java 的 -Xmx),確保其最大用量低於 Batch Limit 限制。
在啟動指令碼中等待:在啟動應用主進程前,加入等待邏輯,直到檢測到 Cgroup 記憶體限制已成功設定。
可在容器內執行以下命令,查看記憶體資源限制參數的生效情況。
# 單位為位元組
cat /sys/fs/cgroup/memory/memory.limit_in_bytes
# 預期輸出
1048576000如預期輸出值與配置的 Batch Limit值(換算為位元組後)相符,則表明記憶體限制已生效。