すべてのプロダクト
Search
ドキュメントセンター

Container Service for Kubernetes:トポロジ対応CPUスケジューリング

最終更新日:Nov 17, 2024

複数のポッドが同じノードで実行されると、ポッドはCPUリソースを求めて競合します。 各ポッドに割り当てられているCPUコアが頻繁に変更され、パフォーマンスのジッターが発生する場合があります。 パフォーマンスに敏感なアプリケーションでは、トポロジ対応のCPUスケジューリング機能を有効にして、ポッドをノードのCPUコアにピン留めできます。 このアプローチにより、CPUコンテキストの切り替えとNUMA (Non-Uniform memory access) ノード間のメモリアクセスによって引き起こされるパフォーマンスの問題が軽減されます。

説明

この機能をよりよく理解して使用するには、Kubernetesの公式ドキュメントを参照して、ポッドQoSクラスコンテナーとポッドへのメモリリソースの割り当て、およびCPU管理ポリシーnoneポリシー、staticポリシーなどのCPU管理ポリシーを確認することを推奨します。

シナリオ

Kubernetesクラスターでは、複数のポッドが同じノード上のCPUコアを共有する場合があります。 ただし、次のシナリオでは、一部のアプリケーションを特定のCPUコアに固定する必要がある場合があります。

  • クラウドネイティブシナリオに適合していないアプリケーション。 たとえば、スレッドの数は、コンテナの仕様ではなく、デバイスの総物理コアに基づいて指定されます。 その結果、アプリケーションのパフォーマンスが低下する。

  • Intel CPUまたはAMD CPUを搭載したマルチコアECS Bare Metalインスタンスで動作し、NUMAノード間のメモリアクセスによりパフォーマンスが低下するアプリケーション。

  • CPUコンテキストの切り替えに非常に敏感で、パフォーマンスのジッターを許容できないアプリケーション。

これらの懸念に対処するために、ACKはKubernetesの新しいスケジューリングフレームワークに基づくトポロジ対応のCPUスケジューリングをサポートします。これは、ポッド注釈を使用してCPU依存ワークロードのサービスパフォーマンスを最適化することができます。

トポロジ対応のCPUスケジューリングは、Kubernetesが提供するCPU Managerの制限を克服します。 CPU Managerは、高いCPUアフィニティとパフォーマンス要件を持つアプリケーションの静的ポリシーを構成することで、これらの問題を解決します。 これにより、これらのアプリケーションはノード上の特定のCPUコアのみを使用して、安定したコンピューティングリソースを確保できます。 ただし、CPU ManagerはノードレベルのCPUスケジューリングソリューションのみを提供し、クラスターレベルで複数のCPUコアを割り当てる最適な方法を見つけることはできません。 さらに、CPUマネージャーを使用して静的ポリシーを構成すると、保証ポッドにのみ影響し、バースト可能ポッドやBestEffortポッドなどの他のポッドタイプには適用されません。 Guaranteedポッドでは、各コンテナーはCPU要求とCPU制限の両方で構成され、これらの値は同じに設定されます。

前提条件

  • ACK Proクラスターが作成され、ノードプールのCPUポリシーがNoneに設定されています。 詳細については、「ACK Proクラスターの作成」をご参照ください。

  • ack-koordinatorコンポーネントがインストールされており、コンポーネントのバージョンは0.2.0以降です。 詳細については、「ack-koordinator」をご参照ください。

課金ルール

ack-koordinatorコンポーネントをインストールして使用する場合、料金はかかりません。 ただし、次のシナリオでは料金が請求される場合があります。

  • ack-koordinatorは、インストール後にワーカーノードリソースを占有する管理対象外のコンポーネントです。 コンポーネントのインストール時に、各モジュールが要求するリソースの量を指定できます。

  • 既定では、ack-koordinatorは、リソースプロファイリングやきめ細かいスケジューリングなどの機能のモニタリングメトリックをPrometheusメトリックとして公開します。 ack-koordinatorのPrometheusメトリクスを有効にし、PrometheusのManaged Serviceを使用する場合、これらのメトリクスはカスタムメトリクスと見なされ、料金が課金されます。 料金は、クラスターのサイズやアプリケーションの数などの要因によって異なります。 Prometheusメトリクスを有効にする前に、Prometheusのマネージドサービスの課金概要トピックを読んで、カスタムメトリクスの無料クォータと課金ルールについて確認することをお勧めします。 リソース使用量を監視および管理する方法の詳細については、「リソース使用量と請求書」をご参照ください。

