全部產品
Search
文件中心

Container Service for Kubernetes:使用負載感知調度

更新時間:Nov 09, 2024

ACK預設調度器僅會使用所需資源(Request)篩選規則進行節點篩選。推薦您在ACK叢集Pro版中啟用調度器的負載感知調度功能。該功能會根據節點的實際負載情況,將Pod優先調度到負載較低的節點,以實現節點負載平衡,降低節點故障風險。

前提條件

  • 已安裝ack-koordinator組件,且版本為1.1.1-ack.1及以上。具體操作,請參見ack-koordinator(ack-slo-manager)

  • 對於不同版本的ACK叢集,已確保支援負載感知調度的ACK調度器kube-scheduler滿足如下版本要求。

    ACK版本

    支援負載感知調度的ACK調度器版本

    1.26及以上

    所有版本均可支援

    1.24

    v1.24.6-ack-4.0及以上

    1.22

    v1.22.15-ack-4.0及以上

費用說明

ack-koordinator組件本身的安裝和使用是免費的,不過需要注意的是,在以下情境中可能產生額外的費用:

  • ack-koordinator是非託管組件,安裝後將佔用Worker節點資源。您可以在安裝組件時配置各模組的資源申請量。

  • ack-koordinator預設會將資源畫像、精細化調度等功能的監控指標以Prometheus的格式對外透出。若您配置組件時開啟了ACK-Koordinator開啟Prometheus監控指標選項並使用了阿里雲Prometheus服務,這些指標將被視為自訂指標併產生相應費用。具體費用取決於您的叢集規模和應用數量等因素。建議您在啟用此功能前,仔細閱讀阿里雲Prometheus計費說明,瞭解自訂指標的免費額度和收費策略。您可以通過賬單和用量查詢,監控和管理您的資源使用方式。

使用限制

僅支援ACK叢集Pro版。具體操作,請參見建立ACK Pro版叢集

負載感知調度介紹

負載感知調度是ACK調度器kube-scheduler基於Kubernetes Scheduling Framework實現的外掛程式。與Kubernetes原生調度策略不同的是,原生調度器主要基於資源的分配情況進行調度,而ACK調度器可以感知節點實際的資源負載情況。通過參考節點負載的歷史統計並對新調度Pod進行預估,調度器會將Pod優先調度到負載較低的節點,實現節點負載平衡的目標,避免出現因單個節點負載過高而導致的應用程式或節點故障。

如下圖所示,已指派資源量(Requested)代表已申請的資源量,已使用資源量(Usage)代表真實使用的資源量,只有真實使用的資源才會被算作真實負載。面對相同的節點情況,ACK調度器將新建立的Pod分配到負載更低的節點B。

1

考慮到節點的利用率會隨著時間、叢集環境、工作負載的流量或請求等動態變化,ack-koordinator組件還提供重調度能力,防止在Pod調度完成後,叢集再次出現負載極端不均衡的情況。通過將負載感知調度和熱點打散重調度結合使用,可以獲得叢集最佳的負載平衡效果。關於熱點打散重調度,請參見使用負載熱點打散重調度

工作原理

負載感知調度功能由kube-schedulerack-koordinator組件配合完成。其中,ack-koordinator組件負責節點資源使用率的採集和上報,ACK調度器會根據利用率資料對節點進行打分排序,優先選取負載更低的節點參與調度。關於組件架構的詳細介紹,請參見ack-koordinator組件架構

策略說明

策略名稱稱

說明

節點篩選

開啟節點篩選後,調度器會根據節點實際負載水位進行篩選。當某節點實際負載超過配置的負載閾值時,調度器會拒絕將Pod調度到該節點上。篩選功能預設不開啟,需要您在組件配置按需修改loadAwareThreshold參數,詳細資料,請參見Kube Scheduler參數配置

重要

若叢集已經開啟了節點自動Auto Scaling,配置負載感知閾值過濾可能會引起非預期的節點擴縮,原因是自動Auto Scaling的擴容是依據Pod是否Pending,而縮容是依據叢集的分配率水位。若您需要同時開啟自動Auto Scaling和負載感知的節點篩選,請結合叢集容量和利用率適當調整配置,詳見啟用節點自動調整

節點排序

負載感知調度考慮CPU和記憶體兩個資源維度。調度器在為節點打分時採用了加權的計算方式,優先選取分數更高的節點參與調度。在組件配置勾選Pod 調度時啟用負載感知的打分能力,開啟後,還可進一步對CPU和記憶體權重支援自訂配置,詳細資料,請參見Kube Scheduler參數配置中的loadAwareResourceWeight

計算公式:((1 - CPU資源使用率) * CPU權重配置 + (1 - 記憶體資源使用率) * 記憶體權重配置)/(CPU權重 + 記憶體權重),其中CPU和記憶體的資源使用率單位為百分比。

資源使用率統計演算法

