Azure Kubernetes Service (AKS) でコンピューティングを集中的に使用するワークロードに GPU を使用する

グラフィック処理装置 (GPU) は、グラフィックや視覚化ワークロードなど、コンピューティング処理の負荷が高いワークロードによく使用されます。 AKS では、コンピューティング処理の負荷が高い Kubernetes ワークロードを実行するための GPU 対応 Linux ノード プールがサポートされています。

この記事は、新規および既存の AKS クラスターでスケジュール可能な GPU を使用してノードをプロビジョニングするのに役立ちます。

サポートされている GPU 対応 VM

サポートされている GPU 対応 VM を表示するには、Azure での GPU 最適化済み VM サイズに関する記事を参照してください。 AKS ノード プールには、最小サイズの Standard_NC6s_v3 をお勧めします。 NVv4 シリーズ (AMD GPU に基づく) は、AKS ではサポートされていません。

Note

GPU 対応 VM には、より高い価格が適用され、利用可能なリージョンが限られる特殊なハードウェアが含まれます。 詳細については、価格ツールと利用可能なリージョンを参照してください。

制限事項

  • Azure Linux GPU 対応ノード プールを使用している場合、自動セキュリティ パッチは適用されず、クラスターの既定の動作は "アンマネージド" です。 詳細については、「自動アップグレード」を参照してください。
  • NVadsA10 v5 シリーズは、GPU VHD の推奨 SKU では "ありません"。
  • 既存のノード プールの更新による GPU の追加はサポートされていません。

開始する前に

  • この記事は、AKS クラスターがすでに存在していることを前提としています。 クラスターがない場合は、Azure CLIAzure PowerShell、または Azure portal を使用して作成します。
  • Azure CLI バージョン 2.0.64 以降がインストールされて構成されている必要があります。 バージョンを確認するには、az --version を実行します。 インストールまたはアップグレードする必要がある場合は、Azure CLI のインストールに関するページを参照してください。

クラスターの資格情報を取得する

  • az aks get-credentials コマンドを使用して AKS クラスターの資格情報を取得します。 次のコマンド例では、myResourceGroup リソース グループにある myAKSCluster の資格情報を取得します。

    az aks get-credentials --resource-group myResourceGroup --name myAKSCluster
    

NVIDIA GPU を使用するためのオプション

NVIDIA GPU の使用には、Kubernetes 向け NVIDIA デバイス プラグインなどのさまざまな NVIDIA ソフトウェア コンポーネントのインストールや GPU ドライバーのインストールなどがともないます。

GPU ドライバーのインストールをスキップする (プレビュー)

AKS では、GPU ドライバーの自動インストールが既定で有効になっています。 独自のドライバーをインストールしたり、NVIDIA GPU Operator を使用したりするときは、GPU ドライバーのインストールをスキップすることがあります。

重要

AKS のプレビュー機能は、セルフサービスのオプトイン単位で利用できます。 プレビューは、"現状有姿" および "利用可能な限度" で提供され、サービス レベル アグリーメントおよび限定保証から除外されるものとします。 AKS プレビューは、ベストエフォート ベースでカスタマー サポートによって部分的にカバーされます。 そのため、これらの機能は、運用環境での使用を意図していません。 詳細については、次のサポート記事を参照してください。

  1. az extension add または az extension update コマンドを利用し、aks-preview 拡張機能を登録するか、更新します。

    # Register the aks-preview extension
    az extension add --name aks-preview
    
    # Update the aks-preview extension
    az extension update --name aks-preview
    
  2. az aks nodepool add コマンドを使用して (--skip-gpu-driver-install フラグを指定) ノード プールを作成し、GPU ドライバーの自動インストールをスキップします。

    az aks nodepool add \
        --resource-group myResourceGroup \
        --cluster-name myAKSCluster \
        --name gpunp \
        --node-count 1 \
        --skip-gpu-driver-install \
        --node-vm-size Standard_NC6s_v3 \
        --enable-cluster-autoscaler \
        --min-count 1 \
        --max-count 3
    

    ノード プール作成時に --skip-gpu-driver-install フラグを追加することで、GPU ドライバーの自動インストールがスキップされます。 既存のノードは変更されません。 ノード プールをゼロにスケールしてバックアップすることで変更を適用できます。

NVIDIA デバイス プラグインのインストール