手順

このトピックでは、例としてNGINXアプリケーションを使用して、トポロジ対応のCPUスケジューリングを有効にしてプロセッサアフィニティを実現する方法を示します。

手順1: サンプルアプリケーションのデプロイ

  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. ポッドがデプロイされているノードで、次のコマンドを実行して、コンテナにバインドされているCPUコアを表示します。

    # The path can be obtained by concatenating the pod UID and the 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

    期待される出力:

    # The output shows that the serial numbers of the CPU cores that can be used by the container range from 0 to 31 before you bind CPU cores to the container.
    0-31

手順2: トポロジ対応CPUスケジューリングの有効化

ポッドアノテーションを使用してトポロジ対応のCPUスケジューリングを有効にし、プロセッサアフィニティを実現できます。

重要

トポロジ対応のCPUスケジューリングを使用する場合は、ポッドにnodeNameを指定しないでください。 kube-schedulerは、このようなポッドのスケジューリングプロセスには関与しません。 nodeSelectorなどのフィールドを使用して、ノードスケジューリングを指定するアフィニティポリシーを設定できます。

標準CPUコアバインディング

ポッド注釈cpuset-schedulerを使用してトポロジ対応のCPUスケジューリングを有効にすると、システムはプロセッサアフィニティを実装します。

  1. ポッドYAMLファイルのmetadata.annotationsで、cpuset-schedulertrueに設定して、トポロジ対応のCPUスケジューリングを有効にします。

    説明

    デプロイなどのワークロードに構成を適用するには、template.metadataフィールドでポッドに適切なアノテーションを設定します。

  2. [コンテナー] フィールドで、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" # Set to true to enable topology-aware CPU scheduling.
      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 # Set the value of resources.limit.cpu, which must be an integer.
            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コアバインディング

アノテーションを使用して、トポロジ対応のCPUスケジューリングと自動CPUコアバインディングポリシーを同時に有効にできます。 設定後、スケジューラは、ポッドの仕様に基づいてバインドされたCPUコアの数を自動的に決定し、交差NUMAメモリアクセスを回避しようとします。

  1. ポッドYAMLファイルのmetadata.annotationsで、cpuset-schedulertrueに、cpu-policystatic-burstに設定して、自動CPUコアバインディングを有効にします。

    説明

    デプロイなどのワークロードに構成を適用するには、template.metadataフィールドでポッドに適切なアノテーションを設定します。

  2. [コンテナー] フィールドで、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" # Set to true to enable topology-aware CPU scheduling.
        cpu-policy: "static-burst" # Set to static-burst to enable automatic CPU core binding.
      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 # Used as a reference value for the CPU core limit, must be an integer.
            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スケジューリングが正常に有効になっているかどうかを確認するには、標準のCPUコアバインディングを例にします。 自動CPUコアバインディングの検証プロセスも同様です。

ポッドがデプロイされているノードで、自動CPUコアバインドを有効にした後、次のコマンドを実行して、コンテナーにバインドされているCPUコアを表示します。

# The path can be obtained by concatenating the Pod UID and the 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

期待される出力:

# The output is the same as the limit.
0-3

予想される出力は、コンテナが使用できるCPUコアのシリアル番号が0から3の範囲であることを示しています。 使用可能なCPUコアの数は、YAMLファイルで宣言されたresources.limit.cpuと一致しています。

関連ドキュメント

  • Kubernetesは、ノード上のGPUリソースのトポロジを認識していません。 したがって、Kubernetes による GPU リソースのスケジューリングはランダムな方法で行われます。 その結果、トレーニングジョブのGPUアクセラレーションは、GPUリソースのスケジューリング結果に基づいて大きく異なります。 トレーニングジョブに最適なGPUアクセラレーションを実現するには、トポロジ対応のGPUスケジューリングを有効にすることを推奨します。 詳細については、「トポロジ対応のGPUスケジューリング」をご参照ください。

  • ポッドに割り当てられているが使用されていないリソースを定量化し、これらのリソースを優先度の低いジョブにスケジュールして、リソースのオーバーコミットメントを実現できます。 詳細については、「動的リソースのオーバーコミットメントの有効化」をご参照ください。