NVIDIA Device Plugin は、Kubernetes クラスター向けの GPU デバイスプラグインです。各ノードの GPU を管理し、Kubernetes が GPU リソースをより効率的に使用できるようにします。このトピックでは、GPU 排他スケジューリングシナリオにおいて、Alibaba Cloud Container Service for Kubernetes (ACK) ノード上で NVIDIA Device Plugin をアップグレードおよび再起動する方法、GPU デバイスを隔離する方法、およびそのバージョンを確認する方法について説明します。
注意事項
NVIDIA Device Plugin を DaemonSet としてデプロイする場合、次の点にご注意ください。
-
クラスターを作成すると、このアドオンは自動的にインストールされます。
-
このアドオンをアンインストールすると、スケールアウトされた GPU アクセラレーションノードは GPU リソースを正しく報告できなくなります。
-
クラスターを以前のバージョンから 1.32 にアップグレードすると、NVIDIA Device Plugin も静的 Pod から ACK アドオンにアップグレードされます。
-
DaemonSet は NodeSelector (`ack.node.gpu.schedule=default`) を使用します。GPU アクセラレーションノードがクラスターに追加されると、ノードを追加する ACK スクリプトがこのラベルを GPU アクセラレーションノードに自動的にアタッチします。その後、DaemonSet はその Pod を 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コンポーネントがデフォルトで Pod にNVIDIA_VISIBLE_DEVICES=all環境変数を設定するため、GPU デバイスにアクセスできなくなる可能性があるために発生します。詳細については、「GPU コンテナの実行時に「Failed to initialize NVML: Unknown Error」エラーが発生した場合の対処法」をご参照ください。 -
2025 年 5 月 1 日より前に、クラスターを 1.32 より前のバージョンからバージョン 1.32 にアップグレードした場合、クラスターには静的 Pod と DaemonSet の両方としてデプロイされた NVIDIA Device Plugin が含まれる可能性があります。次のスクリプトを実行して、NVIDIA Device Plugin が静的 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この出力は、一部のノードにまだ静的 Pod として NVIDIA Device Plugin がデプロイされていることを示しています。次のコマンドを使用して、NVIDIA Device Plugin を静的 Pod から DaemonSet に移行できます。
kubectl label nodes <NODE_NAME> ack.node.gpu.schedule=default -
バージョン 1.31 以前のクラスターでノードプールをアップグレードすると、NVIDIA Device Plugin もアップグレードされ、その非標準の構成はリセットされます。
バージョンによる違い
ack-nvidia-device-plugin コンポーネントの実装と管理戦略は、次の表に示すように、クラスターのバージョンによって異なります。
|
機能 |
バージョン 1.32 以降 |
バージョン 1.20 から 1.31 |
|
デプロイ方法 |
DaemonSet |
静的 Pod |
|
管理方法 |
ACK コンソールのアドオンページ |
手動 |
|
ノードラベル要件 |
ack.node.gpu.schedule=default |
なし |
|
ノードプールのアップグレード戦略 |
手動アップグレード |
自動アップグレード |
ご利用のクラスターのバージョンが 1.20 より前の場合は、クラスターを手動でアップグレードすることを推奨します。
前提条件
ACK コンソールにログインします。左側のナビゲーションウィンドウで、クラスターリスト をクリックします。
NVIDIA device plugin のバージョンの確認
バージョン 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 device plugin のアップグレード
-
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 Device Plugin が再起動したかを確認します。
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 Device Plugin 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 # ノードの割り当て可能な 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 Device Plugin の再起動」をご参照ください。
NVIDIA device plugin の再起動
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 ログインは提供されていません。それでも O&M のためにインスタンスにログインする必要がある場合は、「ContainerOS ノードの O&M」をご参照ください。
-
管理する 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拡張リソースの値がゼロ以外であることは、Device Plugin が正常に動作していることを示します。
デバイスプラグインのチェックポイントキーの変更
デバイスを Pod に割り当てる際、デバイスプラグインはノード上にチェックポイントファイルを作成し、どのデバイスがどの Pod に割り当てられているかを記録します。デフォルトでは、NVIDIA Device Plugin は GPU の UUID をチェックポイントファイル内の各 GPU デバイスの一意キーとして使用します。このキーをデバイスインデックスに変更することで、VM のコールド移行後の UUID 損失などの問題を解決できます。
バージョン 1.32 以降
-
次のコマンドを実行して、NVIDIA Device Plugin DaemonSet を編集します。
kubectl edit ds -n kube-system ack-nvidia-device-plugin -
CHECKPOINT_DEVICE_ID_STRATEGY環境変数を追加します。env: - name: CHECKPOINT_DEVICE_ID_STRATEGY value: index -
変更を適用するために、NVIDIA Device Plugin を再起動します。
バージョン 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ファイル内の静的 Pod の環境変数を変更します。次のコードを参照して、CHECKPOINT_DEVICE_ID_STRATEGY環境変数を追加します。env: - name: CHECKPOINT_DEVICE_ID_STRATEGY value: index -
変更を適用するために、NVIDIA Device Plugin を再起動します。
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 を入力できます。各デバイスについて、どちらか一方を入力するだけで十分です。ファイルを保存すると、変更は自動的に有効になります。
設定が完了したら、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 カードを見つけて、設定 をクリックします。
-
表示されるダイアログボックスで、Enable GDRCopy to accelerate GPU memory copy (effective on Lingjun nodes with GDR software installed and nvidia-container-toolkit version >= 1.15.0) を選択します。
結果の検証
クラスターリスト ページで、クラスターの名前をクリックします。左側のナビゲーションウィンドウで、 をクリックします。
-
デプロイメント ページで、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 Device Plugin を使用して障害のある GPU を自動的に隔離し、スケジューラがタスクを割り当てるのを防ぎます。ただし、この自動隔離は自動修復を行いません。ノードを手動で再起動または修復する必要があります。GPU の例外に迅速に対応するために、GPU 例外のアラートを設定することを推奨します。NVIDIA Device Plugin のネイティブ 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 Device Plugin で 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')..." # Get pod names with the expected label. 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 # Check if it's a static pod: annotation kubernetes.io/config.source must be "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 # Not a static pod (e.g., managed by a DaemonSet), skip. continue fi # Get node name. node=$(kubectl get pod "$pod" -n kube-system -o jsonpath='{.spec.nodeName}' 2>/dev/null) [ -z "$node" ] && continue # Check if DP_DISABLE_HEALTHCHECKS is set to "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) # If not set or not equal to "all", health checks are active, which means isolation is enabled. 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 the 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.出力に
Note: The above nodes will automatically isolate faulty GPUs via NVIDIA Device Plugin.が含まれている場合、GPU 隔離機能は有効になっています。
-
アドオンをアップグレードして GPU 隔離機能を無効にします。
NVIDIA Device Plugin アドオンの最新バージョンでは、ネイティブ GPU 隔離機能はデフォルトで無効になっています。この変更を適用するには、NVIDIA Device Plugin を最新バージョンにアップグレードします。
関連トピック
-
アドオンの変更履歴については、「ack-nvidia-device-plugin」をご参照ください。
-
GPU アクセラレーションノードで問題が発生した場合は、「GPU アクセラレーションノードの問題の診断」および「GPU に関するよくある質問」をご参照ください。
-
共有 GPU スケジューリングについては、「共有 GPU スケジューリング」をご参照ください。