AKS on Azure Local のコンピューティング集中型ワークロードに GPU を使用してマルチラックデプロイを行う

この記事では、Azure Local のマルチラック展開環境において、Azure Arc 対応 AKS で GPU 対応ノード プールをデプロイおよび構成する方法について説明します。 グラフィカル処理ユニット (GPU) は、機械学習、ディープ ラーニング、AI 推論などのコンピューティング集中型ワークロードに役立ちます。

Azure Local プラットフォームは、vfio-pci PCI パススルーを使用して個別のデバイス割り当て (DDA) を使用して、物理 GPU を AKS Arc worker 仮想マシン (VM) に公開します。 AKS Arc クラスター内のワークロードは、デバイスに対して直接実行できます。

サポートされている GPU モデルと VM サイズ

マルチラック展開用の AKS on Azure Localでは、次の GPU ハードウェアと SKU がサポートされています。

GPU モデル サポートされている VM サイズ vCPU メモリ (GiB) VM あたりの GPU 数
NVIDIA RTX Pro 6000 Blackwell (96 GiB) Standard_NC16_RTX6000Pro_1 16 64 1
NVIDIA RTX Pro 6000 Blackwell (96 GiB) Standard_NC32_RTX6000Pro_1 32 128 1

Note

マルチ GPU SKU ( Standard_NC16_RTX6000Pro_2Standard_NC32_RTX6000Pro_2など) はカタログに存在しますが、まだ一般公開されていません。

始める前の準備

GPU 対応ノード プールを作成するには、次の要件が満たされていることを確認します。

  • マルチラック展開用のAzure Local クラスターがデプロイされ、Azure Arcに登録されます。詳細については、マルチラック展開の概要を参照してください。

  • Azure Local クラスターのカスタムの場所に、使用可能な NVIDIA RTX Pro 6000 GPU を備えた物理コンピューティング ノードがあることを確認します。 Azure Local管理者は、コンピューティング ロール ノード上のnvidia.com/nvidia-rtx-pro-6000 リソースについてプラットフォーム クラスターにクエリを実行することで、管理ノードからこれを確認できます。

    kubectl get nodes -l platform.afo-nc.microsoft.com/role=compute -o json \
      | jq -r '.items[] | .metadata.name as $n
               | .status.allocatable | to_entries[]
               | select(.key | test("nvidia|gpu|vfio"; "i"))
               | "\($n)\t\(.key) = \(.value)"'
    

    出力には、各コンピューティング ノードとその割り当て可能な GPU 関連リソースが一覧表示されます。次に例を示します。

    nvidia.com/gpu_vfio = 0
    nvidia.com/nvidia-rtx-pro-6000 = 2
    nvidia.com/gpu_vfio = 0
    nvidia.com/nvidia-rtx-pro-6000 = 2
    

    少なくとも 1 つのコンピューティング ノードが 0 以外の nvidia.com/nvidia-rtx-pro-6000 値を報告する必要があり、コンピューティング ノード間の合計は、手順 2 で要求する予定の --node-count 以上である必要があります。 ノードが表示されない場合、またはすべての値が0場合は、先に進む前に管理者またはMicrosoft サポートに問い合わせてください。

  • 最新バージョンのAzure CLIaksarc拡張機能をインストールします。

  • NVIDIA ソフトウェアへの送信アクセスを有効にする前に、テナント プロキシまたは論理ネットワーク接続を構成します。 BYO プロキシの手順については、Azure Local のマルチラック上の AKS に BYO プロキシを追加する方法を参照してください。

  • クラスター作成時に、AKS Arc クラスターが SSH キーを使用して作成され、これらの SSH キーにアクセスできることを確認します。 この記事の手順 3 と 4 では、NVIDIA ドライバーが正しくインストールされていることを確認し、NVIDIA Container Toolkit をインストールするために、各 GPU ワーカー VM への SSH アクセスが必要です。 SSH キーは、クラスターの作成時にのみ構成できます。

Note

NVIDIA ドライバーはワーカー VM イメージにプレインストールされているため、手動でインストールする必要はありません。 GPU がポッド スペックから nvidia.com/gpu スケジュール可能になるように、NVIDIA Container Toolkit と NVIDIA Kubernetes デバイス プラグインをインストールする必要があります。 手順 3 では、プレインストールされているドライバーを確認し、手順 4 と 5 で残りのコンポーネントをインストールし、手順 6 ではポッド ワークロードでエンド ツー エンドを検証します。

