Skip to content
Published on

[仮想化] 06. KubeVirt: Kubernetes上でVMを実行する

Authors

はじめに

コンテナと仮想マシン(VM)は代替品ではなく補完品です。レガシーアプリケーション、Windowsワークロード、カーネルレベルのカスタマイズが必要な場合には、依然としてVMが不可欠です。KubeVirtはKubernetes APIを拡張し、VMをPodのように管理できるようにするプロジェクトです。

KubeVirtとは?

KubeVirtはKubernetesネイティブのVMオーケストレーションソリューションです。Kubernetes APIを拡張し、VMのライフサイクルをkubectlで管理できます。

主な特徴

  • Kubernetes CRD(Custom Resource Definition)でVMを定義
  • 既存のKubernetesインフラ(ネットワーキング、ストレージ、モニタリング)を再利用
  • コンテナとVMが同一クラスタで共存
  • 実績あるlibvirt/QEMU/KVM仮想化スタックを活用

CNCFプロジェクト現況

KubeVirtはCNCF(Cloud Native Computing Foundation)の主要プロジェクトです。

項目詳細
CNCFレベルIncubating(Graduation申請中)
導入企業41社以上
CNCFランキングTop 20プロジェクト
GitHubスター5,000+
主要利用企業Red Hat、NVIDIA、ARM、CoreWeave

アーキテクチャ詳細

KubeVirtの全体アーキテクチャを見てみましょう。

+------------------------------------------------------------------+
|                    Kubernetes Control Plane                        |
|  +------------+  +----------------+  +-------------------------+  |
|  | API Server |  | etcd           |  | Controller Manager      |  |
|  +------+-----+  +----------------+  +-------------------------+  |
|         |                                                         |
|  +------v------------------+                                      |
|  | virt-api                |  <-- API拡張、バリデーション         |
|  | (Deployment)            |                                      |
|  +------+------------------+                                      |
|         |                                                         |
|  +------v------------------+                                      |
|  | virt-controller         |  <-- VM/VMI監視、ライフサイクル管理  |
|  | (Deployment)            |                                      |
|  +-------------------------+                                      |
+------------------------------------------------------------------+

+------------------------------------------------------------------+
|                    Worker Node                                     |
|  +-------------------------+                                      |
|  | virt-handler            |  <-- ノードレベルDaemonSet           |
|  | (DaemonSet)             |                                      |
|  +------+------------------+                                      |
|         |                                                         |
|  +------v------------------+  +-------------------------------+   |
|  | virt-launcher Pod       |  | virt-launcher Pod             |   |
|  |  +------------------+   |  |  +-------------------------+  |   |
|  |  | libvirt          |   |  |  | libvirt                 |  |   |
|  |  |  +------------+  |   |  |  |  +-------------------+  |  |   |
|  |  |  | QEMU/KVM   |  |   |  |  |  | QEMU/KVM         |  |  |   |
|  |  |  | (VM 1)     |  |   |  |  |  | (VM 2)           |  |  |   |
|  |  |  +------------+  |   |  |  |  +-------------------+  |  |   |
|  |  +------------------+   |  |  +-------------------------+  |   |
|  +-------------------------+  +-------------------------------+   |
+------------------------------------------------------------------+

コンポーネント詳細

virt-api

APIサーバーの拡張ポイントとして、VM関連のAPIリクエストを処理します。

  • Admission WebhookによるVMスペックのバリデーション
  • Subresource API提供(start、stop、restart、migrate)
  • VNC/Consoleプロキシエンドポイント

virt-controller

クラスタレベルのDeploymentで、VMとVMIリソースを監視します。

  • VM CRDの変更検知とVMI作成/削除
  • virt-launcher Podのスケジューリング要求
  • ライブマイグレーションのオーケストレーション
  • VM状態の同期

virt-handler

ノードレベルのDaemonSetで、実際のVMライフサイクルを管理します。

  • libvirtと直接通信
  • VMドメインXMLの生成と適用
  • ノードレベルのネットワーキング設定
  • デバイスホットプラグ処理

virt-launcher

各VMごとに作成されるPodです。

  • libvirtデーモンの実行
  • QEMU/KVMプロセスの管理
  • VMコンソールアクセスの提供
  • Pod終了時のVMクリーンアップ

CRD(Custom Resource Definitions)

VirtualMachine(VM)

VMはバーチャルマシンの宣言的定義です。Podに対するDeploymentと同様の役割を果たします。

apiVersion: kubevirt.io/v1
kind: VirtualMachine
metadata:
  name: my-vm
  namespace: default