資源使用率的統計演算法支援多種類型的配置,包括平均值和分位值。預設為近5分鐘的平均值,詳細資料,請參見Kube Scheduler參數配置。此外,記憶體資源維度用量資料排除了Page Cache,因為Page Cache可以被作業系統回收。需要注意的是通過kubectl top node命令查詢時,返回的利用率會包含Page Cache,您可以通過使用阿里雲Prometheus監控查看真實的記憶體用量資訊。

步驟一:開啟負載感知調度

重要

請務必完成ack-koordinator組件的安裝,且版本為1.1.1-ack.1及以上,否則負載感知調度功能無法生效。

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

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

  3. 組件管理頁面,定位Kube Scheduler,然後在Kube Scheduler卡片中單擊配置

  4. 在對話方塊中參考下表按需進行相關配置,然後單擊確定

    下表介紹負載感知調度的主要配置項,關於詳細配置以及各配置依賴的組件版本請參見kube-scheduler自訂調度器參數

    配置項

    類型

    說明

    取值

    樣本值

    loadAwareThreshold

    由資源名resourceName和權重threshold組成的列表。

    對應節點篩選策略,表示資源類型對應的閾值。

    • resourceName:支援cpumemory兩種類型。

    • threshold:[0,100]。

    預設值為空白,即不開啟篩選功能。

    • resourceName:cpu

    • threshold:80

    loadAwareResourceWeight

    由資源名resourceName和權重resourceWeight組成的列表。

    對應節點排序策略,表示資源類型對應的打分權重。需要勾選Pod 調度時啟用負載感知的打分能力

    • resourceName:使用schema進行校正,僅支援cpumemory

    • resourceWeight:整數,取值範圍為[1,100]。

    預設值為cpu=1、memory=1。

    • resourceName:cpu

    • resourceWeight:1

    loadAwareAggregatedUsageAggragationType

    enum

    負載統計值的彙總類型。各類型具體含義為:

    • avg:平均值。

    • p50:50%分位值,即中位元。

    • p90p95p99:分別表示90%、95%、99%分位值。

    • avg

    • p50

    • p90

    • p95

    • p99

    預設值為avg

    p90

    在左側導覽列,單擊叢集資訊,然後在右側頁面單擊基本資料頁簽,等待叢集狀態變為運行中,表示負載感知調度功能開啟成功。

步驟二:驗證負載感知調度

下文以擁有3台4 Core 16 GiB節點的叢集為例進行說明。

  1. 使用如下YAML內容,建立stress-demo.yaml檔案。

    展開查看詳細YAML檔案。

    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: stress-demo
      namespace: default
      labels:
        app: stress-demo
    spec:
      replicas: 1
      selector:
        matchLabels:
          app: stress-demo
      template:
        metadata:
          name: stress-demo
          labels:
            app: stress-demo
        spec:
          containers:
            - args:
                - '--vm'
                - '2'
                - '--vm-bytes'
                - '1600M'
                - '-c'
                - '2'
                - '--vm-hang'
                - '2'
              command:
                - stress
              image: polinux/stress
              imagePullPolicy: Always
              name: stress
              resources:
                limits:
                  cpu: '2'
                  memory: 4Gi
                requests:
                  cpu: '2'
                  memory: 4Gi
          restartPolicy: Always
  2. 執行如下命令,建立Pod。建立完成後,按需提升其中一個節點的負載水位。

    kubectl create -f stress-demo.yaml
    # 預期輸出
    deployment.apps/stress-demo created
  3. 執行如下命令,觀察Pod的狀態,直至開始運行。

    kubectl get pod -o wide

    預期輸出:

    NAME                           READY   STATUS    RESTARTS   AGE   IP           NODE                    NOMINATED NODE   READINESS GATES
    stress-demo-7fdd89cc6b-g****   1/1     Running   0          82s   10.XX.XX.112   cn-beijing.10.XX.XX.112   <none>           <none>

    預期輸出表明,Pod stress-demo-7fdd89cc6b-g****調度在節點cn-beijing.10.XX.XX.112上。

    等待3分鐘左右,確保Pod完成初始化,節點負載水位已完成提升。

  4. 執行如下命令,檢查每個節點的負載。

    kubectl top node

    預期輸出:

    NAME                    CPU(cores)   CPU%   MEMORY(bytes)   MEMORY%
    cn-beijing.10.XX.XX.110   92m          2%     1158Mi          9%
    cn-beijing.10.XX.XX.111   77m          1%     1162Mi          9%
    cn-beijing.10.XX.XX.112   2105m        53%    3594Mi          28%

    預期輸出表明,節點cn-beijing.10.XX.XX.111負載最低,節點cn-beijing.10.XX.XX.112的負載最高,此時叢集已經出現節點負載不均的情況。

  5. 使用以下YAML內容,建立nginx-with-loadaware.yaml檔案。

    展開查看詳細YAML檔案。

    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: nginx-with-loadaware
      namespace: default
      labels:
        app: nginx
    spec:
      replicas: 6
      selector:
        matchLabels:
          app: nginx
      template:
        metadata:
          name: nginx
          labels:
            app: nginx
        spec:
          containers:
          - name: nginx
            image: nginx
            resources:
              limits:
                cpu: 500m
              requests:
                cpu: 500m
  6. 執行如下命令,建立Pod。

    kubectl create -f nginx-with-loadaware.yaml
    # 預期輸出
    deployment/nginx-with-loadawre created
  7. 執行如下命令,查看Pod調度詳情。

    kubectl get pods | grep nginx

    預期輸出:

    nginx-with-loadaware-5646666d56-2****   1/1     Running   0          18s   10.XX.XX.118   cn-beijing.10.XX.XX.110   <none>           <none>
    nginx-with-loadaware-5646666d56-7****   1/1     Running   0          18s   10.XX.XX.115   cn-beijing.10.XX.XX.110   <none>           <none>
    nginx-with-loadaware-5646666d56-k****   1/1     Running   0          18s   10.XX.XX.119   cn-beijing.10.XX.XX.110   <none>           <none>
    nginx-with-loadaware-5646666d56-q****   1/1     Running   0          18s   10.XX.XX.113   cn-beijing.10.XX.XX.111   <none>           <none>
    nginx-with-loadaware-5646666d56-s****   1/1     Running   0          18s   10.XX.XX.120   cn-beijing.10.XX.XX.111   <none>           <none>
    nginx-with-loadaware-5646666d56-z****   1/1     Running   0          18s   10.XX.XX.116   cn-beijing.10.XX.XX.111   <none>           <none>

    預期輸出表明,叢集開啟負載感知調度功能後,能感知節點負載,通過運用調度策略將Pod優先調度到除cn-beijing.10.XX.XX.112以外的節點上。