手順 1: 使用可能な GPU 対応 VM サイズを一覧表示する

Azure Local クラスターをデプロイした後、GPU 対応 SKU がカスタムの場所に表示されていることを確認します。

az aksarc vmsize list --custom-location <custom location ID> --resource-group <resource group name> --output table

このリリースの場合、出力には Standard_NC*_RTX6000Pro_* SKU が含まれます。

手順 2: GPU 対応ノード プールを使用してクラスターを作成する

AKS Arc クラスターに GPU ノード プールを追加します。 コントロール プレーンとシステム ノード プールでは、標準の GPU 以外の VM サイズが使用されます。 GPU SKU は、ワークロードを実行するユーザー ノード プール専用です。

Important

初期 (システム) ノード プールとして GPU 対応 SKU を持つ AKS Arc クラスターを作成することはできません。 最初に、GPU 以外の標準の VM サイズでクラスターを作成してから、GPU 対応のユーザー ノード プールを追加する必要があります。

  1. (GPU ノード プールを使用せずに) AKS Arc クラスターを作成します。 詳細な手順とパラメーターのガイダンスについては、Azure CLIを使用した Kubernetes クラスターの作成に関する記事を参照してください。

  2. GPU 対応の Linux ノード プールを追加します。 次の例では、 Standard_NC16_RTX6000Pro_1 VM の 2 ノード プール (ノードあたり 1 つの NVIDIA RTX Pro 6000 GPU) を追加します。

    az aksarc nodepool add \
      --cluster-name <aks cluster name> \
      --resource-group <resource group name> \
      --name <nodepool name> \
      --node-count <node count> \
      --node-vm-size Standard_NC16_RTX6000Pro_1 \
      --os-type Linux
    

    プラットフォームは、コマンドの実行時に GPU 容量を検証します。 クラスターに、要求されたノード数をバックアップするための十分な物理 GPU がない場合、コマンドは失敗します。

  3. (省略可能)Azure Arc プロキシを使用してクラスターに接続します。

    az connectedk8s proxy --name <aks cluster name> --resource-group <resource group name>
    

手順 3: ワーカー VM 内の NVIDIA ドライバーを確認する

Azure Local プラットフォームは、PCI パススルーを介してワーカー VM に物理 GPU を配信します。 ワーカー VM は Linux 3 Azure実行され、NVIDIA ドライバー (Blackwell アーキテクチャに必要なオープン カーネル モジュールを含むMicrosoft署名されたcuda-open パッケージ) がワーカー VM イメージにプレインストールされています。 ドライバーを手動でインストールする必要はありません。 このセクションの手順を使用して、GPU とドライバーが存在することを確認します。

GPU ノード プール内の各ワーカー VM で、このセクションの検証手順を実行します。 ゲスト内シェルを開くには、SSH を使用します (SSH を使用した Windows または Linux ワーカー ノードへの接続を参照)。

  1. GPU デバイスがゲストに表示されていることを確認します。

    lspci -nn | grep -i nvidia
    

    次のようなものが予想されます。

    0e:00.0 3D controller [0302]: NVIDIA Corporation Device [10de:2bb5] (rev a1)
    
  2. ドライバーが読み込まれ、GPU を検出できることを確認します。 ドライバーが必要な/dev/nvidia*デバイス ノードを作成できるように、最初のnvidia-smi呼び出しをルートとして実行する必要があります。 最初の実行後は、昇格された特権なしで nvidia-smi を使用できます。

    lsmod | grep '^nvidia'
    sudo nvidia-smi
    

    sudo nvidia-smiからの正常な出力には、インストールされているドライバーバージョンの NVIDIA RTX Pro 6000 が表示され、プレインストールされているドライバーが動作していることを確認します。 アイドル状態の GPU ワーカー VM では、出力は次のようになります。

    +-----------------------------------------------------------------------------------------+
    | NVIDIA-SMI 580.105.08             Driver Version: 580.105.08     CUDA Version: 13.0     |
    +-----------------------------------------+------------------------+----------------------+
    | GPU  Name                 Persistence-M | Bus-Id          Disp.A | Volatile Uncorr. ECC |
    | Fan  Temp   Perf          Pwr:Usage/Cap |           Memory-Usage | GPU-Util  Compute M. |
    |                                         |                        |               MIG M. |
    |=========================================+========================+======================|
    |   0  NVIDIA RTX PRO 6000 Blac...    Off |   00000000:0E:00.0 Off |                    0 |
    | N/A   24C    P0             55W /  600W |       0MiB /  97887MiB |      3%      Default |
    |                                         |                        |             Disabled |
    +-----------------------------------------+------------------------+----------------------+
    
    +-----------------------------------------------------------------------------------------+
    | Processes:                                                                              |
    |  GPU   GI   CI              PID   Type   Process name                        GPU Memory |
    |        ID   ID                                                               Usage      |
    |=========================================================================================|
    |  No running processes found                                                             |
    +-----------------------------------------------------------------------------------------+
    

    lsmod nvidiaモジュールが表示されない場合は、手動で読み込み、nvidia-smi再実行します。

    sudo modprobe nvidia
    sudo modprobe nvidia_uvm
    sudo modprobe nvidia_drm
    