spec:
  running: true
  template:
    metadata:
      labels:
        app: my-vm
    spec:
      domain:
        cpu:
          cores: 2
        memory:
          guest: 4Gi
        devices:
          disks:
            - name: rootdisk
              disk:
                bus: virtio
            - name: cloudinitdisk
              disk:
                bus: virtio
          interfaces:
            - name: default
              masquerade: {}
      networks:
        - name: default
          pod: {}
      volumes:
        - name: rootdisk
          dataVolume:
            name: my-vm-dv
        - name: cloudinitdisk
          cloudInitNoCloud:
            userData: |
              #cloud-config
              hostname: my-vm
              ssh_authorized_keys:
                - ssh-rsa AAAA...

VirtualMachineInstance(VMI)

VMIは実行中のVMインスタンスを表します。Podと同様に、実際の実行状態を反映します。

apiVersion: kubevirt.io/v1
kind: VirtualMachineInstance
metadata:
  name: my-vmi
spec:
  domain:
    cpu:
      cores: 1
    memory:
      guest: 2Gi
    devices:
      disks:
        - name: rootdisk
          disk:
            bus: virtio
  volumes:
    - name: rootdisk
      containerDisk:
        image: quay.io/kubevirt/fedora-cloud-container-disk-demo:latest

VirtualMachineInstanceReplicaSet

同一のVMIを複数レプリカで実行します。

apiVersion: kubevirt.io/v1
kind: VirtualMachineInstanceReplicaSet
metadata:
  name: my-vmirs
spec:
  replicas: 3
  selector:
    matchLabels:
      app: web-vm
  template:
    metadata:
      labels:
        app: web-vm
    spec:
      domain:
        cpu:
          cores: 1
        memory:
          guest: 1Gi
        devices:
          disks:
            - name: rootdisk
              disk:
                bus: virtio
      volumes:
        - name: rootdisk
          containerDisk:
            image: quay.io/kubevirt/fedora-cloud-container-disk-demo:latest

VirtualMachineInstanceMigration

VMIを別のノードにライブマイグレーションします。

apiVersion: kubevirt.io/v1
kind: VirtualMachineInstanceMigration
metadata:
  name: migration-job
spec:
  vmiName: my-vmi

CDI(Containerized Data Importer)

CDIはVMディスクイメージをKubernetes PVCにインポートするコンポーネントです。

DataVolume CRD

apiVersion: cdi.kubevirt.io/v1beta1
kind: DataVolume
metadata:
  name: ubuntu-dv
spec:
  source:
    http:
      url: 'https://cloud-images.ubuntu.com/jammy/current/jammy-server-cloudimg-amd64.img'
  storage:
    accessModes:
      - ReadWriteOnce
    resources:
      requests:
        storage: 10Gi
    storageClassName: local-path

様々なイメージソース

CDIは複数のソースからディスクイメージをインポートできます。

+------------------+     +-------+     +------------------+
| HTTP/HTTPS URL   | --> |       |     |                  |
+------------------+     |       |     |                  |
                         |       |     |                  |
+------------------+     |  CDI  | --> |  PersistentVolume|
| Container Registry| --> |       |     |  Claim (PVC)     |
+------------------+     |       |     |                  |
                         |       |     |                  |
+------------------+     |       |     |                  |
| S3 Bucket        | --> |       |     |                  |
+------------------+     +-------+     +------------------+
| oVirt / VMware   | -->
+------------------+

コンテナレジストリからのインポート

apiVersion: cdi.kubevirt.io/v1beta1
kind: DataVolume
metadata:
  name: registry-dv
spec:
  source:
    registry:
      url: 'docker://quay.io/kubevirt/fedora-cloud-container-disk-demo:latest'
  storage:
    accessModes:
      - ReadWriteOnce
    resources:
      requests:
        storage: 5Gi

S3からのインポート

apiVersion: cdi.kubevirt.io/v1beta1
kind: DataVolume
metadata:
  name: s3-dv
spec:
  source:
    s3:
      url: 's3://my-bucket/images/rhel9.qcow2'
      secretRef: s3-credentials
  storage:
    accessModes:
      - ReadWriteOnce
    resources:
      requests:
        storage: 20Gi

ネットワーキング

デフォルトPodネットワーク

デフォルトでVMはPodネットワークを使用します。masqueradeモードが推奨されます。

spec:
  domain:
    devices:
      interfaces:
        - name: default
          masquerade: {}
  networks:
    - name: default
      pod: {}

Multusによるマルチネットワーク

Multus CNIを使用すると、VMに複数のネットワークインターフェースを接続できます。

apiVersion: k8s.cni.cncf.io/v1
kind: NetworkAttachmentDefinition
metadata:
  name: br-vlan100
spec:
  config: |
    {
      "cniVersion": "0.3.1",
      "type": "bridge",
      "bridge": "br-vlan100",
      "vlan": 100,
      "ipam": {
        "type": "host-local",
        "subnet": "10.100.0.0/24"
      }
    }
---
apiVersion: kubevirt.io/v1
kind: VirtualMachine
metadata:
  name: multi-net-vm
