Skip to content
Published on

GPU Operator × KubeVirt 総まとめ — コンポーネント・設定・バージョン、部分MIGと手動MIGまで

シェア
Authors

はじめに — コンテナのGPU、VMのGPU

Kubernetes上のGPUインフラは二つの世界に分かれます。コンテナにGPUを差し込む世界(GPU Operator)と、Kubernetes上で仮想マシンを動かしてGPUを丸ごと渡す世界(KubeVirt)です。面白いのは、この二つが最終的に一つのスタックで出会うという点です — GPU OperatorはKubeVirt VM向けのGPUプロビジョニングまで担当します。本記事では両方の柱のコンポーネント・設定・バージョンを総整理し、よく聞かれる二つのテーマ — 一部のGPUだけへのMIG適用MIGの手動操作 — を実践コマンドで扱います。GPU OperatorインストールとMIG基礎編を先に読んでおくと、この記事は二倍わかりやすくなります。

第1部 — GPU Operator: コンポーネント・設定・バージョン

コンポーネント (オペランド)

GPU Operatorは「GPUノードに必要なものすべて」をDaemonSetのオペランドとしてデプロイし、一つのClusterPolicyで調整するオペレーターです。

オペランド                 役割
─────────────────────────  ─────────────────────────────────────
driver                     NVIDIAドライバーをコンテナとしてロード
container-toolkit          ランタイムがGPUをコンテナに公開するよう設定
device-plugin              nvidia.com/gpuリソースをスケジューラーに広告
gpu-feature-discovery      GPUモデル・メモリ・MIG状態をノードラベルに
dcgm-exporter              使用率・温度・電力をPrometheusメトリクスに
mig-manager                ノードラベルベースのMIGパーティショニング
node-feature-discovery     ハードウェア検出 (依存コンポーネント)
validator                  各段階の検証ジョブ
(sandbox系)                vfio-manager, vgpu-device-manager,
                           kubevirt-gpu-device-plugin — 第5部にて

設定 — ClusterPolicyが単一の真実

すべてのオペランドの設定は clusterpolicies.nvidia.com/cluster-policy という一つのCRに集約されます。Helmの --set は、結局このCRのフィールドを埋めるものです。実務でよく触るフィールド:

# ClusterPolicyの主要フィールド (抜粋)
spec:
  driver:
    enabled: true          # ノードに既にドライバーがあればfalse
    version: "580.65.06"   # ドライバーバージョンを固定
  toolkit:
    enabled: true
  mig:
    strategy: mixed        # single | mixed
  migManager:
    enabled: true
    config:
      name: custom-mig-config   # カスタムMIGプロファイルのConfigMap
    env:
      - name: WITH_REBOOT       # CSPのように再起動が必要な環境
        value: "true"
  devicePlugin:
    config:
      name: time-slicing-config # タイムスライシング設定もConfigMapで
  sandboxWorkloads:
    enabled: false         # KubeVirt連携時はtrue (第5部)

変更はHelmアップグレードまたは kubectl patch clusterpolicies... で行い、オペレーターが変更を検知して該当するオペランドだけを再構成します。

バージョン体系

GPU Operatorは年ベースのバージョン(vYY.N.パッチ)を採用しています — 本記事執筆時点の最新系列はv26.x(例: v26.3.3)で、その前にはv25.x、v24.9、v23.9の系列があります。各リリースがサポートするドライバーバージョンのセットとKubernetesバージョンの範囲はドキュメントに明記されているため、アップグレード前の互換性マトリクスの確認は必須です。覚えておくべき原則: オペレーターのバージョンがドライバーのバージョンを管理するので、ドライバーだけを個別に上げたい場合はClusterPolicyの driver.version を使うのが定石です。

第2部 — 一部のGPUだけにMIGを適用する

GPUを8枚積んだノードで「0番GPUだけを細かく分割して推論用に、残りの7枚は丸ごと学習用に」という要件は非常によくあります。答えはmixed戦略 + カスタムMIG設定です。

apiVersion: v1
kind: ConfigMap
metadata:
  name: custom-mig-config
  namespace: gpu-operator
data:
  config.yaml: |
    version: v1
    mig-configs:
      # 0番GPUだけMIG、1〜7番はそのまま
      partial-mig:
        - devices: [0]
          mig-enabled: true
          mig-devices:
            "1g.10gb": 4
            "3g.40gb": 1
        - devices: [1, 2, 3, 4, 5, 6, 7]
          mig-enabled: false
