NVIDIA Device Plugin は、Kubernetes クラスター内の各ノードで GPU を管理するコンポーネントです。これにより、Kubernetes は GPU リソースをより簡単かつ効率的に使用できます。このトピックでは、専用 GPU スケジューリングシナリオで、NVIDIA Device Plugin のアップグレードと再起動、GPU デバイスの隔離、および ACK ノード上のコンポーネントバージョンの表示と更新を行う方法について説明します。
使用上の注意
詳細については、「NVIDIA Device Plugin の設定と管理」をご参照ください。
DaemonSet としてデプロイされた NVIDIA Device Plugin に関する以下の点に注意してください。
このコンポーネントは、クラスターの作成時に自動的にインストールされます。
このコンポーネントをアンインストールすると、スケールアウトされた GPU ノードは GPU リソースを報告できなくなります。
クラスターを以前のバージョンからバージョン 1.32 にアップグレードすると、静的 Pod としてデプロイされた NVIDIA Device Plugin も 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 ビットの場合、NVIDIA Device Plugin が正しく動作しないことがあります。これは、
ack-nvidia-device-pluginコンポーネントがデフォルトで Pod にNVIDIA_VISIBLE_DEVICES=all環境変数を設定するためです。その結果、ノードがsystemctl daemon-reloadまたはsystemctl daemon-reexecコマンドを実行した後、プラグインは GPU デバイスにアクセスできなくなります。詳細については、「GPU コンテナーの実行時に「Failed to initialize NVML: Unknown Error」エラーが発生した場合はどうすればよいですか?」をご参照ください。2025 年 5 月 1 日より前にクラスターを以前のバージョンからバージョン 1.32 にアップグレードすると、クラスターに静的 Pod と DaemonSet の両方としてデプロイされた NVIDIA Device Plugin が存在する可能性があります。次のスクリプトを実行して、プラグインが静的 Pod としてデプロイされているノードを表示できます。
#!/bin/bash for i in $(kubectl get po -n kube-system -l component=nvidia-device-plugin | grep -v NAME | awk '{print $1}');do if kubectl get po $i -o yaml -n kube-system | grep 'kubernetes.io/config.source: file' &> /dev/null;then 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 Device Plugin が一部のノードでまだ静的 Pod としてデプロイされていることを示しています。次のスクリプトを実行して、NVIDIA Device Plugin を静的 Pod デプロイメントから DaemonSet デプロイメントに移行できます。
kubectl label nodes <NODE_NAME> ack.node.gpu.schedule=default
バージョンの違い
ack-nvidia-device-plugin コンポーネントの実装と管理ポリシーは、クラスターのバージョンによって異なります。クラスターのバージョンが 1.20 より前の場合は、「クラスターを手動でアップグレード」してください。違いは次のとおりです。
属性 | クラスターバージョン 1.32 以降 | クラスターバージョン 1.20 から 1.31 |
デプロイメントメソッド | DaemonSet | 静的ポッド |
管理方法 | コンソールでのコンポーネント管理 | 手動メンテナンス |
ノードラベルの要件 | ack.node.gpu.schedule=default | 特別な要件なし |
前提条件
ACK コンソールにログインします。左側のナビゲーションウィンドウで、[クラスター] をクリックします。
NVIDIA Device Plugin のバージョンを表示する
クラスターバージョン 1.32 以降
DaemonSet としてデプロイされたコンポーネントの場合、コンソールの [コンポーネント管理] ページで 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 ノードを選択します。ノードリストの下にある [バッチ操作] をクリックします。[バッチ操作] ダイアログボックスで、[シェルコマンドの実行] を選択し、[OK] をクリックします。
重要まず、少数の GPU ノードを選択してアップグレードします。これらのノードで Device Plugin が期待どおりに動作することを確認した後、より多くのノードで操作を実行します。
OOS インターフェイスにリダイレクトされます。[実行モード] を [失敗時に一時停止] に設定し、[次へ: パラメーターの設定] をクリックします。
[パラメーターの設定] ページで、[シェルスクリプトの実行] を選択し、次のサンプルスクリプトを貼り付けます。
説明スクリプトで、
RUN_PKG_VERSIONパラメーターをクラスターのメジャーバージョン (1.30 など) に変更します。マイナーバージョン (1.30.1 など) は入力しないでください。入力すると、スクリプトは失敗します。#!/bin/bash set -e RUN_PKG_VERSION=1.30 function update_device_plugin() { base_dir=/tmp/update_device_plugin rm -rf $base_dir mkdir -p $base_dir cd $base_dir region_id=$(curl -ssL 100.100.100.200/latest/meta-data/region-id 2> /dev/null || echo "") if [[ $region_id == "" ]]; then echo "Error: failed to get region id,region id is null" exit 1 fi PKG_URL=https://aliacs-k8s-${region_id}.oss-${region_id}.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" } 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 ノードの Device Plugin が期待どおりに動作するかどうかを確認します。
次のコマンドを実行して、NVIDIA Device Plugin が再起動したかどうかを確認します。
kubectl get po -n kube-system -l component=nvidia-device-plugin出力例:
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ノードがリソースとして 0 を報告する場合は、「NVIDIA Device Plugin の再起動」をご参照ください。
NVIDIA Device Plugin の再起動
ACK の専用 GPU スケジューリングシナリオでは、ノード上の GPU デバイスを報告する Device Plugin は、デフォルトで Pod としてデプロイされます。したがって、再起動プロセスはターゲットノードで実行する必要があります。
バージョン 1.32 以降のクラスター
次のコマンドを実行して、ノード上の Device Plugin Pod を見つけます。
kubectl get pod -n kube-system -l component=nvidia-device-plugin -o wide | grep <NODE>次のコマンドを実行して、Device Plugin Pod を再起動します。
kubectl delete po <DEVICE_PLUGIN_POD> -n kube-system
バージョン 1.20 から 1.31 のクラスター
クラスター ページで、管理するクラスターを見つけてその名前をクリックします。左側のナビゲーションウィンドウで、 を選択します。
[ノードプール] ページで、ノードプールの名前をクリックし、ターゲット GPU ノードにログインします。
オペレーティングシステムが ContainerOS の場合、潜在的なセキュリティリスクを軽減し、追跡不可能な操作を防ぐために、直接のユーザーログインはサポートされていません。Secure Shell (SSH) 機能もログインには使用できません。運用および保守 (O&M) のためにインスタンスにログインするには、「ContainerOS ノードで O&M を実行する」をご参照ください。
バッチメンテナンスが必要な GPU ノードを選択します。ノードリストの下にある [バッチ操作] をクリックします。[バッチ操作] ダイアログボックスで、[シェルコマンドの実行] を選択し、[OK] をクリックします。
重要まず、少数の GPU ノードを再起動します。再起動したノードで Device Plugin が期待どおりに動作することを確認した後、より多くのノードで操作を実行します。
表示される OOS ページで、[実行モード] を [失敗時に一時停止] に設定し、[次へ: パラメーターの設定] をクリックします。
[パラメーターの設定] ページで、[シェルスクリプトの実行] を選択し、次のサンプルスクリプトを貼り付けます。
#!/bin/bash set -e if [ -f /etc/kubernetes/manifests/nvidia-device-plugin.yml ]; then 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 the NVIDIA device plugin." fi[次へ: 確認] をクリックします。情報が正しいことを確認したら、[作成] をクリックします。その後、[タスク実行管理] ページにリダイレクトされ、タスクのステータスを表示できます。
次のコマンドを実行して、GPU ノードの Device Plugin が期待どおりに動作するかどうかを確認します。
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 でない場合、Device Plugin は期待どおりに動作しています。
NVIDIA Device Plugin のデバイス ID を変更する
Device Plugin が Pod にデバイスを割り当てると、ノードにチェックポイントファイルが作成されます。このファイルには、どのデバイスが割り当てられ、それに対応する Pod 情報が記録されます。NVIDIA Device Plugin では、チェックポイントファイルはデフォルトで各 GPU デバイスの一意の識別子 (キー) として GPU の UUID を使用します。このキーをデバイスインデックスに変更して、VM のコールド移行によって引き起こされる UUID の損失などの問題を解決できます。
クラスターバージョン 1.32 以降の場合
次のコマンドを実行して、NVIDIA Device Plugin DaemonSet を変更します。
kubectl get 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 を使用して、隔離するデバイスを指定できます。各デバイスに 1 つの識別子を指定するだけで済みます。変更は、ファイルを保存すると自動的に有効になります。
構成が完了したら、Kubernetes ノードによって報告された nvidia.com/gpu リソースの数を確認して、デバイスが隔離されていることを確認できます。
リファレンス
GPU ノードで問題が発生した場合は、「GPU ノードのトラブルシューティング」および「GPU に関するよくある質問」をご参照ください。
共有 GPU スケジューリングの詳細については、「共有 GPU スケジューリング」をご参照ください。