手順 4: 各 GPU ワーカー VM に NVIDIA Container Toolkit をインストールする

ドライバーはワーカー VM のホスト OS から GPU を使用できるようにしますが、コンテナーには、 /dev/nvidia* と一致するユーザー空間ライブラリ (libcuda.solibnvidia-ml.so) を確認するためのランタイム フックが必要です。 nvidia-container-toolkit パッケージは、そのフックを提供し、containerdに登録します。

nvidia-container-toolkit パッケージはpackages.microsoft.comからインストールされるため、ワーカー VM には送信 HTTPS アクセスが必要です。 環境で送信トラフィックに HTTPS プロキシが必要な場合は、インストールする前に使用するように tdnf を構成します。 <proxy-url>を、packages.microsoft.comへのアクセスが許可されているプロキシに置き換えます。

echo 'proxy=<proxy-url>' | sudo tee -a /etc/tdnf/tdnf.conf

Note

tdnf は、 /etc/tdnf/tdnf.confからプロキシを読み取ります。 ワーカー VM 上の今後のパッケージの更新には、同じプロキシが必要です。

各 GPU ワーカー VM で実行します。

sudo tdnf install -y nvidia-container-toolkit
sudo nvidia-ctk runtime configure --runtime=containerd --set-as-default
sudo systemctl restart containerd

パッケージがインストールされていることと、 nvidia ランタイムが containerdに登録されていることを確認します。

rpm -q nvidia-container-toolkit
grep -A3 'runtimes.nvidia' /etc/containerd/config.toml

grep コマンドは、[plugins."io.containerd.grpc.v1.cri".containerd.runtimes.nvidia]runtime_type であり、io.containerd.runc.v2BinaryName を指している /usr/bin/nvidia-container-runtime ブロックを出力する必要があります。 ブロックがない場合は、 sudo nvidia-ctk runtime configure --runtime=containerd --set-as-default 再実行し、 containerdを再起動します。

手順 5: AKS Arc クラスターに NVIDIA Kubernetes デバイス プラグインをインストールする

デバイス プラグインは、 リソースとして GPU を AKS Arc クラスターのスケジューラにアドバタイズします。 これがないと、nvidia.com/gpu: 1 を要求するポッドは Pending のままになります。