AKS で GPU を使用するとき、NVIDIA デバイス プラグインをインストールする必要があります。 NVIDIA GPU OperatorAKS GPU イメージ (プレビュー) の使用時など、インストールが自動で処理されることもあります。 あるいは、NVIDIA デバイス プラグインを手動でインストールできます。

NVIDIA デバイス プラグインを手動でインストールする

NVIDIA デバイス プラグイン用の DaemonSet をデプロイできます。このプラグインは、各ノードでポッドを実行して、GPU に必要なドライバーを提供します。 これは、Azure Linux に GPU 対応ノード プールを使用する場合に推奨される方法です。

既定の OS SKU を使用するには、OS SKU を指定せずにノード プールを作成します。 ノード プールは、クラスターの Kubernetes バージョンに基づき、既定のオペレーティング システムに対して設定されます。

  1. az aks nodepool add コマンドを使用して、クラスターにノード プールを追加します。

    az aks nodepool add \
        --resource-group myResourceGroup \
        --cluster-name myAKSCluster \
        --name gpunp \
        --node-count 1 \
        --node-vm-size Standard_NC6s_v3 \
        --node-taints sku=gpu:NoSchedule \
        --enable-cluster-autoscaler \
        --min-count 1 \
        --max-count 3
    

    このコマンドでは、gpunp という名前のノード プールを myResourceGroupmyAKSCluster に追加し、パラメーターを使用して次のノード プール設定を構成します。

    • --node-vm-size: ノード プール内のノードの VM サイズを Standard_NC6s_v3 に設定します。
    • --node-taints: ノード プール上の sku=gpu:NoSchedule テイントを指定します。
    • --enable-cluster-autoscaler: クラスターの自動スケーラーを有効にします。
    • --min-count: ノード プール内の少なくとも 1 つのノードを維持するようにクラスター自動スケーラーを構成します。
    • --max-count: ノード プール内の最大 3 つのノードを維持するようにクラスター自動スケーラーを構成します。

    注意

    テイントと VM のサイズは、ノード プールの作成時にのみノード プールに設定できますが、自動スケーラーの設定はいつでも更新できます。

  1. kubectl create namespace コマンドを使って名前空間を作成します。

    kubectl create namespace gpu-resources
    
  2. nvidia-device-plugin-ds.yaml という名前のファイルを作成し、Kubernetes プロジェクトの NVIDIA デバイス プラグインの一部として提供される次の YAML マニフェストを貼り付けます。

    apiVersion: apps/v1
    kind: DaemonSet
    metadata:
      name: nvidia-device-plugin-daemonset
      namespace: gpu-resources
    spec:
      selector:
        matchLabels:
          name: nvidia-device-plugin-ds
      updateStrategy:
        type: RollingUpdate
      template:
        metadata:
          # Mark this pod as a critical add-on; when enabled, the critical add-on scheduler
          # reserves resources for critical add-on pods so that they can be rescheduled after
          # a failure.  This annotation works in tandem with the toleration below.
          annotations:
            scheduler.alpha.kubernetes.io/critical-pod: ""
          labels:
            name: nvidia-device-plugin-ds
        spec:
          tolerations:
          # Allow this pod to be rescheduled while the node is in "critical add-ons only" mode.
          # This, along with the annotation above marks this pod as a critical add-on.
          - key: CriticalAddonsOnly
            operator: Exists
          - key: nvidia.com/gpu
            operator: Exists
            effect: NoSchedule
          - key: "sku"
            operator: "Equal"
            value: "gpu"
            effect: "NoSchedule"
          containers:
          - image: mcr.microsoft.com/oss/nvidia/k8s-device-plugin:v0.14.1
            name: nvidia-device-plugin-ctr
            securityContext:
              allowPrivilegeEscalation: false
              capabilities:
                drop: ["ALL"]
            volumeMounts:
              - name: device-plugin
                mountPath: /var/lib/kubelet/device-plugins
          volumes:
            - name: device-plugin
              hostPath:
                path: /var/lib/kubelet/device-plugins
    
  3. DaemonSet を作成し、kubectl apply コマンドを使って NVIDIA デバイス プラグインが正常に作成されたことを確認します。

    kubectl apply -f nvidia-device-plugin-ds.yaml
    
  4. これで NVIDIA デバイス プラグインが正常にインストールされたので、GPU がスケジュール可能であることを確認したり、GPU ワークロードを実行したりできます。

AKS で NVIDIA GPU オペレーターを使用する