# ① ClusterPolicyがこのConfigMapを参照するよう指定 (設定済みなら省略)
kubectl patch clusterpolicies.nvidia.com/cluster-policy --type='json' \
  -p='[{"op":"replace","path":"/spec/migManager/config/name","value":"custom-mig-config"}]'

# ② 戦略がmixedであることを確認 — プロファイルが混在するためsingleでは表現できない
kubectl patch clusterpolicies.nvidia.com/cluster-policy --type='json' \
  -p='[{"op":"replace","path":"/spec/mig/strategy","value":"mixed"}]'

# ③ ノードにプロファイルを適用
kubectl label nodes <ノード> nvidia.com/mig.config=partial-mig --overwrite

# ④ 結果: リソースは次のように広告されます
#   nvidia.com/gpu: 7                ← MIGしていない7枚
#   nvidia.com/mig-1g.10gb: 4        ← 0番から切り出された断片
#   nvidia.com/mig-3g.40gb: 1

Podは用途に応じて nvidia.com/gpu(丸ごと)または nvidia.com/mig-1g.10gb(断片)をリクエストするだけです。核心ルールは二つ — プロファイルがGPU間で異なる場合は必ずmixed戦略でなければならないこと、そして devices リストに載っていないGPUの挙動を明示するには mig-enabled: false のエントリを必ず併記すること(暗黙の状態に任せないでください)。

第3部 — MIGの手動適用: nvidia-smiで直接操作する

Kubernetesの外のベアメタルサーバーや、mig-managerを使わない環境では、nvidia-smi mig で直接パーティショニングします。GPU Operatorが内部で行っているのはまさにこれなので、一度手を動かしてみると、オペレーターをデバッグする力も一緒に鍛えられます。

# ① MIGモードを有効化 (GPU 0番のみ) — 先に対象GPUのプロセスを空けておく必要あり
sudo nvidia-smi -i 0 -mig 1
# "Pending" と表示されたらGPUリセットまたは再起動が必要:
sudo nvidia-smi --gpu-reset -i 0

# ② 作成できるGPUインスタンス(GI)のプロファイルを確認
nvidia-smi mig -lgip
#  例: H100 80GB → 1g.10gb(ID 19), 2g.20gb(14), 3g.40gb(9), 7g.80gb(0) ...

# ③ GIを作成 — 3g.40gbを1個 + 1g.10gbを4個、-C はコンピュートインスタンス(CI)まで自動作成
sudo nvidia-smi mig -i 0 -cgi 9,19,19,19,19 -C

# ④ 確認
nvidia-smi mig -lgi        # 作成されたGIの一覧
nvidia-smi -L              # MIGデバイスのUUID一覧 (MIG-xxxx形式)

# ⑤ 特定のインスタンスで実行 — UUIDで指定
CUDA_VISIBLE_DEVICES=MIG-<uuid> python infer.py

# ⑥ 解除 — CI → GI の順に削除してからMIGモードを無効化
sudo nvidia-smi mig -i 0 -dci && sudo nvidia-smi mig -i 0 -dgi
sudo nvidia-smi -i 0 -mig 0

押さえておきたい概念: MIGは GI(GPU Instance — メモリ・SMのハードウェア分割) の中に CI(Compute Instance — SMの再分割) が入る2段構造です。ほとんどの場合はGIごとにCI一つ(-C オプション)で十分で、CIをさらに分割するのは、同じメモリパーティションを共有しながら演算だけを分けたい特殊なケースです。また、②のプロファイルIDはGPUモデルごとに異なるため、必ず先に -lgip で確認してください。

第4部 — KubeVirt: コンポーネント・設定・バージョン

なぜKubernetesでVMなのか

コンテナに移せないワークロードは意外と多いものです — カーネルモジュールが必要なレガシー、Windowsゲスト、強い分離が求められるマルチテナントGPU環境。KubeVirtはVMをKubernetesの一級市民(CRD)にすることで、PodとVMを同じクラスター・同じネットワーク・同じkubectlで扱えるようにします。

4大コンポーネント

コンポーネント    形態          役割
──────────────  ───────────  ─────────────────────────────────────
virt-operator    Deployment   KubeVirt自体のインストール・アップグレード管理
virt-controller  Deployment   クラスターレベルのVMライフサイクル (VMI作成など)
virt-handler     DaemonSet    ノードレベルのデーモン — VMIスペックとlibvirtドメインを同期
virt-launcher    Pod(VMごと1)  VMを包むPod — 内部のlibvirtdがQEMU/KVMを起動

