ノードプールを使用して cGPU を管理することで、GPU 共有とメモリ隔離のための柔軟なポリシーを有効にできます。このトピックでは、専用クラスターに特定のラベルを持つ 2 つのノードプールを作成して、これらの機能を制御する方法を説明します。
利用シーン
-
このトピックで説明する機能は、専用クラスターでのみサポートされており、マネージドクラスターではサポートされていません。
-
ACK Pro マネージドクラスターに ack-cgpu コンポーネントをインストールするには、「ack-cgpu コンポーネントの管理」をご参照ください。
前提条件
次のタスクを完了していることを確認してください。
-
ノードプールを計画します。
ノードプールにはカスタム名を使用できます。このトピックでは、例として `cgpu` と `cgpu-no-isolation` を使用します。
ノードプール
GPU 共有
メモリ隔離
ラベル
cgpu
有効
有効
-
cgpu=true
-
cgpu.disable.isolation=false
cgpu-no-isolation
有効
無効
-
cgpu=true
-
cgpu.disable.isolation=true
-
背景情報
Container Service for Kubernetes (ACK) で GPU 共有を使用する場合、次のようなシナリオに遭遇することがあります。
-
トレーニングジョブ A の場合、アプリケーションコードは既に使用可能な GPU メモリを指定しています。したがって、クラスターは GPU 共有のみを提供する必要があり、メモリ隔離は必要ありません。
-
トレーニングジョブ B の場合、アプリケーションコードは使用可能な GPU メモリを指定していません。この場合、クラスターは GPU 共有とメモリ隔離の両方を提供する必要があります。
1 つのクラスターで両方のシナリオをサポートするにはどうすればよいでしょうか。
ノードプールを使用して cGPU を管理することで、両方のシナリオをサポートできます。次の 2 つのノードプールを作成するだけです。
-
GPU 共有のみを提供し、メモリ隔離は提供しないノードプール。このプールは、トレーニングジョブ A のようなジョブ用です。
-
GPU 共有とメモリ隔離の両方を提供するノードプール。このプールは、トレーニングジョブ B のようなジョブ用です。
注意事項
ノードプールを使用して cGPU を管理する場合は、次の点に注意してください。
-
ジョブに `nodeSelector` が指定されていない場合、その Pod はどのノードプールにもスケジュールされる可能性があり、予期しない結果につながる可能性があります。
重要各ジョブには必ず `nodeSelector` を指定してください。
-
ノードラベルが変更された場合 (例:`cgpu.disable.isolation=false` から `cgpu.disable.isolation=true` へ)、メモリ隔離の設定を有効にするには、そのノード上の `gpushare-device-plugin` Pod を再起動する必要があります。
プラグインを再起動するには、既存の `gpushare-device-plugin` Pod を削除します。すると、ACK が自動的に新しい Pod を作成します。次の手順に従ってください。
-
次のコマンドを実行して、クラスター内の `gpushare-device-plugin` Pod を一覧表示します。
kubectl get po -n kube-system -l name=gpushare-device-plugin-ds -o wide次のような出力が想定されます。
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES gpushare-device-plugin-ds-6r8gs 1/1 Running 0 18h 192.168.7.157 cn-shanghai.192.168.7.157 <none> <none> gpushare-device-plugin-ds-pjrvn 1/1 Running 0 15h 192.168.7.158 cn-shanghai.192.168.7.158 <none> <none> -
例えば、`cn-shanghai.192.168.7.157` ノード上の Pod を削除するには、次のコマンドを実行します。
kubectl delete po gpushare-device-plugin-ds-6r8gs -n kube-system
-
ステップ 1:ノードプールの作成
ACK コンソールにログインします。左側のナビゲーションウィンドウで、クラスターリスト をクリックします。
クラスターリスト ページで、クラスターの名前をクリックします。左側のナビゲーションウィンドウで、 をクリックします。
-
右上隅で、ノードプールの作成 をクリックします。
-
ノードプールの作成 ページで、ノードプールのパラメーターを設定します。
パラメーターの詳細については、「ACK マネージドクラスターの作成」をご参照ください。以下に主要なパラメーターをいくつか示します。
-
数量: ノードプール内の初期ノード数です。現時点でノードを作成しない場合は、0 に設定します。
-
オペレーティングシステム: CentOS 7.x や Alibaba Cloud Linux 2.x など、ノードのオペレーティングシステムを選択します。
-
ノードラベル (Labels):このノードプール内のノードに適用するラベル。
-
ECS ラベル: 基盤となる ECS インスタンスに適用するタグ。
-
カスタムリソースグループ: ノードプール内のノード用のリソースグループです。
ノードラベル (Labels) セクションで、各ノードプールに特定のラベルを追加します。
-
`cgpu` ノードプール:`cgpu=true` および `cgpu.disable.isolation=false`
-
`cgpu-no-isolation` ノードプール:`cgpu=true` および `cgpu.disable.isolation=true`
次の設定では、`cgpu-no-isolation` ノードプールを例として使用します。
-
-
注文の確認 をクリックします。
ノードプール ページで、ステータス が 初期化中 の場合、ノードプールは作成中です。作成が完了すると、ステータス は 有効 に変わります。
GPU ノードを追加する必要がある場合は、ノードプールをスケールアウトできます。詳細については、「ノードプールの作成と管理」をご参照ください。
ステップ 2:ジョブの送信
`cgpu-test` と `cgpu-test-no-isolation` の 2 つのジョブを送信します。各ジョブの YAML ファイルで nodeSelector を指定する必要があります。
-
`cgpu-test`:このジョブのコードでは使用可能な GPU メモリサイズが設定されていないため、正しく実行するには cGPU のメモリ隔離が必要です。次のサンプル YAML ファイルに設定を示します。
apiVersion: batch/v1 kind: Job metadata: name: cgpu-test spec: parallelism: 1 template: metadata: labels: app: cgpu-test spec: nodeSelector: cgpu.disable.isolation: "false" # Add a nodeSelector to select the cgpu node pool. containers: - name: cgpu-test image: registry.cn-hangzhou.aliyuncs.com/ai-samples/gpushare-sample:tensorflow-1.5 command: - python - tensorflow-sample-code/tfjob/docker/mnist/main.py - --max_steps=100000 - --data_dir=tensorflow-sample-code/data resources: limits: # この Pod は合計 3 GiB の GPU メモリをリクエストします。 aliyun.com/gpu-mem: 3 workingDir: /root restartPolicy: Never説明-
nodeSelector:`cgpu` ノードプールを指定します。
-
cgpu.disable.isolation: "false":ジョブを `cgpu` ノードプールのノードにスケジュールします。
-
aliyun.com/gpu-mem:GPU メモリの量を GiB 単位で設定します。
-
-
`cgpu-test-no-isolation`:このジョブのコードは自身の GPU メモリ使用量を管理するため、cGPU のメモリ隔離は必要ありません。次のサンプル YAML ファイルに設定を示します。
apiVersion: batch/v1 kind: Job metadata: name: cgpu-test-no-isolation spec: parallelism: 1 template: metadata: labels: app: cgpu-test-no-isolation spec: nodeSelector: cgpu.disable.isolation: "true" # Add a nodeSelector to select the cgpu-no-isolation node pool. containers: - name: cgpu-test-no-isolation image: registry.cn-hangzhou.aliyuncs.com/ai-samples/gpushare-sample:tensorflow-1.5 command: - python - tensorflow-sample-code/tfjob/docker/mnist/main.py - --max_steps=100000 - --data_dir=tensorflow-sample-code/data resources: limits: # この Pod は合計 3 GiB の GPU メモリをリクエストします。 aliyun.com/gpu-mem: 3説明-
nodeSelector:`cgpu-no-isolation` ノードプールを指定します。
-
cgpu.disable.isolation: "true":ジョブを `cgpu-no-isolation` ノードプールのノードにスケジュールします。
-
aliyun.com/gpu-mem:GPU メモリの量を GiB 単位で設定します。
-
ステップ 3:結果の確認
-
次のコマンドを実行してジョブのステータスを確認します。
kubectl get po次のような出力が想定されます。
NAME READY STATUS RESTARTS AGE cgpu-test-0 1/1 Running 0 5m55s cgpu-test-no-isolation-0 1/1 Running 0 6m42s -
メモリ隔離が必要な `cgpu-test-0` Pod で
nvidia-smiコマンドを実行し、コンテナで使用可能な GPU メモリを確認します。kubectl exec cgpu-test-0 -- nvidia-smi次のような出力が想定されます。
Mon Nov 2 11:33:10 2020 +-----------------------------------------------------------------------------+ | NVIDIA-SMI 418.87.01 Driver Version: 418.87.01 CUDA Version: 10.1 | |-------------------------------+----------------------+----------------------+ | GPU Name Persistence-M| Bus-Id Disp.A | Volatile Uncorr. ECC | | Fan Temp Perf Pwr:Usage/Cap| Memory-Usage | GPU-Util Compute M. | |===============================+======================+======================| | 0 Tesla V100-SXM2... On | 00000000:00:07.0 Off | 0 | | N/A 34C P0 54W / 300W | 3039MiB / 3226MiB | 1% Default | +-------------------------------+----------------------+----------------------+ +-----------------------------------------------------------------------------+ | Processes: GPU Memory | | GPU PID Type Process name Usage | |=============================================================================| +-----------------------------------------------------------------------------+コンテナから見える合計メモリは 3,226 MiB であり、物理カードの合計 16 GiB よりもはるかに少ないです。これにより、cGPU のメモリ隔離が有効であることが確認できます。
-
メモリ隔離が不要な `cgpu-test-no-isolation-0` Pod で
nvidia-smiコマンドを実行し、コンテナで使用可能な GPU メモリを確認します。kubectl exec cgpu-test-no-isolation-0 -- nvidia-smi次のような出力が想定されます。
Mon Nov 2 11:39:59 2020 +-----------------------------------------------------------------------------+ | NVIDIA-SMI 418.87.01 Driver Version: 418.87.01 CUDA Version: 10.1 | |-------------------------------+----------------------+----------------------+ | GPU Name Persistence-M| Bus-Id Disp.A | Volatile Uncorr. ECC | | Fan Temp Perf Pwr:Usage/Cap| Memory-Usage | GPU-Util Compute M. | |===============================+======================+======================| | 0 Tesla V100-SXM2... On | 00000000:00:07.0 Off | 0 | | N/A 37C P0 56W / 300W | 1929MiB / 16130MiB | 1% Default | +-------------------------------+----------------------+----------------------+ +-----------------------------------------------------------------------------+ | Processes: GPU Memory | | GPU PID Type Process name Usage | |=============================================================================| +-----------------------------------------------------------------------------+コンテナから見える合計メモリは 16,130 MiB であり、これは 16 GiB GPU カードの合計メモリです。これにより、cGPU のメモリ隔離が無効になっていることが確認できます。このシナリオでは、コンテナ内のアプリケーションは、次の環境変数から許可されたメモリクォータを決定する必要があります。次のコマンドを実行して、許可されている GPU メモリサイズをクエリします。
kubectl exec cgpu-test-no-isolation-0 -- env | grep ALIYUN次のような出力が想定されます。
ALIYUN_COM_GPU_MEM_CONTAINER=3 # このコンテナが GPU カード上で使用を許可されているメモリ量 (GiB)。この場合は 3 GiB。 ALIYUN_COM_GPU_MEM_DEV=15 # GPU カードの合計メモリ。 ... -
`cgpu-test-no-isolation-0` Pod と `cgpu-test-0` Pod からの
nvidia-smiの出力を比較します。`cgpu-test-no-isolation-0` の出力は GPU カード全体のメモリを示しているのに対し、`cgpu-test-0` の出力は割り当てられたメモリのスライスのみを示しています。これは、ノードプールが cGPU の機能を管理する効果的な方法であることを示しています。