NVIDIA GPU Operator では、ドライバー インストール、Kubernetes 向けの NVIDIA デバイス プラグイン、NVIDIA コンテナー ランタイムなど、GPU のプロビジョニングに必要なあらゆる NVIDIA ソフトウェア コンポーネントの管理が自動化されます。 GPU Operator によってこれらのコンポーネントが処理されるため、NVIDIA デバイス プラグインを手動でインストールする必要がなくなります。 これはまた、AKS に GPU ドライバーを自動インストールする必要がなくなったことを意味します。

  1. az aks nodepool add コマンドと --skip-gpu-driver-install を使用してノード プールを作成することで GPU ドライバーの自動インストールをスキップします。 ノード プール作成時に --skip-gpu-driver-install フラグを追加することで、GPU ドライバーの自動インストールがスキップされます。 既存のノードは変更されません。 ノード プールをゼロにスケールしてバックアップすることで変更を適用できます。

  2. NVIDIA ドキュメントに従い、GPU Operator をインストールします。

  3. これで GPU Operator が正常にインストールされたので、GPU がスケジュール可能であることを確認したり、GPU ワークロードを実行したりできます。

警告

AKS GPU イメージを使用するクラスターで NVIDIA デバイス プラグイン デーモン セットを手動でインストールすることはお勧めしません。

AKS GPU イメージを使用する (プレビュー)

AKS からは、Kubernetes 向け NVIDIA デバイス プラグインが含まれる、完全構成済みの AKS イメージが提供されます。 AKS GPU イメージは現在、Ubuntu 18.04 でのみサポートされています。

重要

AKS のプレビュー機能は、セルフサービスのオプトイン単位で利用できます。 プレビューは、"現状有姿" および "利用可能な限度" で提供され、サービス レベル アグリーメントおよび限定保証から除外されるものとします。 AKS プレビューは、ベストエフォート ベースでカスタマー サポートによって部分的にカバーされます。 そのため、これらの機能は、運用環境での使用を意図していません。 詳細については、次のサポート記事を参照してください。

  1. az extension add コマンドを使って Azure CLI 拡張機能 aks-preview をインストールします。

    az extension add --name aks-preview
    
  2. az extension update コマンドを使って拡張機能の最新バージョンに更新します。

    az extension update --name aks-preview
    
  3. az feature register コマンドを使用して、GPUDedicatedVHDPreview 機能フラグを登録します。

    az feature register --namespace "Microsoft.ContainerService" --name "GPUDedicatedVHDPreview"
    

    状態が [登録済み] と表示されるまでに数分かかります。

  4. az feature show コマンドを使用して、登録の状態を確認します。

    az feature show --namespace "Microsoft.ContainerService" --name "GPUDedicatedVHDPreview"
    
  5. 状態が Registered と表示されたら、az provider register コマンドを使用して Microsoft.ContainerService リソース プロバイダーの登録を最新の情報に更新します。

    az provider register --namespace Microsoft.ContainerService
    

    AKS GPU イメージを使用するようにクラスターを更新したので、GPU ノード用のノード プールをクラスターに追加できます。

  6. az aks nodepool add コマンドを使ってノード プールを追加します。

    az aks nodepool add \
        --resource-group myResourceGroup \
        --cluster-name myAKSCluster \
        --name gpunp \
        --node-count 1 \
        --node-vm-size Standard_NC6s_v3 \
        --node-taints sku=gpu:NoSchedule \
        --aks-custom-headers UseGPUDedicatedVHD=true \
        --enable-cluster-autoscaler \
        --min-count 1 \
        --max-count 3
    

    前のコマンドの例では、gpunp という名前のノード プールを myResourceGroupmyAKSCluster に追加し、パラメーターを使用して次のノード プール設定を構成します。

    • --node-vm-size: ノード プール内のノードの VM サイズを Standard_NC6s_v3 に設定します。
    • --node-taints: ノード プール上の sku=gpu:NoSchedule テイントを指定します。
    • --aks-custom-headers: 特殊な AKS GPU イメージ UseGPUDedicatedVHD=true を指定します。 GPU SKU で第 2 世代の VM が必要な場合は、代わりに --aks-custom-headers UseGPUDedicatedVHD=true,usegen2vm=true を使用します。
    • --enable-cluster-autoscaler: クラスターの自動スケーラーを有効にします。
    • --min-count: ノード プール内の少なくとも 1 つのノードを維持するようにクラスター自動スケーラーを構成します。
    • --max-count: ノード プール内の最大 3 つのノードを維持するようにクラスター自動スケーラーを構成します。

    注意

    テイントと VM のサイズは、ノード プールの作成時にのみノード プールに設定できますが、自動スケーラーの設定はいつでも更新できます。

  7. これで GPU イメージを利用してノード プールが正常に作成されたので、GPU がスケジュール可能であることを確認したり、GPU ワークロードを実行したりできます。

