- はじめに — GPUノードセットアップ地獄からの脱出
- GPU Operatorは何をデプロイするのか
- インストール — Helmチャート一つで
- 検証 — ポッドからGPUが見えるか
- MIG — 一枚のGPUをハードウェアレベルで分割する
- MIG戦略 — single vs mixed
- MIGの適用 — ノードラベル一つで
- カスタムプロファイル — 一枚の中でサイズを混ぜる
- 運用上の注意 — 先に知っていれば障害にならないこと
- おわりに
- 参考資料
はじめに — GPUノードセットアップ地獄からの脱出
KubernetesクラスタにGPUノードを手作業で追加したことのある人なら分かるはずです。NVIDIAドライバーをカーネルバージョンに合わせてインストールし、container toolkitを入れ、ランタイム設定を変え、デバイスプラグインをデプロイし、モニタリングエクスポーターを付ける — この五層のバージョンの相性が一つでもずれると、ポッドはGPUを見つけられません。ノードが10台ならこの作業が10回、カーネルアップデートが来ればまた最初からです。
NVIDIA GPU Operator は、このスタック全体をKubernetesのオペレーターパターンで自動化します。管理者はHelmチャートを一つインストールし、望む状態を宣言すれば、オペレーターが各ノードに必要なコンポーネントをコンテナとしてデプロイし、継続的に調整(reconcile)します。この記事はインストールから検証、そしてA100/H100級GPUのキラー機能である MIG(Multi-Instance GPU)分割設定 までを、実際のコマンドとともに扱います。Kubernetesの基礎を先に固めたいなら、このサイトの Kubernetesプレイグラウンド もどうぞ。
GPU Operatorは何をデプロイするのか
オペレーターをインストールすると、gpu-operator ネームスペースに次のオペランド(operand)がDaemonSetとして配置されます。それぞれが、手作業時代にやっていた仕事の一つずつに対応します。
- NVIDIA Driver(コンテナ化) — ホストにドライバーを直接入れず、コンテナからカーネルモジュールをロードします。カーネルアップデート対応が劇的に楽になります。
- NVIDIA Container Toolkit — コンテナランタイムがGPUをポッドに公開できるようにします。
- Device Plugin —
nvidia.com/gpuリソースをKubernetesスケジューラに広告します。 - GPU Feature Discovery(GFD) — GPUのモデル・メモリ・MIG状態をノードラベルとして公開し、ノードセレクターで使えるようにします。
- DCGM Exporter — GPU使用率・メモリ・温度・電力をPrometheusメトリクスとして出力します。
- MIG Manager — この記事の主役。ノードラベルを監視し、MIGパーティションを実際にハードウェアへ適用します。
- Validator — 各段階が正常に動くか検証するジョブを回します。
インストール — Helmチャート一つで
前提条件は三つ:NVIDIA GPUを積んだノード、サポートされるコンテナランタイム(containerdなど)、そしてNode Feature Discovery(オペレーターがデフォルトで一緒にインストール)。
# 1) NVIDIAのHelmリポジトリを登録
helm repo add nvidia https://helm.ngc.nvidia.com/nvidia
helm repo update
# 2) インストール(バージョンはドキュメントで最新を確認 — 執筆時点 v26.3.3)
helm install --wait gpu-operator \
-n gpu-operator --create-namespace \
nvidia/gpu-operator \
--version=v26.3.3
環境によってよく使う変形が二つ:
# ノードにドライバーが既にインストール済みの場合(DGX OS、手動インストールなど)
helm install --wait gpu-operator \
-n gpu-operator --create-namespace \
nvidia/gpu-operator \
--version=v26.3.3 \
--set driver.enabled=false
# container toolkitも既にあるなら、さらに:
# --set toolkit.enabled=false
インストール状態の確認:
kubectl get pods -n gpu-operator
# driver-daemonset, container-toolkit, device-plugin, dcgm-exporter,
# gpu-feature-discovery, operator-validator がすべて Running/Completed なら正常
検証 — ポッドからGPUが見えるか
最も確実な検証は、GPUを要求するテストポッドです。
apiVersion: v1
kind: Pod
metadata:
name: gpu-smoke-test
spec:
restartPolicy: Never
containers:
- name: nvidia-smi
image: nvidia/cuda:12.4.1-base-ubuntu22.04
command: ['nvidia-smi']
resources:
limits:
nvidia.com/gpu: 1
kubectl apply -f gpu-smoke-test.yaml
kubectl logs gpu-smoke-test
# nvidia-smi の出力にGPUモデルが表示されれば成功
GFDが付けたノードラベルも確認しておくと、ノードセレクターを書くときに便利です。
kubectl get node <ノード名> -o jsonpath='{.metadata.labels}' | jq . | grep nvidia
# nvidia.com/gpu.product, nvidia.com/gpu.memory, nvidia.com/gpu.count など
MIG — 一枚のGPUをハードウェアレベルで分割する
A100/H100のようなデータセンターGPUは、一枚では大きすぎます。小さな推論ワークロード一つが80GBのGPUを丸ごと占有すると、残りの容量は遊んでしまいます。MIG(Multi-Instance GPU) はAmpere世代からサポートされる機能で、GPU一枚を最大7個の ハードウェア分離されたインスタンス に分割します。
核心は「ハードウェア分離」です。各MIGインスタンスは自分の取り分のSM(演算ユニット)、L2キャッシュ、メモリ帯域を物理的に割り当てられます。タイムスライシング(time-slicing)との決定的な違いがここにあります — タイムスライシングは複数のポッドがGPUを交互に使うため、あるポッドの暴走が別のポッドの遅延に波及しますが、MIGは隣のインスタンスが何をしていようと自分の性能が保証されます。マルチテナントクラスタ、推論サービング、チーム別GPU割り当てでMIGが好まれる理由です。
プロファイル名は <GI数>g.<メモリ>gb 形式です。たとえばH100 80GB一枚は代表的に次のように分割できます:
プロファイル インスタンス数(最大) 用途の感覚
1g.10gb ×7 小型推論を7個
2g.20gb ×3 中型推論/実験を3個
3g.40gb ×2 中大型学習を2個
7g.80gb ×1 分割せず丸ごと
(混合も可能:例 — 3g.40gb 1個 + 2g.20gb 1個 + 1g.10gb 2個)
A100 40GBなら同じ原理で 1g.5gb×7、2g.10gb×3、3g.20gb×2 … となります。正確な組み合わせ規則はGPUモデルごとに異なるので、NVIDIA MIGユーザーガイド のプロファイル表を基準にしてください。
MIG戦略 — single vs mixed
GPU OperatorでMIGを使うには、インストール時に 戦略(strategy) をまず決めます。この選択がKubernetesへのリソースの広告のされ方を変えます。
- single — ノードのすべてのGPUがMIGになり、すべて同じプロファイルで分割されます。リソースはおなじみの
nvidia.com/gpuの名前のまま広告され、数だけが増えます(例:H100 1枚 →nvidia.com/gpu: 7)。ポッドのスペックを変える必要がなく、導入が最も簡単です。 - mixed — ノード内で異なるプロファイル(MIG未適用のGPUさえ)が共存します。リソースはプロファイル別の名前で広告されます(例:
nvidia.com/mig-1g.10gb、nvidia.com/mig-3g.40gb)。柔軟ですが、ポッドがプロファイルを明示する必要があります。
# single戦略でインストール
helm install --wait gpu-operator \
-n gpu-operator --create-namespace \
nvidia/gpu-operator \
--version=v26.3.3 \
--set mig.strategy=single
# クラウド(GKE/EKSなど)のように再起動が必要な環境なら追加:
# --set migManager.env[0].name=WITH_REBOOT \
# --set-string migManager.env[0].value=true
インストール済みのクラスタで戦略だけ変えるにはClusterPolicyをパッチします:
kubectl patch clusterpolicies.nvidia.com/cluster-policy \
--type='json' \
-p='[{"op":"replace", "path":"/spec/mig/strategy", "value":"mixed"}]'
MIGの適用 — ノードラベル一つで
MIG Managerの動作原理は優雅なほどシンプルです。nvidia.com/mig.config ノードラベルを監視し、ラベルが変わるとそのプロファイルをハードウェアに適用 します。
# H100ノードを 1g.10gb ×7 に分割
kubectl label nodes <ノード名> nvidia.com/mig.config=all-1g.10gb --overwrite
デフォルト提供のプロファイルには all-disabled(MIGを切る)、all-1g.10gb、all-2g.20gb、all-3g.40gb、all-balanced(複数サイズをバランスよく混合)などがあります。適用の進行はラベルで追跡します:
kubectl get node <ノード名> -o jsonpath='{.metadata.labels}' | jq . | grep mig
# nvidia.com/mig.config.state が
# pending → (必要なら rebooting)→ success になれば完了
success 後にリソースを確認すると分割結果が見えます:
kubectl describe node <ノード名> | grep -A5 'Allocatable'
# single戦略: nvidia.com/gpu: 7 (ラベルの gpu.product に MIG-1g.10gb と表示)
# mixed 戦略: nvidia.com/mig-1g.10gb: 7 のようにプロファイル別リソース
mixed戦略では、ポッドはこのように特定プロファイルを要求します:
resources:
limits:
nvidia.com/mig-1g.10gb: 1
カスタムプロファイル — 一枚の中でサイズを混ぜる
デフォルトのプロファイルで足りない場合(例:「GPU 0番だけ3g+1g+1gの混合、残りはMIGオフ」)、ConfigMapで直接定義します。
apiVersion: v1
kind: ConfigMap
metadata:
name: custom-mig-config
namespace: gpu-operator
data:
config.yaml: |
version: v1
mig-configs:
all-disabled:
- devices: all
mig-enabled: false
inference-mix:
- devices: [0]
mig-enabled: true
mig-devices:
"1g.10gb": 5
"2g.20gb": 1
- devices: [1, 2, 3]
mig-enabled: false
# MIG ManagerがこのConfigMapを使うようClusterPolicyをパッチ
kubectl patch clusterpolicies.nvidia.com/cluster-policy \
--type='json' \
-p='[{"op":"replace", "path":"/spec/migManager/config/name", "value":"custom-mig-config"}]'
# ノードにカスタムプロファイルを適用
kubectl label nodes <ノード名> nvidia.com/mig.config=inference-mix --overwrite
なお v26.3.0 からは、MIG Managerが起動時にNVMLでノードのハードウェアを照会し、可能なプロファイル一覧をランタイムで自動生成 してノードごとのConfigMapに書き出します。新しいGPUモデルが出ても、組み込みプロファイル一覧の更新を待つ必要がなくなりました。
運用上の注意 — 先に知っていれば障害にならないこと
- 再構成は破壊的な作業です。 MIG Managerはプロファイルを変える前に、対象GPU上のすべてのポッド(デバイスプラグイン・DCGM・GFDを含む)を停止します。ユーザーワークロードが走るノードなら、先に cordon + drain するのが安全な運用手順です。
- クラウドでは再起動が必要な場合があります。 一部のCSP環境はMIGモードの切り替えにノード再起動が必要です — 上記の
WITH_REBOOT設定がその対応です。mig.config.stateがrebootingを経由するのは正常なフローです。 - ポッドはインスタンスをまたげません。 MIGインスタンス一つがポッド一つの上限です。7gプロファイルが必要な大型学習が来る可能性があるなら、mixed戦略か別のノードプールを用意してください。インスタンス間のNVLink P2Pも使えません。
- 状態が
pendingで止まったら、まずMIG Managerポッドのログを見てください。よくある原因:ラベルのタイポ(存在しないプロファイル名)、そのGPUがサポートしない組み合わせ、まだGPUを掴んでいるポッド。 - モニタリングはDCGMで。 DCGM ExporterはMIGインスタンス単位のメトリクスを出すので、Prometheusでインスタンス別の使用率・メモリがそのまま見えます。「分割したのに遊んでいる」インスタンスを見つけるのがMIG運用の後半戦です。
- タイムスライシングとの使い分け:分離と予測可能性が必要ならMIG、オーバーサブスクリプション(とにかく多くのポッドを載せる)が目的で干渉を許容できるならtime-slicing — 二つの機能は目的が違います。
おわりに
GPU Operatorは「GPUノードのセットアップ」という反復労働を宣言的リソース一つに変え、MIG Managerはその上で高価なGPUの稼働率問題をラベル一行で扱えるようにしてくれます。要約すると:Helmでインストールし、戦略(single/mixed)を決め、nvidia.com/mig.config ラベルで分割し、mig.config.state で確認し、DCGMで観察する — この五つの文がすべてです。残りは自分のワークロードに合うプロファイルを見つける仕事で、それはモニタリングデータが教えてくれます。
LinuxとKubernetesの基礎を一緒に固めたいなら、Linuxターミナル と クベストロノートクイズ も活用してみてください。
参考資料
현재 단락 (1/114)
KubernetesクラスタにGPUノードを手作業で追加したことのある人なら分かるはずです。NVIDIAドライバーをカーネルバージョンに合わせてインストールし、container toolkitを入れ...