全部產品
Search
文件中心

Container Service for Kubernetes:CPU拓撲感知調度

更新時間:Oct 25, 2024

在同一節點上同時運行多個Pod時,Pod之間可能會因為CPU資源的爭搶帶來頻繁的環境切換,導致效能抖動。針對效能敏感型應用,您可以啟用CPU拓撲感知調度功能,將Pod固定在節點的CPU Core上運行,緩解因CPU環境切換、跨NUMA訪存導致的應用效能下降問題。

說明

為了協助您更好地理解本文檔並使用本功能,推薦您參見Kubernetes官方文檔瞭解Pod Qos類為容器和 Pod 分配記憶體資源節點上的CPU管理原則(例如CPU管理原則none策略、static策略)等概念。

使用情境

在Kubernetes叢集中,多個Pod會在同一個節點上共用CPU核心。但在以下情境中,某些應用可能需要固定在部分CPU核心上運行。

  • 應用尚未完成對雲原生情境的適配,例如在設定線程數量時未考慮容器規格(而是整機物理核心數量),導致應用出現效能下降問題。

  • 應用運行在神龍裸金屬(Intel、AMD)等多核機器上,且出現大量因跨NUMA訪存帶來的應用效能下降問題。

  • 應用對CPU環境切換十分敏感,無法承受因此帶來的效能抖動。

雖然Kubernetes提供了CPU Manager以解決此問題,支援為對CPU親和性和效能有更高要求的應用配置static策略,允許這些應用獨佔節點上的特定CPU Core,以獲得穩定的計算資源。但CPU Manager僅提供節點維度CPU調度選擇,無法在叢集維度選擇最優的CPU Core組合。此外,通過CPU Manager為應用配置static策略時,Pod僅支援對Guaranteed類型的Pod生效,即Pod中的每個容器必須聲明了CPU Request和CPU Limit且兩者取值相等,無法適用於其他類型的Pod,包括Burstable和BestEffort。

為此,ACK叢集基於新版的Scheduling Framework實現了CPU拓撲感知調度功能,支援通過Pod Annotation直接啟用,以更好地保障CPU敏感型工作負載的服務效能。

前提條件

  • 已建立ACK叢集Pro版,且節點池的CPU Policy為None,請參見建立ACK Pro版叢集

  • 已安裝ack-koordinator組件,且組件版本為0.2.0及以上,請參見ack-koordinator

費用說明

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

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

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

步驟一:部署樣本應用

本文以一個Nginx應用為例,介紹如何啟用CPU拓撲感知調度,實現CPU綁核。

  1. 使用以下YAML樣本,部署一個Nginx應用。

    展開查看YAML檔案內容

    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: nginx-deployment
      labels:
        app: nginx
    spec:
      replicas: 2
      selector:
        matchLabels:
          app: nginx
      template:
        metadata:
          labels:
            app: nginx
        spec:
          nodeSelector:
            policy: intel
          containers:
          - name: nginx
            image: alibaba-cloud-linux-3-registry.cn-hangzhou.cr.aliyuncs.com/alinux3/nginx_optimized:20240221-1.20.1-2.3.0
            ports:
            - containerPort: 80
            resources:
              requests:
                cpu: 4
                memory: 8Gi
              limits:
                cpu: 4
                memory: 8Gi
            volumeMounts:
               - mountPath: /etc/nginx/nginx.conf
                 name: nginx
                 subPath: nginx.conf
          volumes:
            - name: nginx
              configMap:
                name: nginx-configmap
                items:
                  - key: nginx_conf
                    path: nginx.conf
  2. 在Pod對應的節點上,執行以下命令,查看當前容器的CPU核心綁定情況。

    # 具體路徑可根據Pod的UID以及Container的ID拼接得到。
    cat /sys/fs/cgroup/cpuset/kubepods.slice/kubepods-burstable.slice/kubepods-burstable-podf9b79bee_eb2a_4b67_befe_51c270f8****.slice/cri-containerd-aba883f8b3ae696e99c3a920a578e3649fa957c51522f3fb00ca943dc2c7****.scope/cpuset.cpus

    預期輸出:

    # 未指定自動綁核策略前,可使用的CPU編號範圍為0~31,表示CPU目前沒有約束。
    0-31

步驟二:啟用CPU拓撲感知調度功能

您可以通過Pod Annotation啟用CPU拓撲感知調度功能,實現對Pod的綁核,具體策略如下。

重要

在使用CPU拓撲感知調度時,請勿在Pod上直接指定nodeNamekube-scheduler並不參與這類Pod的調度過程。您可以使用nodeSelector等欄位配置親和性策略,來指定節點調度。

普通綁核策略