GPU がスケジュール可能であることを確認する

クラスターを作成したら、Kubernetes で GPU がスケジュール可能であることを確認します。

  1. kubectl get nodes コマンドを使用して、クラスター内のノードを一覧表示します。

    kubectl get nodes
    

    出力は次の出力例のようになります。

    NAME                   STATUS   ROLES   AGE   VERSION
    aks-gpunp-28993262-0   Ready    agent   13m   v1.20.7
    
  2. kubectl describe node コマンドを使用して GPU がスケジュール可能であることを確認します。

    kubectl describe node aks-gpunp-28993262-0
    

    Capacity セクションで、GPU は nvidia.com/gpu: 1 と表示されているはずです。 出力は、次の要約された出力例のようになります:

    Name:               aks-gpunp-28993262-0
    Roles:              agent
    Labels:             accelerator=nvidia
    
    [...]
    
    Capacity:
    [...]
     nvidia.com/gpu:                 1
    [...]
    

GPU 対応ワークロードの実行

GPU が機能していることを確認するために、適切なリソース要求を指定して GPU 対応ワークロードをスケジュールできます。 この例では、MNIST データセットに対して Tensorflow ジョブを実行します。

  1. samples-tf-mnist-demo.yaml という名前のファイルを作成し、nvidia.com/gpu: 1 という制限のある次の YAML マニフェストを貼り付けます。

    注意

    ドライバーを呼び出すときに、"CUDA driver version is insufficient for CUDA runtime version" (CUDA ドライバーのバージョンが CUDA ランタイムのバージョンに対して不十分です" などのバージョン不一致エラーが発生した場合は、NVIDIA ドライバーのマトリックス互換性チャートを確認してください。

    apiVersion: batch/v1
    kind: Job
    metadata:
      labels:
        app: samples-tf-mnist-demo
      name: samples-tf-mnist-demo
    spec:
      template:
        metadata:
          labels:
            app: samples-tf-mnist-demo
        spec:
          containers:
          - name: samples-tf-mnist-demo
            image: mcr.microsoft.com/azuredocs/samples-tf-mnist-demo:gpu
            args: ["--max_steps", "500"]
            imagePullPolicy: IfNotPresent
            resources:
              limits:
               nvidia.com/gpu: 1
          restartPolicy: OnFailure
          tolerations:
          - key: "sku"
            operator: "Equal"
            value: "gpu"
            effect: "NoSchedule"
    
  2. kubectl apply コマンドを使用してジョブを実行します。これにより、マニフェスト ファイルが解析され、定義された Kubernetes オブジェクトが作成されます。

    kubectl apply -f samples-tf-mnist-demo.yaml
    

GPU 対応ワークロードの状態を表示する

  1. --watch フラグを指定して kubectl get jobs コマンドを使用し、ジョブの進行状況を監視します。 イメージを最初にプルし、データセットを処理するまで数分かかる可能性があります。

    kubectl get jobs samples-tf-mnist-demo --watch
    

    次の出力例に示すように、COMPLETIONS 列に 1/1 と表示されている場合、ジョブは正常に完了しました。

    NAME                    COMPLETIONS   DURATION   AGE
    
    samples-tf-mnist-demo   0/1           3m29s      3m29s
    samples-tf-mnist-demo   1/1   3m10s   3m36s
    
  2. Ctrl-Ckubectl --watch プロセスを終了します。

  3. kubectl get pods コマンドを使用してポッドの名前を取得します。

    kubectl get pods --selector app=samples-tf-mnist-demo
    
  4. kubectl logs コマンドを使用して、GPU 対応ワークロードの出力を表示します。

    kubectl logs samples-tf-mnist-demo-smnr6
    

    次の要約されたポッド ログの出力例は、適切な GPU デバイス である Tesla K80 が検出されたことを確認します。

    2019-05-16 16:08:31.258328: I tensorflow/core/platform/cpu_feature_guard.cc:137] Your CPU supports instructions that this TensorFlow binary was not compiled to use: SSE4.1 SSE4.2 AVX AVX2 FMA
    2019-05-16 16:08:31.396846: I tensorflow/core/common_runtime/gpu/gpu_device.cc:1030] Found device 0 with properties: 
    name: Tesla K80 major: 3 minor: 7 memoryClockRate(GHz): 0.8235
    pciBusID: 2fd7:00:00.0
    totalMemory: 11.17GiB freeMemory: 11.10GiB
    2019-05-16 16:08:31.396886: I tensorflow/core/common_runtime/gpu/gpu_device.cc:1120] Creating TensorFlow device (/device:GPU:0) -> (device: 0, name: Tesla K80, pci bus id: 2fd7:00:00.0, compute capability: 3.7)
    2019-05-16 16:08:36.076962: I tensorflow/stream_executor/dso_loader.cc:139] successfully opened CUDA library libcupti.so.8.0 locally
    Successfully downloaded train-images-idx3-ubyte.gz 9912422 bytes.
    Extracting /tmp/tensorflow/input_data/train-images-idx3-ubyte.gz
    Successfully downloaded train-labels-idx1-ubyte.gz 28881 bytes.
    Extracting /tmp/tensorflow/input_data/train-labels-idx1-ubyte.gz
    Successfully downloaded t10k-images-idx3-ubyte.gz 1648877 bytes.
    Extracting /tmp/tensorflow/input_data/t10k-images-idx3-ubyte.gz
    Successfully downloaded t10k-labels-idx1-ubyte.gz 4542 bytes.
    Extracting /tmp/tensorflow/input_data/t10k-labels-idx1-ubyte.gz
    Accuracy at step 0: 0.1081
    Accuracy at step 10: 0.7457
    Accuracy at step 20: 0.8233
    Accuracy at step 30: 0.8644
    Accuracy at step 40: 0.8848
    Accuracy at step 50: 0.8889
    Accuracy at step 60: 0.8898
    Accuracy at step 70: 0.8979
    Accuracy at step 80: 0.9087
    Accuracy at step 90: 0.9099
    Adding run metadata for 99
    Accuracy at step 100: 0.9125
    Accuracy at step 110: 0.9184
    Accuracy at step 120: 0.922
    Accuracy at step 130: 0.9161
    Accuracy at step 140: 0.9219
    Accuracy at step 150: 0.9151
    Accuracy at step 160: 0.9199
    Accuracy at step 170: 0.9305
    Accuracy at step 180: 0.9251
    Accuracy at step 190: 0.9258
    Adding run metadata for 199
    [...]
    Adding run metadata for 499
    

