この記事では、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_2 や Standard_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 CLIと
aksarc拡張機能をインストールします。NVIDIA ソフトウェアへの送信アクセスを有効にする前に、テナント プロキシまたは論理ネットワーク接続を構成します。 BYO プロキシの手順については、Azure Local のマルチラック上の AKS に BYO プロキシを追加する方法を参照してください。
クラスター作成時に、AKS Arc クラスターが SSH キーを使用して作成され、これらの SSH キーにアクセスできることを確認します。 この記事の手順 3 と 4 では、NVIDIA ドライバーと Container Toolkit をインストールするために各 GPU ワーカー VM への SSH アクセスが必要であり、SSH キーはクラスターの作成時にのみ構成できます。
Note
GPU がポッド スペックから nvidia.com/gpu としてスケジュール可能になるように、NVIDIA ドライバー、NVIDIA Container Toolkit、NVIDIA Kubernetes デバイス プラグインを手動でインストールする必要があります。 この記事の手順 3 - 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 対応のユーザー ノード プールを追加する必要があります。
(GPU ノード プールを使用せずに) AKS Arc クラスターを作成します。 詳細な手順とパラメーターのガイダンスについては、Azure CLIを使用した Kubernetes クラスターの作成に関する記事を参照してください。
GPU 対応の Linux ノード プールを追加します。 次の例では、
Standard_NC16_RTX6000Pro_1VM の 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 がない場合、コマンドは失敗します。
(省略可能)Azure Arc プロキシを使用してクラスターに接続します。
az connectedk8s proxy --name <aks cluster name> --resource-group <resource group name>
手順 3: ワーカー VM 内に NVIDIA ドライバーをインストールする
Azure Local プラットフォームは PCI パススルーを介してワーカー VM に物理 GPU を配信しますが、ゲスト オペレーティング システム内の NVIDIA ドライバーはプレインストールされていません。 ワーカー VM は Azure Linux 3 で実行され、サポートされているインストール方法は、cuda-open から入手する Microsoft 署名済みの packages.microsoft.com RPM です。
Important
NVIDIA RTX Pro 6000 (Blackwell アーキテクチャ) には 、オープン カーネル モジュールが必要です。
cuda-open パッケージを使用します。 Azure Linux 3 では、署名されていないモジュールの実行を妨げるセキュリティの強制により、cuda インストーラーが実行されないため、NVIDIA .run パッケージを使用できません。
GPU ノード プール内の各ワーカー VM で、このセクションの手順を繰り返します。 ゲスト内シェルを開くには、SSH を使用します (SSH を使用した Windows または Linux ワーカー ノードへの接続を参照)。
GPU デバイスがゲストに表示されていることを確認します。
lspci -nn | grep -i nvidia次のようなものが予想されます。
0e:00.0 3D controller [0302]: NVIDIA Corporation Device [10de:2bb5] (rev a1)ワーカー VM が、
packages.microsoft.comへの送信 HTTPS アクセス権を持っていることを確認します。環境で送信トラフィックに HTTPS プロキシが必要な場合は、それを使用するように
tdnfを構成します。<proxy-url>を、packages.microsoft.comに到達することが許可されているプロキシに置き換えます。echo 'proxy=<proxy-url>' | sudo tee -a /etc/tdnf/tdnf.confNote
tdnfは、/etc/tdnf/tdnf.confからプロキシを読み取ります。 手順 4 とワーカー VM での今後のパッケージの更新には、同じプロキシが必要です。リポジトリへの接続を確認します。 上記でプロキシを構成した場合は、
-xを使用して明示的に渡します。それ以外の場合は、-xフラグを省略します。curl -sI -x <proxy-url> https://packages.microsoft.com/azurelinux/3.0/prod/nvidia/x86_64/ | head -1予期される応答:
HTTP/2 200。Azure Linux NVIDIA リポジトリを有効にします。 既定では、ベース、
ms-oss、およびms-non-ossリポジトリのみが構成されます。cuda-openパッケージは、1 回追加する必要がある別の NVIDIA リポジトリに存在します。sudo tee /etc/yum.repos.d/azurelinux-nvidia.repo > /dev/null <<'EOF' [azurelinux-official-nvidia] name=Azure Linux Official NVIDIA 3.0 x86_64 baseurl=https://packages.microsoft.com/azurelinux/3.0/prod/nvidia/x86_64 gpgkey=https://packages.microsoft.com/keys/microsoft.asc gpgcheck=1 enabled=1 sslverify=1 EOF sudo tdnf makecacheカーネル パッケージと
tdnfが同じバージョンになるように、ビルドの前提条件と NVIDIA ドライバーを単一のcuda-openトランザクションでインストールします。 パッケージ名にもかかわらず、cuda-openはカーネル モジュールを開いた ドライバー パッケージです。手順 4 で個別にインストールされている CUDA ツールキット (nvcc) は含まれません。sudo tdnf install -y \ kernel kernel-devel kernel-headers kernel-drivers-gpu \ libdrm-devel gcc make glibc-devel \ cuda-opencuda-openは Mariner Trusted Base によって署名されているため、lockdown=integrityが有効になっている場合でもカーネル モジュールが読み込まれます。Important
cuda-openは、特定のカーネル ABI に対してビルドされます (cuda-open-580.105.08-4_6.6.139.1.1.azl3など、バージョン サフィックスを参照)。 現在実行中のカーネルよりも新しいカーネルをインストールする場合は、モジュールを読み込む前に再起動する必要があります。または、modprobe nvidiaModule nvidia not found in directory /lib/modules/<running-kernel>で失敗します。uname -rに対してrpm -q kernelを確認し、異なる場合はsudo reboot実行します。NVIDIA カーネル モジュールを読み込み、
nvidia-smiで確認します。 ドライバーが/dev/nvidia*デバイス ノードを作成できるようにするには、最初の呼び出しをルートとして実行する必要があります。ノードはモード0666で作成されるため、後続の特権のない呼び出しは機能します。sudo modprobe nvidia sudo modprobe nvidia_uvm sudo modprobe nvidia_drm lsmod | grep '^nvidia' sudo nvidia-smisudo nvidia-smiからの正常な出力には、インストールされているドライバーバージョンの NVIDIA RTX Pro 6000 が一覧表示されます。 この時点で、ドライバーはワーカー VM 内で完全に検証されます。
手順 4: 各 GPU ワーカー VM に NVIDIA Container Toolkit をインストールする
ドライバーはワーカー VM のホスト OS から GPU を使用できるようにしますが、コンテナーには、 /dev/nvidia* と一致するユーザー空間ライブラリ (libcuda.so、 libnvidia-ml.so) を確認するためのランタイム フックが必要です。
nvidia-container-toolkit パッケージは、そのフックを提供し、containerdに登録します。
各 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.v2 が BinaryName を指している /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のウェブサイトでも見つけることができます。
az connectedk8s proxyを使用して AKS Arc クラスターに接続します。 詳細なガイダンスについては、「 クラスターへの接続」を参照してください。--fileオプションを使用して、専用の kubeconfig (たとえば、./<aks cluster name>.kubeconfig) を記述し、プロキシを実行したままにし、残りの手順のために 2 番目のターミナルのその kubeconfig でkubectlをポイントします。次のマニフェストを 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マニフェストを適用します。
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 コマンドを実行します。
まず、
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.0kubectl 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次の内容を含む 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マニフェストを適用してサンプル アプリケーションをデプロイします。
kubectl apply -f gpupod.yamlポッドが起動し、実行が完了し、GPU が割り当てられていることを確認します。
kubectl describe pod cuda-vector-add | grep -i gpu前のコマンドでは、1 つの GPU が割り当てられている必要があります。
nvidia.com/gpu: 1 nvidia.com/gpu: 1ポッドのログ ファイルを調べて、テストに合格したかどうかを確認します。
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