次のマニフェストでは、Microsoft Container Registry (MCR) にミラー化されたデバイス プラグイン イメージを使用します。 GitHubやNvidiaのウェブサイトでも見つけることができます。

  1. az connectedk8s proxyを使用して AKS Arc クラスターに接続します。 詳細なガイダンスについては、「 クラスターへの接続」を参照してください。 --file オプションを使用して、専用の kubeconfig (たとえば、./<aks cluster name>.kubeconfig) を記述し、プロキシを実行したままにし、残りの手順のために 2 番目のターミナルのその kubeconfig でkubectlをポイントします。

  2. 次のマニフェストを nvidia-device-plugin.yaml として保存します。

    apiVersion: apps/v1
    kind: DaemonSet
    metadata:
      name: nvidia-device-plugin-daemonset
      namespace: kube-system
    spec:
      selector:
        matchLabels:
          name: nvidia-device-plugin-ds
      updateStrategy:
        type: RollingUpdate
      template:
        metadata:
          labels:
            name: nvidia-device-plugin-ds
        spec:
          tolerations:
            - key: nvidia.com/gpu
              operator: Exists
              effect: NoSchedule
          priorityClassName: "system-node-critical"
          containers:
            - image: mcr.microsoft.com/oss/v2/nvidia/k8s-device-plugin:v0.19.1
              name: nvidia-device-plugin-ctr
              env:
                - name: FAIL_ON_INIT_ERROR
                  value: "false"
              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. マニフェストを適用します。

    kubectl apply -f nvidia-device-plugin.yaml
    

DaemonSet が実行されており、GPU がアドバタイズされていることを確認します。

kubectl get pods -n kube-system -l name=nvidia-device-plugin-ds -o wide

kubectl get nodes -o jsonpath='{range .items[*]}{.metadata.name}{"\t"}{.status.allocatable.nvidia\.com/gpu}{"\n"}{end}'

GPU 対応ノードは、1の下にnvidia.com/gpuを報告する必要があります。 その場合は、手順 6 に進みます。 GPU の可用性を確認するか、期待される値が表示されない場合は、Microsoft サポートにお問い合わせください。

手順 6: (省略可能) GPU 対応ポッド ワークロードを実行する

GPU が Kubernetes ポッドからエンド ツー エンドで使用可能であることを確認するには、小さな CUDA ワークロードをデプロイし、GPU に対して完了していることを確認します。 この手順は、手順 4 と 5 が完了していること(コンテナー ツールキットがインストールされ、nvidia.com/gpu がノード上で公開されていること)を前提としています。

Note

手順 5 で kubeconfig ファイルを指定したのと同じシェルで、次の kubectl コマンドを実行します。

  1. まず、 kubectl get nodesを使用してクラスター内のノードを一覧表示します。 出力は次の例のようになります。

    NAME             STATUS  ROLES                 AGE   VERSION
    moc-l9qz36vtxzj  Ready   control-plane,master  6m14s  v1.29.0
    moc-lhbkqoncefu  Ready   <none>                3m19s  v1.29.0
    moc-li87udi8l9s  Ready   <none>                3m5s   v1.29.0
    
  2. kubectl describe nodeを使用して、GPU がワーカー ノードでスケジュール可能であることを確認します。 [ 容量 ] セクションでは、GPU は nvidia.com/gpu: 1として表示されます。

    kubectl describe <node> | grep -i gpu
    

    出力にはワーカー ノードの GPU が表示され、次の例のようになります。

    Capacity:
      cpu:                16
      ephemeral-storage:  103110508Ki
      memory:             65536000Ki
      nvidia.com/gpu:     1
      pods:               110
    
  3. 次の内容を含む gpupod.yaml という名前の新しいファイルを作成します。

    apiVersion: v1
    kind: Pod
    metadata:
      name: cuda-vector-add
    spec:
      restartPolicy: OnFailure
      containers:
        - name: cuda-vector-add
          image: "k8s.gcr.io/cuda-vector-add:v0.1"
          resources:
            limits:
              nvidia.com/gpu: 1
    
  4. マニフェストを適用してサンプル アプリケーションをデプロイします。

    kubectl apply -f gpupod.yaml
    
  5. ポッドが起動し、実行が完了し、GPU が割り当てられていることを確認します。

    kubectl describe pod cuda-vector-add | grep -i gpu
    

    前のコマンドでは、1 つの GPU が割り当てられている必要があります。

    nvidia.com/gpu: 1
    nvidia.com/gpu: 1
    
  6. ポッドのログ ファイルを調べて、テストに合格したかどうかを確認します。

    kubectl logs cuda-vector-add
    

    前のコマンドからの出力例を次に示します。

    [Vector addition of 50000 elements]
    Copy input data from the host memory to the CUDA device
    CUDA kernel launch with 196 blocks of 256 threads
    Copy output data from the CUDA device to the host memory
    Test PASSED
    Done
    

次のステップ