您可以通過Pod Annotation cpuset-scheduler啟用CPU拓撲感知調度功能,系統會為您實現CPU綁核。

  1. 在Pod YAML的metadata.annotations中,配置cpuset-schedulertrue,啟用CPU拓撲感知調度。

    說明

    如需在工作負載(例如Deployment)中配置,請在template.metadata欄位下配置Pod對應的Annotation。

  2. Containers欄位下,配置resources.limit.cpu的取值(該值需為整數),限定CPU綁核範圍。


展開查看啟用了普通綁核策略的樣本YAML

apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx-deployment
  labels:
    app: nginx
spec:
  replicas: 2
  selector:
    matchLabels:
      app: nginx
  template:
    metadata:
      annotations:
        cpuset-scheduler: "true" # 設定為true,啟用CPU拓撲感知調度。
      labels:
        app: nginx
    spec:
      nodeSelector:
        policy: intel
      containers:
      - name: nginx
        image: alibaba-cloud-linux-3-registry.cn-hangzhou.cr.aliyuncs.com/alinux3/nginx_optimized:20240221-1.20.1-2.3.0
        ports:
        - containerPort: 80
        resources:
          requests:
            cpu: 4
            memory: 8Gi
          limits:
            cpu: 4 # 設定resources.limit.cpu值,需為整數。
            memory: 8Gi
        volumeMounts:
           - mountPath: /etc/nginx/nginx.conf
             name: nginx
             subPath: nginx.conf
      volumes:
        - name: nginx
          configMap:
            name: nginx-configmap
            items:
              - key: nginx_conf
                path: nginx.conf

自動綁核策略

您可以通過Annotation開啟CPU拓撲感知調度功能並同步啟用自動綁核策略。配置後,調度器會根據Pod規格自動規劃綁核心數量,盡量避免出現跨NUMA訪問記憶體的情況。

  1. 在Pod YAML的metadata.annotations中,配置cpuset-schedulertrue,且cpu-policystatic-burst,啟用自動綁核策略。

    說明

    如需在工作負載(例如Deployment)中配置,請在template.metadata欄位下配置Pod對應的Annotation。

  2. Containers欄位下,配置resources.limit.cpu的取值(該值需為整數),做為CPU綁核範圍的參考值。


展開查看啟用了自動綁核策略的樣本YAML

apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx-deployment
  labels:
    app: nginx
spec:
  replicas: 2
  selector:
    matchLabels:
      app: nginx
  template:
    metadata:
      annotations:
        cpuset-scheduler: "true" # 設定為true,啟用CPU拓撲感知調度。
        cpu-policy: "static-burst" # 設定為static-burst,啟用自動綁核策略。
      labels:
        app: nginx
    spec:
      nodeSelector:
        policy: intel
      containers:
      - name: nginx
        image: alibaba-cloud-linux-3-registry.cn-hangzhou.cr.aliyuncs.com/alinux3/nginx_optimized:20240221-1.20.1-2.3.0
        ports:
        - containerPort: 80
        resources:
          requests:
            cpu: 4
            memory: 8Gi
          limits:
            cpu: 4 # 做為CPU綁核範圍的參考值,需為整數。
            memory: 8Gi
        volumeMounts:
           - mountPath: /etc/nginx/nginx.conf
             name: nginx
             subPath: nginx.conf
      volumes:
        - name: nginx
          configMap:
            name: nginx-configmap
            items:
              - key: nginx_conf
                path: nginx.conf

結果驗證

以普通綁核策略為例,驗證CPU拓撲感知調度是否成功啟用。自動綁核策略的驗證流程類似。

在Pod對應的節點上,再次執行以下命令,查看啟用自動綁核策略後容器的CPU核心綁定情況。

# 具體路徑可根據Pod的UID以及Container的ID拼接得到。
cat /sys/fs/cgroup/cpuset/kubepods.slice/kubepods-burstable.slice/kubepods-burstable-podf9b79bee_eb2a_4b67_befe_51c270f8****.slice/cri-containerd-aba883f8b3ae696e99c3a920a578e3649fa957c51522f3fb00ca943dc2c7****.scope/cpuset.cpus

預期輸出:

# 和limit數量相同
0-3

預期輸出表明,容器可用的CPU編號範圍為0~3,與YAML中聲明的resources.limit.cpu一致。

相關文檔

  • Kubernetes對節點的GPU拓撲資訊不感知,調度過程中對GPU的選擇比較隨機,選擇不同的GPU組合訓練速度會存在較大的差異。推薦您啟用GPU拓撲感知調度,在節點的GPU組合中選擇具有最優訓練速度的組合,請參見GPU拓撲感知調度

  • 您可以將叢集中已指派但未使用的資源量化並提供給低優先順序任務使用,以實現對叢集資源的超賣,請參見啟用動態資源超賣