spec:
  running: true
  template:
    spec:
      domain:
        devices:
          interfaces:
            - name: default
              masquerade: {}
            - name: vlan100
              bridge: {}
      networks:
        - name: default
          pod: {}
        - name: vlan100
          multus:
            networkName: br-vlan100

ストレージ

VMディスクはPVC(PersistentVolumeClaim)を通じて管理されます。

ストレージオプション比較

ストレージタイプ用途永続性
PVC永続ディスク永続
DataVolumeCDI経由のイメージインポート永続
containerDisk読み取り専用ブートイメージ一時
emptyDisk一時データ一時
cloudInitNoCloud初期設定データ一時

ライブマイグレーション

ライブマイグレーションは、VMを停止せずに別のノードに移動する機能です。

要件

  • ReadWriteMany(RWX)アクセスモードのPVC
  • 共有ストレージ(Ceph、NFSなど)
  • ソース/デスティネーションノード間で同一のCPU機能セット

マイグレーションの実行

# kubectlでマイグレーション開始
kubectl virt migrate my-vm

# またはMigration CRDを作成
cat <<EOF | kubectl apply -f -
apiVersion: kubevirt.io/v1
kind: VirtualMachineInstanceMigration
metadata:
  name: migration-my-vm
spec:
  vmiName: my-vm
EOF

# マイグレーション状態の確認
kubectl get vmim migration-my-vm -o yaml

マイグレーションポリシー設定

apiVersion: migrations.kubevirt.io/v1alpha1
kind: MigrationPolicy
metadata:
  name: high-priority-policy
spec:
  bandwidthPerMigration: 1Gi
  completionTimeoutPerGiB: 800
  allowAutoConverge: true
  selectors:
    namespaceSelector:
      matchLabels:
        migration-policy: high-priority

インストールガイド

Operatorインストール

# 最新バージョンの確認
export KUBEVIRT_VERSION=$(curl -s https://api.github.com/repos/kubevirt/kubevirt/releases/latest | grep tag_name | cut -d '"' -f 4)

# Operatorのデプロイ
kubectl apply -f "https://github.com/kubevirt/kubevirt/releases/download/$KUBEVIRT_VERSION/kubevirt-operator.yaml"

# KubeVirt CRの作成
kubectl apply -f "https://github.com/kubevirt/kubevirt/releases/download/$KUBEVIRT_VERSION/kubevirt-cr.yaml"

# インストール完了待機
kubectl wait kv kubevirt -n kubevirt --for=condition=Available --timeout=300s

ユースケース

1. ハイブリッドコンテナ/VMワークロード

マイクロサービス(コンテナ)とレガシーモノリス(VM)を一つのクラスタで運用します。

2. レガシーアプリケーションのマイグレーション

VMware、OpenStackなどで実行中の既存VMをKubernetesに段階的に移行します。

3. Windowsワークロード

.NET FrameworkアプリケーションやActive DirectoryサーバーをKubernetesクラスタで実行します。

4. 開発/テスト環境

多様なOS環境を迅速にプロビジョニングし、テストに活用します。

おわりに

KubeVirtはコンテナとVMの境界をなくし、統合インフラ管理を実現します。CNCFプロジェクトとして活発なコミュニティサポートを受けており、Red Hat OpenShift Virtualizationのコア技術でもあります。

次の記事では、NVIDIA GPU OperatorによるKubernetes上でのGPU自動管理方法を解説します。


クイズ:KubeVirt理解度チェック

Q1. KubeVirtでVMの宣言的定義を担当するCRDは?

A) VirtualMachineInstance B) VirtualMachine C) VirtualMachineInstanceReplicaSet D) VirtualMachineInstanceMigration

答え:B) VirtualMachine - Deploymentと同様に、VMの望ましい状態(desired state)を宣言します。


Q2. virt-launcherの役割は?

A) クラスタレベルでVMリソースを監視 B) APIリクエストのバリデーション C) 各VMごとに作成されるPodでlibvirt/QEMUを実行 D) ノードレベルでlibvirtと通信

答え:C) virt-launcherは各VMに対して1つのPodとして作成され、内部でlibvirtとQEMU/KVMプロセスを管理します。


Q3. CDIのDataVolumeがサポートしないイメージソースは?

A) HTTP/HTTPS URL B) コンテナレジストリ C) Gitリポジトリ D) S3バケット

答え:C) GitリポジトリはCDIソースとしてサポートされていません。HTTP、Registry、S3、oVirt、VMwareがサポートされます。


Q4. ライブマイグレーションの必須要件は?

A) ReadWriteOnce PVC B) ReadWriteMany PVC + 共有ストレージ C) emptyDiskボリューム D) containerDiskボリューム

答え:B) ライブマイグレーションには、ソース/デスティネーションノードから同時にアクセス可能な共有ストレージ(RWX)が必要です。