全部產品
Search
文件中心

Container Service for Kubernetes:啟用動態資源超賣

更新時間:Oct 25, 2024

在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服務,這些指標將被視為自訂指標併產生相應費用。具體費用取決於您的叢集規模和應用數量等因素。建議您在啟用此功能前,仔細閱讀阿里雲Prometheus計費說明,瞭解自訂指標的免費額度和收費策略。您可以通過賬單和用量查詢,監控和管理您的資源使用方式。

前提條件

操作步驟

您可以通過ConfigMap在叢集維度開啟動態資源超賣功能,然後在Pod的YAML檔案中通過Labelkoordinator.sh/qosClass聲明Pod對應的QoS類,並在Request和Limit中添加對應的Batch資源配置,讓Pod使用動態超賣的資源。

1、開啟動態資源超賣

您可以通過ConfigMap開啟動態資源超賣功能,也可以在ConfigMap中配置相關參數,例如節點資源的預留係數、計算節點資源容量的策略等,實現更靈活的超賣資源管理。

  1. 參見以下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資源,僅包括節點未申請的資源。

    計算可用的動態超賣資源量

    根據Usage計算可用資源

    節點的Batch容量預設會根據實際的資源使用率情況動態進行計算,包括節點未申請的資源以及已申請但未使用的資源量。如需計算當前batch-cpu或batch-memory的可用資源量,可參見以下公式。

    nodeBatchAllocatable = nodeAllocatable * thresholdPercent - podUsage(non-BE) - systemUsage

    • nodeAllocatable:節點可分配的CPU或記憶體資源總量。

    • thresholdPercent:預留水位比例。您可以參見參數說明表格靈活調整。

    • podUsage(non-BE):高優先順序Pod的資源用量,即非BE類型Pod的資源使用量。

    • systemUsage:節點系統資源真實用量。

    根據Pod Request計算Batch記憶體可用資源

    對於batch-memory的資源超賣,您還可以按Pod Request進行計算,僅包括節點未申請的資源。解釋說明,可參見參數說明memoryCalculatePolicy的參數說明。

    您仍然可以參見以下公式來計算。

    nodeBatchAllocatable = nodeAllocatable * thresholdPercent - podRequest(non-BE) - systemUsage

    其中,podRequest(non-BE)表示高優先順序Pod的資源Request,即非BE類型Pod的資源Request之和。

  2. 查看命名空間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

  1. 執行以下命令,查看節點當前可用的Batch資源總量。

    # 將$nodeName替換為要查詢的目標節點名稱。
    kubectl get node $nodeName -o yaml

    預期輸出:

    # 節點資訊。
    status:
      allocatable:
        # 單位為千分之一核,以下表示50核。
        kubernetes.io/batch-cpu: 50000
        # 單位為位元組,以下表示50 GB。
        kubernetes.io/batch-memory: 53687091200
  2. 建立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資源限制的生效情況,驗證配置是否成功。

  1. 執行以下命令,查看節點當前可用的Batch資源總量。

    kubectl get node $nodeName -o yaml

    預期輸出:

    # 節點資訊。
    status:
      allocatable:
        # 單位為千分之一核,以下表示50核。
        kubernetes.io/batch-cpu: 50000
        # 單位為位元組,以下表示50 GB。
        kubernetes.io/batch-memory: 53687091200
  2. 使用以下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
  3. 使用以下命令,部署be-pod-demo作為目標評測應用。

    kubectl apply -f be-pod-demo.yaml
  4. 在單機端的Cgroup分組中查看BE Pod資源限制的生效情況。

    1. 執行以下命令,查看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
    2. 執行以下命令,查看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資源的使用方式。

  1. 登入Container Service管理主控台,在左側導覽列選擇叢集

  2. 叢集列表頁面,單擊目的地組群名稱,然後在左側導覽列,選擇營運管理 > Prometheus 監控

  3. 單擊成本分析/資源最佳化頁簽,然後單擊在離線混部頁簽。

    您可以在在離線混部頁簽查看詳細資料,包括叢集以及單個節點的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