Container Insights を使用して GPU の使用状況を監視する

AKS を使用したコンテナーの分析情報では、次の GPU 使用状況メトリックが監視されます。

メトリックの名前 メトリック ディメンション (タグ) 説明
containerGpuDutyCycle container.azm.ms/clusterIdcontainer.azm.ms/clusterNamecontainerNamegpuIdgpuModelgpuVendor 過去のサンプリング期間 (60 秒) 中に、コンテナーに対して GPU がビジーであるかアクティブに処理を行っていた時間の割合。 デューティ サイクルは 1 から 100 までの値です。
containerGpuLimits container.azm.ms/clusterIdcontainer.azm.ms/clusterNamecontainerName 各コンテナーでは、1 つまたは複数の GPU として制限を指定できます。 GPU の一部を要求または制限することはできません。
containerGpuRequests container.azm.ms/clusterIdcontainer.azm.ms/clusterNamecontainerName 各コンテナーでは、1 つまたは複数の GPU を要求できます。 GPU の一部を要求または制限することはできません。
containerGpumemoryTotalBytes container.azm.ms/clusterIdcontainer.azm.ms/clusterNamecontainerNamegpuIdgpuModelgpuVendor 特定のコンテナーに使用できる GPU メモリの量 (バイト)。
containerGpumemoryUsedBytes container.azm.ms/clusterIdcontainer.azm.ms/clusterNamecontainerNamegpuIdgpuModelgpuVendor 特定のコンテナーに使用された GPU メモリの量 (バイト)。
nodeGpuAllocatable container.azm.ms/clusterIdcontainer.azm.ms/clusterNamegpuVendor Kubernetes で使用できるノード内の GPU の数。
nodeGpuCapacity container.azm.ms/clusterIdcontainer.azm.ms/clusterNamegpuVendor ノード内の GPU の合計数。

リソースをクリーンアップする

  • kubectl delete job コマンドを使用して、この記事で作成した関連する Kubernetes オブジェクトを削除します。

    kubectl delete jobs samples-tf-mnist-demo
    

次のステップ