相關操作

修改負載感知調度配置

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

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

  3. 組件管理頁面,尋找Kube Scheduler,然後在Kube Scheduler卡片中單擊配置

  4. Kube Scheduler 參數配置對話方塊,修改負載感知調度的相關配置參數,單擊確定

    在左側導覽列,單擊叢集資訊,然後在右側頁面單擊基本資料頁簽,等待叢集狀態變為運行中,表示更新完成。

關閉負載感知調度

Kube Scheduler 參數配置對話方塊,取消選中Pod 調度時啟用負載感知的打分能力,並刪除loadAwareResourceWeightloadAwareThreshold參數,單擊確定

在左側導覽列,單擊叢集資訊,然後在右側頁面單擊基本資料頁簽,等待叢集狀態變為運行中,表示更新完成。

常見問題

對於一批新建立的Pod,為什麼沒有全部調度到負載最低的節點?

如果調度器將一批新建立的Pod全部調度到當前負載最低的節點,那麼這個節點反而可能很快就會成為負載熱點,這是因為新Pod在啟動後會增加節點的負載。

因此,負載感知調度外掛程式在計算節點打分時,若節點中有利用率還未上報的新Pod,會對打分結果進行適當調整,避免過量調度而產生新的熱點。

除了節點負載水位,還有哪些因素會影響調度結果?

K8s調度器由多個外掛程式組成,在調度過程中很多外掛程式都會參與到節點排序的打分計算,例如親和性外掛程式、拓撲分布外掛程式,節點的最終排序會受這些外掛程式共同影響,您可以根據實際情況,按需調整各外掛程式的打分權重。

調度器升級為新版本後,是否繼續支援已通過舊版本協議使用的負載感知調度功能?

如需使用舊版本的負載感知調度功能,需為Pod添加Annotation alibabacloud.com/loadAwareScheduleEnabled: "true"

ACK調度器相容舊版本協議,您可無縫升級至新版本。升級後,建議您通過步驟一:開啟負載感知調度為調度器開啟全域的負載平衡調度策略,以減少對Pod配置的改動。

重要

ACK調度器在1.22版本將持續保持對舊版本協議的相容,在1.24版本的相容期限截止至2023年08月30日。建議您升級叢集版本,並使用新版本的負載感知調度功能配置方式。關於叢集升級,請參見手動升級叢集

各版本協議的支援情況和組件版本具體要求如下。

1.26及以上

ACK調度器版本

ack-koordinator(ack-slo-manager)版本要求

Pod Annotation協議

控制台參數配置開關

所有ACK調度器版本

≥1.1.1-ack.1

不支援

支援

1.24

ACK調度器版本

ack-koordinator(ack-slo-manager)版本要求

Pod Annotation協議

控制台參數配置開關

≥v1.24.6-ack-4.0

≥1.1.1-ack.1

支援

支援

≥v1.24.6-ack-3.1且<v1.24.6-ack-4.0

≥0.8.0

支援

不支援

1.22及以下

ACK調度器版本

ack-koordinator(ack-slo-manager)版本要求

Pod Annotation協議

控制台參數配置開關

≥1.22.15-ack-4.0

≥1.1.1-ack.1

支援

支援

≥1.22.15-ack-2.0且<1.22.15-ack-4.0

≥0.8.0

支援

不支援

  • ≥v1.20.4-ack-4.0且≤v1.20.4-ack-8.0

  • v1.18-ack-4.0

≥0.3.0且<0.8.0

支援

不支援