流れは次のとおりです: ユーザーが VirtualMachine CRを作成すると → virt-controllerが VirtualMachineInstance(VMI)とvirt-launcher Podを作成し → 該当ノードのvirt-handlerがVMIスペックをlibvirtドメインに翻訳し → virt-launcher内のlibvirtdがQEMU/KVMプロセスを起動します。VMはまさにPodの中のプロセスなので、Kubernetesのネットワーキング・スケジューリングがそのまま適用されます。ディスクイメージの取り込みは、別プロジェクトの CDI(Containerized Data Importer) がDataVolume CRDで担当します。

設定 — KubeVirt CRとfeatureGates

KubeVirtのグローバル設定も一つのCR(kubevirt.io/v1KubeVirt)に集約されます。GPUパススルーに必要な核心設定:

apiVersion: kubevirt.io/v1
kind: KubeVirt
metadata:
  name: kubevirt
  namespace: kubevirt
spec:
  configuration:
    developerConfiguration:
      featureGates:
        - GPU                 # VMへのGPU割り当てを許可
        - HostDevices
    permittedHostDevices:     # どのホストデバイスをVMに渡せるか
      pciHostDevices:
        - pciVendorSelector: "10de:2331"     # NVIDIA H100 (vendor:device)
          resourceName: "nvidia.com/GH100_H100_PCIE"
          externalResourceProvider: true     # GPU Operatorのプラグインが広告

バージョンの特徴

KubeVirtは2023年にv1.0でプロダクション対応を宣言し、以降は四半期ごとのマイナーリリース(v1.1、v1.2、…)でv1.x系を継続しています。CNCFのインキュベーティングプロジェクトであり、リリースごとにサポートするKubernetesバージョンの範囲が明記されます(おおむね最新のK8s 3バージョン)。体感できる変化の軸は、instancetype/preference APIの成熟(VMサイズをTシャツサイズのように宣言)、メモリホットプラグ・CPUホットプラグといったライブリソース調整、そしてライブマイグレーションの堅牢化です。GPUをパススルーしたVMは、デバイスがノードに物理的に固定されるためライブマイグレーションができないという制約があります — これはバージョンとは無関係な物理法則として覚えておいてください。

第5部 — 二つの世界の接続: GPU Operator × KubeVirt

GPU Operatorを sandboxWorkloads.enabled=true でインストールすると、VM向けのGPUプロビジョニングまで担当するようになります。

helm install --wait gpu-operator \
  -n gpu-operator --create-namespace \
  nvidia/gpu-operator --version=v26.3.3 \
  --set sandboxWorkloads.enabled=true

このとき、ノードラベル nvidia.com/gpu.workload.config がスイッチになります:

値               ノードの用途           デプロイされるオペランド
──────────────  ────────────────────  ─────────────────────────────
container        通常のGPUコンテナ      driver, device-plugin, ... (第1部の構成)
vm-passthrough   VMにGPUを丸ごと       vfio-manager (vfio-pciバインド),
                                       kubevirt-gpu-device-plugin
vm-vgpu          VMにvGPUの断片        vgpu-manager, vgpu-device-manager

パススルーノードでは、vfio-managerが(ホストドライバーの代わりに)GPUを vfio-pci ドライバーにバインドし、kubevirt-gpu-device-pluginがそのデバイスを nvidia.com/GH100_H100_PCIE のようなリソースとして広告します。VMスペックでは次のようにリクエストします:

# VirtualMachineスペック抜粋
spec:
  template:
    spec:
      domain:
        devices:
          gpus:
            - deviceName: nvidia.com/GH100_H100_PCIE
              name: gpu1

まとめると — 同じクラスターでラベルを変えるだけで、あるノードはコンテナGPU、あるノードはVMパススルー、あるノードはvGPUとして運用できます。強い分離(セキュリティ・ドライバーの自由度)が必要ならVMパススルー、密度が必要ならコンテナ + MIG、その中間がvGPU、という感覚で選ぶとよいでしょう。

おわりに

GPU Operatorは一つのClusterPolicyでオペランドの艦隊を指揮し、KubeVirtは4つのコンポーネントでVMをPodの世界に編入し、両者はsandboxWorkloadsとworkload.configラベルで出会います。部分MIGはmixed戦略 + devicesリストで、手動MIGは nvidia-smi mig -cgi/-dgi で — オペレーターが自動化してくれている仕事の正体を知れば、障害が起きたときにどこを見ればよいかも見えてきます。Kubernetesの基礎感覚はKubernetesプレイグラウンドKubestronautクイズで鍛えられます。

参考資料