NVIDIA デバイスプラグインは、Kubernetes クラスター向けの GPU デバイスプラグインであり、各ノード上の GPU を管理することで、Kubernetes が GPU リソースをより効率的に使用できるようにします。このトピックでは、Alibaba Cloud Container Service for Kubernetes (ACK) ノードの排他的 GPU スケジューリングシナリオにおいて、NVIDIA デバイスプラグインのアップグレード、再起動、GPU デバイスの隔離、およびバージョンの確認を行う方法について説明します。
注意事項
NVIDIA デバイスプラグインを DaemonSet としてデプロイする場合、以下の点に注意してください。
クラスターの作成時に、このアドオンは自動的にインストールされます。
このアドオンをアンインストールすると、スケールアウトした GPU アクセラレーションノードが GPU リソースを正しく報告できなくなります。
クラスターを以前のバージョンから 1.32 にアップグレードすると、NVIDIA デバイスプラグインも静的 Pod から ACK アドオンにアップグレードされます。
DaemonSet は NodeSelector (
ack.node.gpu.schedule=default) を使用します。 GPU 高速化ノードがクラスターに追加されると、ノードを追加する ACK スクリプトがこのラベルを GPU 高速化ノードに自動的に付与します。 その後、DaemonSet はポッドを GPU 高速化ノードにデプロイします。
ノードで Ubuntu 22.04 または Red Hat Enterprise Linux (RHEL) 9.3 64 ビットが実行されている場合、
systemctl daemon-reloadまたはsystemctl daemon-reexecコマンドを実行した後、NVIDIA Device Plugin が正しく動作しない場合があります。この問題は、ack-nvidia-device-pluginコンポーネントがデフォルトでポッドに対してNVIDIA_VISIBLE_DEVICES=all環境変数を設定するために発生します。これにより、GPU デバイスにアクセスできなくなる可能性があります。詳細については、「GPU コンテナーの実行時に「Failed to initialize NVML: Unknown Error」エラーが発生した場合はどうすればよいですか。」をご参照ください。2025 年 5 月 1 日より前に、クラスターを 1.32 より前のバージョンからバージョン 1.32 にアップグレードした場合、クラスターには静的 Pod と DaemonSet の両方としてデプロイされた NVIDIA デバイスプラグインが含まれている可能性があります。以下のスクリプトを実行して、NVIDIA デバイスプラグインが静的 Pod としてデプロイされているノードを見つけることができます。
#!/bin/bash # kube-system 名前空間内の component=nvidia-device-plugin ラベルを持つすべての Pod をループします。 for i in $(kubectl get po -n kube-system -l component=nvidia-device-plugin | grep -v NAME | awk '{print $1}');do # Pod の設定ソースが 'file' かどうかを確認します。これは静的 Pod を示します。 if kubectl get po $i -o yaml -n kube-system | grep 'kubernetes.io/config.source: file' &> /dev/null;then # 静的 Pod の場合、ノード名を出力します。 kubectl get pod $i -n kube-system -o jsonpath='{.spec.nodeName}{"\n"}' fi done想定される出力:
cn-beijing.10.12.XXX.XX cn-beijing.10.13.XXX.XX出力結果は、一部のノードで NVIDIA デバイスプラグインが静的 Pod としてデプロイされていることを示しています。次のコマンドを使用して、NVIDIA デバイスプラグインを静的 Pod から DaemonSet に移行できます。
kubectl label nodes <NODE_NAME> ack.node.gpu.schedule=defaultバージョン 1.31 以前のクラスターでノードプールをアップグレードすると、NVIDIA デバイスプラグインもアップグレードされ、非標準の設定がリセットされます。
バージョン間の違い
ack-nvidia-device-plugin コンポーネントの実装および管理方法は、次の表に示すように、クラスターバージョンによって異なります。
機能 | バージョン 1.32 以降 | バージョン 1.20 から 1.31 |
デプロイ方法 | DaemonSet | 静的 Pod |
管理方法 | ACK コンソールの [アドオン] ページ | 手動 |
ノードラベル要件 | ack.node.gpu.schedule=default | なし |
ノードプールのアップグレード戦略 | 手動アップグレード | 自動アップグレード |
クラスターのバージョンが 1.20 より前の場合は、クラスターを手動でアップグレードすることを推奨します。
前提条件
ACKコンソールにログインします。 左側のナビゲーションウィンドウで、[クラスター] をクリックします。
NVIDIA デバイスプラグインのバージョンの確認
バージョン 1.32 以降
DaemonSet としてデプロイされたアドオンの場合、ACK コンソールのアドオン管理 ページに移動し、ack-nvidia-device-plugin アドオンを見つけ、アドオンカードでそのバージョンを確認します。
バージョン 1.20 から 1.31
静的 Pod としてデプロイされたアドオンの場合は、次のコマンドを実行してアドオンのバージョンを確認します。
kubectl get pods -n kube-system -l component=nvidia-device-plugin \
-o jsonpath='{range .items[*]}{.spec.containers[0].image}{"\t"}{.spec.nodeName}{"\n"}{end}' \
| awk -F'[:/]' '{split($NF, a, "-"); print a[1] "\t" $0}' \
| sort -k1,1V \
| cut -f2- \
| awk -F'\t' '{split($1, img, ":"); print img[NF] "\t" $2}'NVIDIA デバイスプラグインのアップグレード
ack-nvidia-device-plugin アドオンをアップグレードします。
バージョン 1.32 以降
ACKコンソールにログインします。 左側のナビゲーションウィンドウで、[クラスター] をクリックします。
[クラスター] ページで、管理するクラスターの名前をクリックします。 左側のウィンドウで、 を選択します。
「アドオン」ページで、ack-nvidia-device-plugin カードを見つけ、アップグレード をクリックします。
表示されたダイアログボックスで、OK をクリックします。
バージョン 1.20 から 1.31
[クラスター] ページで、管理するクラスターの名前をクリックします。 左側のナビゲーションウィンドウで、 を選択します。
管理する GPU 高速化ノードを選択し、ノードリストの下部にある一括操作をクリックし、一括操作ダイアログボックスでShell スクリプトの実行を選択し、次にOKをクリックします。
重要まず少数の GPU アクセラレーションノードで GPU デバイスプラグインをアップグレードすることを推奨します。プラグインが期待どおりに動作することを確認した後、残りのノードでアップグレードを実行してください。
CloudOps Orchestration Service (OOS) コンソールにリダイレクトされます。実行モード を 失敗中止 に設定し、[次へ: パラメーター設定] をクリックします。
パラメーター設定ページで、[シェルスクリプトの実行] を選択し、次のサンプルスクリプトを貼り付けます。
説明スクリプトの
RUN_PKG_VERSIONパラメーターに、クラスターのメジャーバージョン番号 (例: 1.30) を設定してください。マイナーバージョン番号 (例: 1.30.1) は入力しないでください。そうしないと、スクリプトでエラーが発生します。スクリプトで、
REGION_IDパラメーターを現在のクラスターのリージョン ID (例: cn-beijing) に変更します。
#!/bin/bash set -xe # Kubernetes のメジャーバージョンを設定します。 RUN_PKG_VERSION=1.30 # リージョン ID を設定します。 REGION_ID=cn-beijing function update_device_plugin() { base_dir=/tmp/update_device_plugin rm -rf $base_dir mkdir -p $base_dir cd $base_dir region_id=$REGION_ID PKG_URL=https://aliacs-k8s-${region_id}.oss-${region_id}-internal.aliyuncs.com/public/pkg/run/run-${RUN_PKG_VERSION}.tar.gz curl -sSL --retry 3 --retry-delay 2 -o run.tar.gz $PKG_URL tar -xf run.tar.gz local dir=pkg/run/$RUN_PKG_VERSION/module # イメージレジストリアドレスを置き換えます。 sed -i "s@registry.cn-hangzhou.aliyuncs.com/acs@registry-${region_id}-vpc.ack.aliyuncs.com/acs@g" $dir/nvidia-device-plugin.yml mkdir -p /etc/kubernetes/device-plugin-backup mkdir -p /etc/kubernetes/manifests # 古い設定ファイルをバックアップします。 mv /etc/kubernetes/manifests/nvidia-device-plugin.yml /etc/kubernetes/device-plugin-backup/nvidia-device-plugin.yml.$(date +%s) sleep 5 # 新しい設定ファイルをコピーします。 cp -a $dir/nvidia-device-plugin.yml /etc/kubernetes/manifests echo "succeeded to update device plugin" } # nvidia-device-plugin.yml ファイルが存在するかどうかを確認します。 if [ -f /etc/kubernetes/manifests/nvidia-device-plugin.yml ]; then update_device_plugin else echo "skip to update device plugin" fi次へ: 確認をクリックします。情報を確認した後、作成するをクリックします。
タスクが作成されると、自動的に[タスク実行管理] ページにリダイレクトされ、そこでタスクの実行ステータスを表示できます。更新は、出力 が
succeeded to update device pluginの場合に成功となります。
アドオンが期待どおりに動作しているかどうかを確認します。
次のコマンドを実行して、GPU アクセラレーションノードで GPU デバイスプラグインが正しく動作しているかどうかを確認します。
次のコマンドを実行して、NVIDIA デバイスプラグインが再起動したかどうかを確認します。
kubectl get po -n kube-system -l component=nvidia-device-pluginサンプル出力の AGE 列は、Pod が再起動したかどうかを示します。
NAME READY STATUS RESTARTS AGE nvidia-device-plugin-xxxx 1/1 Running 1 1mすべての Pod が再起動した後、次のスクリプトを実行して、ノードが GPU リソースを報告しているかどうかを確認します。
#!/bin/bash # すべての NVIDIA デバイスプラグイン Pod とそれに対応するノードを取得します。 PODS=$(kubectl get po -n kube-system -l component=nvidia-device-plugin -o jsonpath='{range .items[*]}{.metadata.name}{"\t"}{.spec.nodeName}{"\n"}{end}') # 各 Pod のノードを反復処理します。 echo "$PODS" | while IFS=$'\t' read -r pod_name node_name; do # ノードの allocatable nvidia.com/gpu リソース値を取得します。 gpu_allocatable=$(kubectl get node "$node_name" -o jsonpath='{.status.allocatable.nvidia\.com/gpu}' 2>/dev/null) # リソース値が 0 かどうかを確認します。 if [ "$gpu_allocatable" == "0" ]; then echo "Error: node=$node_name, pod=$pod_name, resource(nvidia.com/gpu) is 0" fi doneノードがゼロのリソースを報告している場合は、「NVIDIA デバイスプラグインの再起動」をご参照ください。
NVIDIA デバイスプラグインの再起動
ACK の排他的 GPU スケジューリングシナリオでは、ノード上の GPU デバイスを報告するデバイスプラグインはデフォルトで Pod としてデプロイされます。そのため、対象ノードで再起動を実行する必要があります。
バージョン 1.32 以降
次のコマンドを実行して、対応するノード上のデバイスプラグイン Pod を見つけます。
kubectl get pod -n kube-system -l component=nvidia-device-plugin -o wide | grep <NODE>次のコマンドを実行して、対応するデバイスプラグイン Pod を再起動します。
kubectl delete po <DEVICE_PLUGIN_POD> -n kube-system
バージョン 1.20 から 1.31
[クラスター] ページで、管理するクラスターの名前をクリックします。 左側のナビゲーションウィンドウで、 を選択します。
ノードプール ページで、ノードプール名をクリックしてノード管理ページに移動し、ターゲット GPU 高速化ノードにログインします。
オペレーティングシステムが ContainerOS の場合、潜在的なセキュリティリスクを軽減するため、デフォルトでユーザーログインが無効になっており、SSH ログインは提供されていません。それでも運用保守のためにインスタンスにログインする必要がある場合は、「ContainerOS ノードの運用保守」をご参照ください。
管理する GPU アクセラレーテッドノードを選択し、ノードリストの下部にある一括操作をクリックし、一括操作 ダイアログボックスで[シェルコマンドの実行]を選択してから、OKをクリックします。
重要まず少数の GPU アクセラレーションノードでデバイスプラグインを再起動することを推奨します。プラグインが期待どおりに動作することを確認した後、残りのノードで再起動を実行してください。
OOS コンソールにリダイレクトされます。実行モード を 失敗中止 に設定し、[次へ: パラメーター設定] をクリックします。
パラメーター設定ページで、[シェルスクリプトの実行] を選択し、次のサンプルスクリプトを貼り付けます。
#!/bin/bash set -e # nvidia-device-plugin.yml ファイルが存在するかどうかを確認します。 if [ -f /etc/kubernetes/manifests/nvidia-device-plugin.yml ]; then # ファイルを移動して静的 Pod を再起動します。 cp -a /etc/kubernetes/manifests/nvidia-device-plugin.yml /etc/kubernetes rm -rf /etc/kubernetes/manifests/nvidia-device-plugin.yml sleep 5 mv /etc/kubernetes/nvidia-device-plugin.yml /etc/kubernetes/manifests echo "the nvidia device is restarted" else echo "no need to restart nvidia device plugin" fi[次へ: 確認] をクリックします。 情報を確認して 作成する をクリックすると、[タスク実行管理] ページにリダイレクトされ、タスクのステータスを表示できます。
次のコマンドを実行して、GPU アクセラレーションノードで GPU デバイスプラグインが正しく動作しているかどうかを確認します。
kubectl get nodes <NODE_NAME> -o jsonpath='{.metadata.name} ==> nvidia.com/gpu: {.status.allocatable.nvidia\.com/gpu}'想定される出力:
cn-hangzhou.172.16.XXX.XX ==> nvidia.com/gpu: 1GPU アクセラレーションノード上の
nvidia.com/gpu拡張リソースの値が 0 以外の場合、デバイスプラグインが正常に動作していることを示します。
デバイスプラグインのチェックポイントキーの変更
デバイスプラグインは、Pod にデバイスを割り当てる際、ノード上にチェックポイントファイルを作成し、どのデバイスがどの Pod に割り当てられているかを記録します。デフォルトでは、NVIDIA デバイスプラグインはチェックポイントファイル内の各 GPU デバイスの一意のキーとして GPU の UUID を使用します。このキーをデバイスインデックスに変更することで、VM のコールド移行後の UUID 損失などの問題を解決できます。
バージョン 1.32 以降
次のコマンドを実行して、NVIDIA デバイスプラグイン DaemonSet を編集します。
kubectl edit ds -n kube-system ack-nvidia-device-pluginCHECKPOINT_DEVICE_ID_STRATEGY環境変数を追加します。env: - name: CHECKPOINT_DEVICE_ID_STRATEGY value: index変更を適用するには、NVIDIA デバイスプラグインを再起動します。
バージョン 1.20 から 1.31
ターゲットノードの
/etc/kubernetes/manifests/nvidia-device-plugin.ymlファイルにあるイメージタグを確認してください。このタグは、Device-Plugin のバージョンを示しています。バージョンが 0.9.3 以降である場合は、何もする必要はありません。そうでない場合は、バージョンをv0.9.3-0dd4d5f5-aliyunに更新してください。/etc/kubernetes/manifests/nvidia-device-plugin.ymlファイル内の静的ポッドの環境変数を変更します。 次のコードを参照して、CHECKPOINT_DEVICE_ID_STRATEGY環境変数を追加します。env: - name: CHECKPOINT_DEVICE_ID_STRATEGY value: index変更を適用するには、NVIDIA デバイスプラグインを再起動します。
GPU デバイスの隔離の有効化
GPU デバイスの分離は nvidia-device-plugin v0.9.1 以降でのみサポートされています。詳細については、「NVIDIA Device Plugin のバージョンを確認する」をご参照ください。
ACK の排他的 GPU スケジューリングシナリオでは、障害やその他の理由により、ノード上の GPU デバイスを隔離する必要がある場合があります。ACK は、スケジューラーが新しい GPU アプリケーション Pod をそのデバイスに割り当てないようにするために、デバイスを手動で隔離するメカニズムを提供しています。次の手順に従います。
ターゲットノードの /etc/nvidia-device-plugin/ ディレクトリで、unhealthyDevices.json ファイルを管理します。このファイルが存在しない場合は、作成します。unhealthyDevices.json ファイルは、次の JSON 形式でなければなりません。配列には、複数のデバイスチェックポイントキーを含めることができます。必要に応じてキーを追加します。
{
"index": ["x", "x"],
"uuid": ["xxx", "xxx"]
}JSON ファイルに、隔離対象のデバイスの index または uuid を入力できます。各デバイスには、いずれか 1 つを入力するだけで十分です。ファイルを保存すると、変更は自動的に適用されます。
設定が完了したら、Kubernetes ノードによって報告される nvidia.com/gpu リソースの数を確認することで、分離効果を検証できます。
GDR デバイスのマウントと GPU メモリコピーの高速化の有効化
要件
v0.5.0 以降、ack-nvidia-device-plugin は GDR デバイスを GPU コンテナにマウントすることに対応しています。この機能には、以下の要件があります。
クラスターのバージョンが 1.32 以降であること。
ノードが Lingjun ノードであること。
ノードに GDR ソフトウェアがインストールされていること。
ノードにログインし、
lsmod | grep gdrdrvコマンドを実行して、GDR カーネルモジュールがロードされているかどうかを確認できます。サンプル出力は次のとおりです。gdrdrv 196608 0 nvidia 14680064 88 nvidia_uvm,nvidia_peermem,gdrdrv,nvidia_modesetノードに NVIDIA Container Toolkit 1.15.0 以降がインストールされていること。
ノードにログインして
nvidia-container-cli --versionを実行すると、バージョンを確認できます。以下に出力例を示します。cli-version: 1.17.8 lib-version: 1.17.8
GDR 高速化の有効化
ACKコンソールにログインします。 左側のナビゲーションウィンドウで、[クラスター] をクリックします。
[クラスター] ページで、管理するクラスターの名前をクリックします。 左側のウィンドウで、 を選択します。
「アドオン」ページで、ack-nvidia-device-plugin カードを見つけ、設定 をクリックします。
表示されたダイアログボックスで、GDRCopy を有効にして GPU メモリコピーを高速化します (有効化後、GDR ソフトウェアがインストール済みで、nvidia-container-toolkit のバージョンが 1.15.0 以上の Lingjun ノードに適用されます)。 を選択します。
結果の検証
[クラスター] ページで、管理するクラスターの名前をクリックします。 左側のウィンドウで、 を選択します。
デプロイメント ページで、YAML のリソースの作成 をクリックします。 次のサンプルコードを使用してアプリケーションを作成します。
apiVersion: v1 kind: Pod metadata: name: tensorflow-mnist namespace: default spec: containers: - image: registry.cn-beijing.aliyuncs.com/acs/tensorflow-mnist-sample:v1.5 name: tensorflow-mnist command: - python - tensorflow-sample-code/tfjob/docker/mnist/main.py - --max_steps=100000 - --data_dir=tensorflow-sample-code/data resources: limits: nvidia.com/gpu: 1 # このコンテナに 1 つの GPU カードをリクエストします。 workingDir: /root restartPolicy: Always次のコマンドを実行して Pod に入ります。
kubectl exec -ti tensorflow-mnist -- ls /dev/gdrdrv想定される出力:
/dev/gdrdrv出力結果は、gdrdrv デバイスが正常にマウントされたことを示しています。
よくある質問
ネイティブ GPU 隔離機能の無効化
背景
ノード上の GPU に障害が発生した場合、ACK は NVIDIA デバイスプラグインを使用して障害のある GPU を自動的に隔離し、スケジューラーがそこにタスクを割り当てないようにします。ただし、この自動隔離は自動修復を実行しません。ノードを手動で再起動または修復する必要があります。GPU 例外のアラートを設定して、迅速に対処することを推奨します。NVIDIA デバイスプラグインのネイティブ GPU 隔離機能の詳細については、「k8s-device-plugin」をご参照ください。
隔離後、ノードにタスクの要件を満たす十分な GPU がない場合 (たとえば、タスクに 8 枚のカードが必要だが、7 枚しか利用できない場合)、スケジューラーはそのノードにタスクを割り当てられず、GPU リソースがアイドル状態のままになります。
GPU ステータスが正常に戻ると、システムはデバイスの隔離を自動的に解除します。
自動隔離を無効にして、障害のある GPU に対してもノードがリソースを報告し続けるようにする必要がある場合は、次のソリューションを参照してください。
ソリューション
アドオンでネイティブ GPU 隔離機能が有効になっているかどうかを確認します。
有効になっていない場合、無効にするための後続の手順を実行する必要はありません。
バージョン 1.32 以降
ACK コンソールにログインし、対象クラスターのアドオン管理 ページで ack-nvidia-device-plugin のバージョンを確認します。バージョンが v0.1.0 の場合、GPU 分離機能が有効になっています。
バージョン 1.20 から 1.31
NVIDIA デバイスプラグインで GPU 隔離が有効になっているかどうかを確認します。
check_gpu_isolation_enabled() { echo "Checking nodes with NVIDIA Device Plugin deployed as static pods that have GPU isolation enabled (i.e., DP_DISABLE_HEALTHCHECKS is not set to 'all')..." # 期待されるラベルを持つ Pod 名を取得します。 pods=$(kubectl get pods -n kube-system -l component=nvidia-device-plugin --no-headers -o custom-columns=":metadata.name" 2>/dev/null) if [ -z "$pods" ]; then echo "No pods found with label 'component=nvidia-device-plugin'." return 0 fi found=0 while IFS= read -r pod; do [ -z "$pod" ] && continue # 静的 Pod かどうかを確認します: アノテーション kubernetes.io/config.source が "file" である必要があります。 config_source=$(kubectl get pod "$pod" -n kube-system -o jsonpath='{.metadata.annotations.kubernetes\.io/config\.source}' 2>/dev/null) if [ "$config_source" != "file" ]; then # 静的 Pod ではありません (例: DaemonSet によって管理されている)。スキップします。 continue fi # ノード名を取得します。 node=$(kubectl get pod "$pod" -n kube-system -o jsonpath='{.spec.nodeName}' 2>/dev/null) [ -z "$node" ] && continue # DP_DISABLE_HEALTHCHECKS が "all" に設定されているかどうかを確認します。 disabled_value=$(kubectl get pod "$pod" -n kube-system -o jsonpath='{range .spec.containers[*]}{range .env[?(@.name=="DP_DISABLE_HEALTHCHECKS")]}{.value}{"\n"}{end}{end}' 2>/dev/null | head -n1) # 設定されていないか、"all" と等しくない場合、ヘルスチェックがアクティブであり、隔離が有効になっていることを意味します。 if [ -z "$disabled_value" ] || [ "$disabled_value" != "all" ]; then echo "Node: $node, Static Pod: $pod" found=1 fi done <<< "$pods" if [ "$found" -eq 0 ]; then echo "No static pods found with GPU isolation enabled." else echo "Note: The above nodes will automatically isolate faulty GPUs via NVIDIA Device Plugin." fi } check_gpu_isolation_enabled想定される出力:
Checking nodes with NVIDIA Device Plugin deployed as static pods that have GPU isolation enabled (i.e., DP_DISABLE_HEALTHCHECKS is not set to 'all')... Node: cn-beijing.192.168.XXX.XXX, Static Pod: nvidia-device-plugin-cn-beijing.192.168.XXX.XXX Note: The above nodes will automatically isolate faulty GPUs via NVIDIA Device Plugin.出力に
注: 上記のノードは、NVIDIA Device Plugin を介して障害のある GPU を自動的に隔離します。が含まれている場合、GPU 隔離機能が有効になっています。
アドオンをアップグレードして GPU 隔離機能を無効にします。
NVIDIA デバイスプラグインアドオンの最新バージョンでは、ネイティブ GPU 隔離機能がデフォルトで無効になっています。NVIDIA デバイスプラグインをアップグレードして、この変更を適用してください。
関連トピック
アドオンの変更履歴については、「ack-nvidia-device-plugin」をご参照ください。
GPU アクセラレーションノードで問題が発生した場合は、「GPU アクセラレーションノードの問題の診断」および「GPU FAQ」をご参照ください。
共有 GPU スケジューリングについては、「共有 GPU スケジューリング」をご参照ください。