KubeVirt

KubeVirt 包括的技術概要

目次

  1. はじめに
  2. KubeVirtとは
  3. アーキテクチャ概要
  4. コアコンポーネント
  5. カスタムリソース定義(CRD)
  6. インストールと環境構築
  7. 仮想マシンの作成と管理
  8. ストレージ管理
  9. ネットワーク構成
  10. ライブマイグレーション
  11. Feature Gates と高度な設定
  12. CDI(Containerized Data Importer)
  13. 運用とベストプラクティス
  14. ユースケースと適用シナリオ
  15. まとめ

はじめに

企業のIT基盤において、従来の仮想マシン(VM)ベースのワークロードとコンテナベースのクラウドネイティブワークロードの共存は、多くの組織が直面する重要な課題である。KubeVirtは、この課題に対する革新的なソリューションとして、Kubernetes上で仮想マシンをネイティブに実行できるようにするオープンソースプロジェクトである。

本記事では、KubeVirtの全体像を包括的に解説し、アーキテクチャ、コアコンポーネント、インストール方法、仮想マシンの作成・管理、ストレージ、ネットワーク、ライブマイグレーションなどの主要機能について、具体的な設定例を交えながら詳細に説明する。


KubeVirtとは

概要

KubeVirtは、Kubernetesのカスタムリソースとオペレーターパターンを活用して、従来の仮想マシンワークロードをKubernetesクラスター上で管理可能にするプロジェクトである。Cloud Native Computing Foundation(CNCF)のIncubating Projectとして位置づけられている。

設計思想

KubeVirtの設計は「KubeVirt Razor」と呼ばれる原則に基づいている:

「Podにとって有用なものは、VMだけのために実装すべきではない」

この原則は、VMとコンテナの機能的な一貫性を保証し、Kubernetesエコシステムとの深い統合を実現する。KubeVirtはKubernetesのスケジューリング、ネットワーキング、ストレージ機能を直接活用しつつ、仮想化機能を追加レイヤーとして提供する。

KubeVirtが解決する課題

課題KubeVirtによる解決策
レガシーVMワークロードの移行Kubernetes上でVMを直接実行可能
統一的なインフラ管理コンテナとVMを同一のKubernetes APIで管理
運用の複雑性既存のKubernetesツールチェーンをそのまま活用
スケジューリングの最適化KubernetesスケジューラーによるVM配置
ネットワーク統合Kubernetes CNIプラグインの活用

アーキテクチャ概要

全体アーキテクチャ

KubeVirtはサービス指向アーキテクチャ(SOA)とコレオグラフィパターンを採用している。Kubernetesの上にレイヤーとして構築され、スケジューリング、ネットワーキング、ストレージをオーケストレーターに委譲しつつ、仮想化機能を提供する。

┌─────────────────────────────────────────────────────────────────┐
│                      Kubernetes Cluster                         │
│                                                                 │
│  ┌───────────────────────────────────────────────────────────┐  │
│  │                   KubeVirt Layer                          │  │
│  │                                                           │  │
│  │  ┌─────────────┐  ┌──────────────────┐  ┌─────────────┐  │  │
│  │  │  virt-api    │  │ virt-controller  │  │   CRDs      │  │  │
│  │  │  (API GW)    │  │ (Cluster Logic)  │  │  VM/VMI/    │  │  │
│  │  └─────────────┘  └──────────────────┘  │  VMIRS      │  │  │
│  │                                          └─────────────┘  │  │
│  │  ┌──────────────────────────────────────────────────────┐ │  │
│  │  │              Per-Node Components                      │ │  │
│  │  │  ┌──────────────┐    ┌───────────────────────────┐   │ │  │
│  │  │  │ virt-handler │    │     virt-launcher Pod     │   │ │  │
│  │  │  │ (DaemonSet)  │    │  ┌─────────┐ ┌────────┐  │   │ │  │
│  │  │  └──────────────┘    │  │libvirtd │ │  QEMU  │  │   │ │  │
│  │  │                      │  └─────────┘ └────────┘  │   │ │  │
│  │  │                      └───────────────────────────┘   │ │  │
│  │  └──────────────────────────────────────────────────────┘ │  │
│  └───────────────────────────────────────────────────────────┘  │
│                                                                 │
│  ┌───────────────────────────────────────────────────────────┐  │
│  │          Kubernetes Native Services                       │  │
│  │  Scheduler │ API Server │ CNI │ CSI │ etcd              │  │
│  └───────────────────────────────────────────────────────────┘  │
└─────────────────────────────────────────────────────────────────┘

処理フロー

  1. ユーザーがKubernetes API Serverに仮想マシンの仕様を送信
  2. virt-controllerが新しいオブジェクトを検知し、スケジューリングをオーケストレーション
  3. Kubernetesスケジューラーがvirt-launcher Podを適切なノードに配置
  4. virt-handlerデーモンがノード上でVMの起動と構成を実行
  5. libvirtdとQEMUが実際の仮想マシンプロセスを管理

コアコンポーネント

virt-api

virt-apiは、KubeVirtのAPIゲートウェイとして機能するコンポーネントである。Kubernetes API Serverの拡張として動作し、以下の役割を担う:

  • 仮想マシン関連のAPIリクエストの検証
  • Webhook Admissionコントローラーとしてのリソースバリデーション
  • SubresourceAPI(コンソールアクセス、VNC接続など)の提供
  • APIバージョニングの管理

virt-controller

virt-controllerは、クラスター全体の仮想マシンオブジェクトを管理するコントローラーである:

  • VirtualMachineおよびVirtualMachineInstanceの状態管理
  • VMIのライフサイクル制御(作成、起動、停止、削除)
  • virt-launcher Podの作成・管理
  • ライブマイグレーションの制御
  • ReplicaSetのスケーリング
# virt-controller は Deployment として実行される
apiVersion: apps/v1
kind: Deployment
metadata:
  name: virt-controller
  namespace: kubevirt
spec:
  replicas: 2
  selector:
    matchLabels:
      kubevirt.io: virt-controller

virt-handler

virt-handlerは、各ノードで実行されるDaemonSetとして配置され、以下の責務を持つ:

  • ノード上のVMIの監視と管理
  • libvirtdを介したVM操作の実行
  • VMの実際の状態とAPIオブジェクトの同期
  • コンソールアクセスのプロキシ
  • ノード固有のネットワーク・ストレージの構成
# virt-handler は DaemonSet として各ノードで実行
apiVersion: apps/v1
kind: DaemonSet
metadata:
  name: virt-handler
  namespace: kubevirt
spec:
  selector:
    matchLabels:
      kubevirt.io: virt-handler

virt-launcher

virt-launcherは、各VMI用に作成されるPod内で実行される。Podのライフサイクルと仮想マシンのライフサイクルを結びつける重要な役割を担う:

  • 1つのvirt-launcher Podが1つのVMIを管理
  • libvirtdデーモンのローカルインスタンスを実行
  • QEMUプロセスの起動と監視
  • コンテナの死活監視メカニズムを活用したVM管理
  • cgroup による リソース制限の適用

libvirtd

各virt-launcher Pod内で実行され、以下を提供する:

  • VMのハイパーバイザー管理
  • デバイスの構成と管理
  • ホットプラグ操作の制御
  • ライブマイグレーションの実行

カスタムリソース定義(CRD)

KubeVirtは、Kubernetesを拡張する3つの主要なカスタムリソースを定義する。

VirtualMachineInstance(VMI)

VMIは、KubeVirtの最も基本的なリソースであり、実行中の仮想マシンインスタンスを表現する。Kubernetesの Pod に相当するエフェメラルなリソースである。

apiVersion: kubevirt.io/v1
kind: VirtualMachineInstance
metadata:
  name: my-vmi
spec:
  domain:
    devices:
      disks:
      - name: containerdisk
        disk:
          bus: virtio
      - name: cloudinitdisk
        disk:
          bus: virtio
      interfaces:
      - name: default
        masquerade: {}
    machine:
      type: q35
    resources:
      requests:
        memory: 1Gi
        cpu: "1"
  networks:
  - name: default
    pod: {}
  volumes:
  - name: containerdisk
    containerDisk:
      image: quay.io/containerdisks/fedora:latest
  - name: cloudinitdisk
    cloudInitNoCloud:
      userData: |
        #cloud-config
        hostname: my-vm
        ssh_authorized_keys:
          - ssh-rsa AAAA...
        packages:
          - nginx
        runcmd:
          - systemctl enable nginx
          - systemctl start nginx

主要フィールド解説:

フィールド説明
spec.domain.resourcesCPU・メモリのリソース要求と制限
spec.domain.devices.disks仮想ディスクデバイスの定義
spec.domain.devices.interfacesネットワークインターフェースの定義
spec.domain.machine.typeマシンタイプ(q35推奨)
spec.networksネットワーク接続の定義
spec.volumesボリュームソースの定義

VirtualMachine(VM)

VMは、VMIのステートフルなラッパーであり、起動・停止・再起動のライフサイクル管理を提供する。Kubernetes の Deployment に相当する概念である。

apiVersion: kubevirt.io/v1
kind: VirtualMachine
metadata:
  name: my-vm
spec:
  running: true
  template:
    metadata:
      labels:
        kubevirt.io/vm: my-vm
    spec:
      domain:
        devices:
          disks:
          - name: rootdisk
            disk:
              bus: virtio
          - name: cloudinitdisk
            disk:
              bus: virtio
          interfaces:
          - name: default
            masquerade: {}
        resources:
          requests:
            memory: 2Gi
            cpu: "2"
      networks:
      - name: default
        pod: {}
      volumes:
      - name: rootdisk
        dataVolume:
          name: my-vm-rootdisk
      - name: cloudinitdisk
        cloudInitNoCloud:
          userData: |
            #cloud-config
            hostname: my-vm
            user: admin
            password: changeme
            chpasswd:
              expire: false
  dataVolumeTemplates:
  - metadata:
      name: my-vm-rootdisk
    spec:
      storage:
        accessModes:
        - ReadWriteOnce
        resources:
          requests:
            storage: 10Gi
      source:
        registry:
          url: docker://quay.io/containerdisks/fedora:latest

VM固有の機能:

  • spec.running: true/false でVMの起動・停止を制御
  • spec.runStrategy: より詳細な実行戦略(AlwaysManualHaltedRerunOnFailure
  • spec.dataVolumeTemplates: VMのライフサイクルに紐づくDataVolumeの自動作成
  • リスタート時のAPI安定性の保証

VirtualMachineInstanceReplicaSet(VMIRS)

VMIRSは、同一構成のエフェメラルVMIのグループを管理する。Kubernetes の ReplicaSet に相当する。

apiVersion: kubevirt.io/v1
kind: VirtualMachineInstanceReplicaSet
metadata:
  name: my-vmirs
spec:
  replicas: 3
  selector:
    matchLabels:
      kubevirt.io/vmReplicaSet: my-vmirs
  template:
    metadata:
      labels:
        kubevirt.io/vmReplicaSet: my-vmirs
    spec:
      domain:
        devices:
          disks:
          - name: containerdisk
            disk:
              bus: virtio
        resources:
          requests:
            memory: 512Mi
      volumes:
      - name: containerdisk
        containerDisk:
          image: quay.io/containerdisks/fedora:latest

インスタンスタイプとプリファレンス

KubeVirtは、VMの構成を標準化するためのインスタンスタイプとプリファレンスメカニズムを提供する。

apiVersion: instancetype.kubevirt.io/v1beta1
kind: VirtualMachineInstancetype
metadata:
  name: u1.small
spec:
  cpu:
    guest: 2
  memory:
    guest: 2Gi

---
apiVersion: instancetype.kubevirt.io/v1beta1
kind: VirtualMachinePreference
metadata:
  name: fedora
spec:
  devices:
    preferredDiskBus: virtio
    preferredInterfaceModel: virtio
  features:
    preferredSmm:
      enabled: true

これらを使用したVM作成:

# virtctl を使用したインスタンスタイプベースのVM作成
virtctl create vm --name my-vm \
  --instancetype u1.small \
  --preference fedora \
  --volume-containerdisk=src:quay.io/containerdisks/fedora:latest

インストールと環境構築

前提条件

KubeVirtをデプロイするには、以下の要件を満たす必要がある:

要件詳細
Kubernetesクラスターリリース時点の最新3バージョンのいずれか
API Server設定--allow-privileged=true
コンテナランタイムcontainerd または crio(runv対応)
ハードウェア仮想化Intel VT-x / AMD-V(推奨)
SELinuxcontainer-selinux 2.170.0以上
kubectlクライアントユーティリティ

ハードウェア仮想化の検証

# ホストの仮想化対応を確認
virt-host-validate qemu

# 出力例:
# QEMU: Checking for hardware virtualization    : PASS
# QEMU: Checking if device /dev/kvm exists      : PASS
# QEMU: Checking if device /dev/kvm is accessible: PASS

標準インストール手順

# 1. 最新安定版のバージョンを取得
export RELEASE=$(curl https://storage.googleapis.com/kubevirt-prow/release/kubevirt/kubevirt/stable.txt)
echo "Installing KubeVirt ${RELEASE}"

# 2. KubeVirt Operatorをデプロイ
kubectl apply -f \
  https://github.com/kubevirt/kubevirt/releases/download/${RELEASE}/kubevirt-operator.yaml

# 3. KubeVirt Custom Resourceを作成
kubectl apply -f \
  https://github.com/kubevirt/kubevirt/releases/download/${RELEASE}/kubevirt-cr.yaml

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

# 5. コンポーネントの確認
kubectl get pods -n kubevirt

ソフトウェアエミュレーション(開発環境向け)

ハードウェア仮想化が利用できない環境(ネストされた仮想化非対応など)では、ソフトウェアエミュレーションを有効化できる:

apiVersion: kubevirt.io/v1
kind: KubeVirt
metadata:
  name: kubevirt
  namespace: kubevirt
spec:
  configuration:
    developerConfiguration:
      useEmulation: true

警告: ソフトウェアエミュレーションは開発・テスト目的のみに使用すること。本番環境ではパフォーマンスが大幅に低下する。

OKD(OpenShift)へのデプロイ

# 特権の付与
oc adm policy add-scc-to-user privileged \
  -n kubevirt \
  -z kubevirt-operator

# Operator と CR のデプロイ(標準手順と同じ)
kubectl apply -f ${RELEASE_URL}/kubevirt-operator.yaml
kubectl apply -f ${RELEASE_URL}/kubevirt-cr.yaml

OKDのWebコンソールは、KubeVirtデプロイ後に仮想化拡張機能を自動検出して有効化する。

k3OS向け設定

# k3OS ノード設定にカーネルモジュールを追加
k3os:
  modules:
  - kvm
  - vhost_net

コンポーネントの配置制御

インフラストラクチャコンポーネントとワークロードの配置を分離する:

# インフラコンポーネントをコントロールプレーンノードに制限
kubectl patch -n kubevirt kubevirt kubevirt --type merge \
  --patch '{
    "spec": {
      "infra": {
        "nodePlacement": {
          "nodeSelector": {
            "node-role.kubernetes.io/control-plane": ""
          }
        }
      },
      "workloads": {
        "nodePlacement": {
          "nodeSelector": {
            "node-role.kubernetes.io/worker": ""
          },
          "tolerations": [
            {
              "key": "dedicated",
              "operator": "Equal",
              "value": "virtualization",
              "effect": "NoSchedule"
            }
          ]
        }
      }
    }
  }'

virtctl CLI のインストール

# 最新の virtctl をダウンロード
export RELEASE=$(curl https://storage.googleapis.com/kubevirt-prow/release/kubevirt/kubevirt/stable.txt)

# Linux
wget https://github.com/kubevirt/kubevirt/releases/download/${RELEASE}/virtctl-${RELEASE}-linux-amd64
chmod +x virtctl-${RELEASE}-linux-amd64
sudo mv virtctl-${RELEASE}-linux-amd64 /usr/local/bin/virtctl

# macOS
wget https://github.com/kubevirt/kubevirt/releases/download/${RELEASE}/virtctl-${RELEASE}-darwin-amd64
chmod +x virtctl-${RELEASE}-darwin-amd64
sudo mv virtctl-${RELEASE}-darwin-amd64 /usr/local/bin/virtctl

# 確認
virtctl version

仮想マシンの作成と管理

virtctl を使用した VM 作成

virtctl create vm コマンドは、VirtualMachineマニフェストを生成するための最も簡単な方法である。

# 基本的なVM作成
virtctl create vm --name my-vm | kubectl create -f -

# インスタンスタイプとプリファレンスを指定
virtctl create vm --name my-vm \
  --instancetype my-instancetype \
  --preference my-preference

# ボリュームとクラウドイニットを含む完全なVM
virtctl create vm --name fedora-vm \
  --instancetype=u1.small \
  --preference=fedora \
  --volume-containerdisk=src:quay.io/containerdisks/fedora:latest \
  --volume-import=type:blank,size:1Gi \
  --cloud-init-user-data "$(base64 -w 0 cloud-init.yaml)"

ボリュームの設定

ボリュームは以下の固定ブート順序でアタッチされる:

  1. Containerdisks
  2. 直接参照の PVC
  3. DataSources
  4. クローンされた PVC
  5. ブランクボリューム
  6. インポートされたボリューム
# DataSource からのVM作成(インスタンスタイプ推論付き)
virtctl create vm --name my-vm \
  --volume-import=type:ds,src:my-ds \
  --infer-instancetype \
  --infer-preference

# 複数ボリュームのセットアップ
virtctl create vm --name multi-disk-vm \
  --instancetype=u1.small \
  --preference=fedora \
  --volume-containerdisk=src:quay.io/containerdisks/fedora \
  --volume-import=type:blank,size:1Gi

SSH アクセスの設定

# SSH公開鍵のSecret作成
kubectl create secret generic my-ssh-keys \
  --from-file=key1=$HOME/.ssh/id_ed25519.pub

# SSHアクセス付きのVM作成
virtctl create vm --name ssh-vm \
  --user myuser \
  --access-cred=src:my-ssh-keys | kubectl create -f -

# VMへのSSH接続
virtctl ssh myuser@ssh-vm

VM のライフサイクル管理

# VM の起動
virtctl start my-vm

# VM の停止
virtctl stop my-vm

# VM の再起動
virtctl restart my-vm

# VM の一時停止
virtctl pause vmi my-vm

# VM の一時停止解除
virtctl unpause vmi my-vm

# VM の削除
kubectl delete vm my-vm

コンソールアクセス

# シリアルコンソール
virtctl console my-vm

# VNC接続
virtctl vnc my-vm

# VNC プロキシ(ブラウザアクセス用)
virtctl vnc --proxy-only --port=5900 my-vm

RunStrategy(実行戦略)

VMの spec.runStrategy で、VMIのライフサイクル動作を細かく制御できる:

戦略説明
AlwaysVMIを常に実行。停止されても自動再作成
Manual手動でのstart/stop/restartのみ
HaltedVMIは作成されない
RerunOnFailure障害時のみ自動再起動
Once一度だけ起動し、停止後は再作成しない
apiVersion: kubevirt.io/v1
kind: VirtualMachine
metadata:
  name: always-running-vm
spec:
  runStrategy: Always
  template:
    spec:
      domain:
        resources:
          requests:
            memory: 1Gi
        devices:
          disks:
          - name: rootdisk
            disk:
              bus: virtio
      volumes:
      - name: rootdisk
        containerDisk:
          image: quay.io/containerdisks/fedora:latest

Cloud-Init による初期設定

# NoCloud方式のCloud-Init設定例
volumes:
- name: cloudinitdisk
  cloudInitNoCloud:
    userData: |
      #cloud-config
      hostname: webserver-01
      fqdn: webserver-01.example.com
      
      # ユーザー設定
      users:
      - name: admin
        sudo: ALL=(ALL) NOPASSWD:ALL
        groups: wheel
        ssh_authorized_keys:
        - ssh-rsa AAAA...
      
      # パッケージインストール
      packages:
      - nginx
      - htop
      - curl
      
      # サービス起動
      runcmd:
      - systemctl enable nginx
      - systemctl start nginx
      - echo "Hello from KubeVirt!" > /var/www/html/index.html
      
      # ネットワーク設定
      write_files:
      - path: /etc/sysctl.d/99-custom.conf
        content: |
          net.ipv4.ip_forward = 1
    
    networkData: |
      network:
        version: 2
        ethernets:
          eth0:
            dhcp4: true

ストレージ管理

ストレージアーキテクチャの概要

KubeVirtのストレージは、3つの相互関連するコンポーネントで構成される:

  • ボリューム(Volumes): クラスター上の永続的なストレージ
  • ディスク(Disks): VM内で表示されるデバイス仕様
  • ファイルシステム(Filesystems): virtiofsベースの共有

各ディスクは名前によってボリュームを参照する必要がある。

ディスクタイプ

1. Disk(標準ディスク)

spec:
  domain:
    devices:
      disks:
      - name: rootdisk
        disk:
          bus: virtio     # virtio, sata, scsi から選択
        # cache: none     # none (デフォルト), writeback, writethrough

2. LUN(SCSI LUN デバイス)

spec:
  domain:
    devices:
      disks:
      - name: scsi-disk
        lun:
          bus: scsi
          reservation: true  # SCSI永続予約の有効化

3. CDROM

spec:
  domain:
    devices:
      disks:
      - name: iso-disk
        cdrom:
          bus: sata
          readonly: true   # デフォルトは読み取り専用

4. Filesystem(virtiofs)

spec:
  domain:
    devices:
      filesystems:
      - name: shared-data
        virtiofs: {}
  volumes:
  - name: shared-data
    persistentVolumeClaim:
      claimName: shared-pvc

ボリュームソースタイプ

PersistentVolumeClaim

volumes:
- name: my-pvc-volume
  persistentVolumeClaim:
    claimName: my-existing-pvc
    # hotpluggable: true  # ホットプラグ対応

DataVolume(CDI連携)

# VMテンプレート内でDataVolumeを自動作成
dataVolumeTemplates:
- metadata:
    name: my-vm-rootdisk
  spec:
    storage:
      accessModes:
      - ReadWriteOnce
      resources:
        requests:
          storage: 20Gi
      storageClassName: fast-ssd
    source:
      http:
        url: https://cloud-images.ubuntu.com/jammy/current/jammy-server-cloudimg-amd64.img

ContainerDisk

volumes:
- name: containerdisk
  containerDisk:
    image: quay.io/containerdisks/fedora:latest
    imagePullPolicy: IfNotPresent
    # imagePullSecret: my-registry-secret

ContainerDiskの特徴: コンテナレジストリからディスクイメージを直接利用でき、ネットワークストレージが不要。ただし、エフェメラルであり、データは永続化されない。

EmptyDisk

volumes:
- name: temp-data
  emptyDisk:
    capacity: 5Gi   # スパースqcow2が作成される

CloudInit

volumes:
- name: cloudinitdisk
  cloudInitNoCloud:
    userData: |
      #cloud-config
      hostname: my-vm

ConfigMap / Secret

volumes:
- name: config-volume
  configMap:
    name: my-config
    # optional: true
- name: secret-volume
  secret:
    secretName: my-secret

IOThreads によるパフォーマンス最適化

spec:
  domain:
    ioThreadsPolicy: auto  # shared, auto, supplementalPool
    devices:
      disks:
      - name: high-perf-disk
        disk:
          bus: virtio
        dedicatedIOThread: true  # 専用IOスレッドを割り当て
        io: native              # native I/O の使用

IOThreadsポリシー:

ポリシー説明
shared全ディスクで1つのIOスレッドを共有
autovCPU数×2 のスレッドプールをラウンドロビン割り当て
supplementalPoolユーザー指定数のスレッドプール(CPUピニング対応)

Block Multi-Queue

spec:
  domain:
    devices:
      blockMultiQueue: true  # vCPU数に応じたI/Oキュー作成
      disks:
      - name: rootdisk
        disk:
          bus: virtio
    resources:
      requests:
        cpu: "4"   # 明示的なCPUリクエストが必要

ディスク共有

spec:
  domain:
    devices:
      disks:
      - name: shared-disk
        disk:
          bus: virtio
        shareable: true  # 複数VMでの共有を許可

注意: 共有ディスクを使用する場合、アプリケーションレベルでの同期メカニズム、またはクラスターファイルシステム(GFS2など)が必要。


ネットワーク構成

ネットワークアーキテクチャ

KubeVirtのネットワーキングは、Kubernetesのネットワークモデルを活用しつつ、仮想マシン固有の要件に対応する。

ネットワークタイプ

Pod Network(デフォルト)

KubernetesのPodネットワークを使用する標準的な構成。クラスターのCNIソリューションによって構成されるデフォルトのPodインターフェース(通常は eth0)を利用する。

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

Multus Networks(セカンダリネットワーク)

Multus CNIプラグインを使用してVMを追加のネットワークに接続する。

# 1. NetworkAttachmentDefinition の作成(管理者が実施)
apiVersion: k8s.cni.cncf.io/v1
kind: NetworkAttachmentDefinition
metadata:
  name: my-vlan-network
  namespace: default
spec:
  config: |
    {
      "cniVersion": "0.3.1",
      "type": "bridge",
      "bridge": "br-vlan100",
      "vlan": 100,
      "ipam": {
        "type": "host-local",
        "subnet": "10.10.100.0/24",
        "rangeStart": "10.10.100.10",
        "rangeEnd": "10.10.100.200"
      }
    }

---
# 2. VMからの参照
apiVersion: kubevirt.io/v1
kind: VirtualMachine
metadata:
  name: multi-net-vm
spec:
  running: true
  template:
    spec:
      networks:
      - name: default
        pod: {}
      - name: vlan-net
        multus:
          networkName: my-vlan-network
      domain:
        devices:
          interfaces:
          - name: default
            masquerade: {}
          - name: vlan-net
            bridge: {}

インターフェースバインディング方式

Masquerade(推奨)

nftablesルールを使用してNATによるトラフィック変換を行う。最もポータブルな方式。

interfaces:
- name: default
  masquerade: {}
  ports:
  - name: http
    port: 80
    protocol: TCP
  - name: ssh
    port: 22
    protocol: TCP

Masqueradeの特徴:

  • イグレスとイングレスの両方でNAT変換
  • IPv4、デュアルスタックIPv6/IPv4、IPv6シングルスタックをサポート
  • ライブマイグレーションと互換性あり
  • Serviceの公開が容易
# VM向けServiceの定義
apiVersion: v1
kind: Service
metadata:
  name: my-vm-service
spec:
  selector:
    kubevirt.io/vm: my-vm
  ports:
  - name: http
    port: 80
    targetPort: 80
  - name: ssh
    port: 22
    targetPort: 22
  type: ClusterIP

Bridge

interfaces:
- name: secondary
  bridge: {}

注意: ブリッジバインディングはPodネットワークでの使用時、ライブマイグレーションと互換性がない。

SR-IOV(高パフォーマンス)

interfaces:
- name: sriov-net
  sriov: {}

SR-IOVはVFIO(Virtual Function I/O)ユーザースペースインターフェースを使用して、仮想マシンにSR-IOV Virtual Functionを直接パススルーする。

前提条件:

  • SR-IOV Network Operator のデプロイ
  • SR-IOV Device Plugin の設定
  • 対応するNICハードウェア

Passt Binding(ベータ)

interfaces:
- name: default
  passt: {}

Passtの特徴:

  • ユーザースペースネットワーキング
  • CAP_NET_RAWCAP_NET_ADMIN が不要
  • ネイティブIPv6サポート
  • サービスメッシュ統合対応
  • PasstBinding Feature Gate の有効化が必要

MAC Spoof Check

# NetworkAttachmentDefinition でMAC偽装防止を設定
spec:
  config: |
    {
      "cniVersion": "0.3.1",
      "type": "bridge",
      "bridge": "br-test",
      "macspoofchk": true
    }

ライブマイグレーション

概要

ライブマイグレーションは、実行中のVMIを別のコンピュートノードに移動する機能であり、VMのダウンタイムなしでノードメンテナンスやリソース最適化を実現する。

前提条件と制約

要件詳細
PVCアクセスモードReadWriteMany(RWX)が必要
ネットワークBridgeバインディング(Podネットワーク)は非対応
ポート49152, 49153 がvirt-launcher Podで利用可能であること
ネットワーク名ソースとターゲットPodのプライマリインターフェース名が同一であること

マイグレーションの実行

# virtctl によるマイグレーション
virtctl migrate my-vmi

# YAML によるマイグレーション
cat <<EOF | kubectl apply -f -
apiVersion: kubevirt.io/v1
kind: VirtualMachineInstanceMigration
metadata:
  name: my-migration
spec:
  vmiName: my-vmi
EOF

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

マイグレーション戦略

Pre-copy(デフォルト)

最も安全な方式。ゲストがソースノードで実行されている間に、メモリをターゲットノードにコピーする。

ソースノード: [VM実行] → メモリコピー → [切替] → 完了
ターゲットノード:         ← メモリ受信 → [VM実行]

Post-copy

ゲストを即座にターゲットノードで実行し、残りのメモリをオンデマンドで転送する。高速だが、障害時のリスクが高い。

ソースノード: [VM実行] → [切替] → メモリ送信(オンデマンド)
ターゲットノード:       → [VM実行] ← メモリ受信

Auto-converge

ダーティレートが高い場合に、ゲストCPUを段階的にスロットリングしてPre-copyの収束を支援する。

クラスター全体の設定

apiVersion: kubevirt.io/v1
kind: KubeVirt
metadata:
  name: kubevirt
  namespace: kubevirt
spec:
  configuration:
    migrations:
      parallelMigrationsPerCluster: 5        # クラスター全体の並列マイグレーション数
      parallelOutboundMigrationsPerNode: 2   # ノードあたりの送信マイグレーション数
      bandwidthPerMigration: 64Mi            # マイグレーションあたりの帯域幅
      completionTimeoutPerGiB: 150           # GiBあたりの完了タイムアウト(秒)
      progressTimeout: 150                    # 進行停滞のタイムアウト(秒)
      allowAutoConverge: false               # Auto-convergeの有効化
      allowPostCopy: false                   # Post-copyの有効化
      disableTLS: false                      # TLS暗号化の無効化
      unsafeMigrationOverride: false         # 安全制約のオーバーライド

専用マイグレーションネットワーク

マイグレーショントラフィック用の専用ネットワークを構成できる:

# 1. NetworkAttachmentDefinition の作成
apiVersion: k8s.cni.cncf.io/v1
kind: NetworkAttachmentDefinition
metadata:
  name: migration-network
  namespace: kubevirt
spec:
  config: |
    {
      "cniVersion": "0.3.1",
      "type": "bridge",
      "bridge": "br-migration",
      "ipam": {
        "type": "whereabouts",
        "range": "192.168.200.0/24"
      }
    }

---
# 2. KubeVirt CR で設定
apiVersion: kubevirt.io/v1
kind: KubeVirt
metadata:
  name: kubevirt
  namespace: kubevirt
spec:
  configuration:
    migrations:
      network: migration-network

マイグレーションのキャンセル

# virtctl によるキャンセル
virtctl migrate-cancel my-vmi

# YAML オブジェクトの削除
kubectl delete vmim my-migration

マイグレーション状態の監視

# VMI のマイグレーション状態を確認
kubectl get vmi my-vmi -o jsonpath='{.status.migrationState}'

# マイグレーション条件の確認
kubectl get vmi my-vmi -o jsonpath='{.status.conditions[?(@.type=="LiveMigratable")]}'

Feature Gates と高度な設定

Feature Gates の管理

KubeVirtは、成熟度が不十分な機能を保護するためにFeature Gatesメカニズムを使用する。

Feature Gatesの有効化

apiVersion: kubevirt.io/v1
kind: KubeVirt
metadata:
  name: kubevirt
  namespace: kubevirt
spec:
  configuration:
    developerConfiguration:
      featureGates:
      - LiveMigration
      - HotplugVolumes
      - GPU
      - HostDevices
      - Snapshot
      - VMExport
      - HotplugNICs
      - PasstBinding
      - EnableVirtioFsStorageVolumes

Feature Gatesの無効化(v1.8以降)

spec:
  configuration:
    developerConfiguration:
      disabledFeatureGates:
      - SomeDefaultEnabledFeature

注意: 同一のFeature Gateを featureGatesdisabledFeatureGates の両方に設定することはできない。バリデーションエラーが発生する。

主要なFeature Gates一覧

Feature Gate説明デフォルト
LiveMigrationライブマイグレーション有効
HotplugVolumesボリュームのホットプラグ-
HotplugNICsNICのホットプラグ-
GPUGPUパススルー-
HostDevicesホストデバイスパススルー-
SnapshotVMスナップショット-
VMExportVMエクスポート-
PasstBindingPasstネットワーキング-
EnableVirtioFsStorageVolumesvirtiofs共有-

CPU・メモリの高度な設定

専用CPU(CPU Pinning)

spec:
  domain:
    cpu:
      cores: 4
      sockets: 1
      threads: 1
      dedicatedCpuPlacement: true   # CPU ピニングの有効化
      isolateEmulatorThread: true   # エミュレータスレッドの分離
    resources:
      requests:
        memory: 4Gi
      limits:
        memory: 4Gi

NUMA トポロジー

spec:
  domain:
    cpu:
      cores: 8
      numa:
        guestMappingPassthrough: {}  # ホストのNUMAトポロジーをゲストに反映
    memory:
      hugepages:
        pageSize: 1Gi               # HugePagesの使用

CPU・メモリのホットプラグ

# CPU ホットプラグ対応のVM定義
spec:
  domain:
    cpu:
      cores: 2
      maxSockets: 8    # ホットプラグ可能な最大ソケット数
    memory:
      guest: 2Gi
      maxGuest: 8Gi    # ホットプラグ可能な最大メモリ
# CPU のホットプラグ
kubectl patch vm my-vm --type merge \
  --patch '{"spec":{"template":{"spec":{"domain":{"cpu":{"sockets":4}}}}}}'

# メモリのホットプラグ
kubectl patch vm my-vm --type merge \
  --patch '{"spec":{"template":{"spec":{"domain":{"memory":{"guest":"4Gi"}}}}}}'

CDI(Containerized Data Importer)

概要

CDI は、PersistentVolumeClaim(PVC)をKubeVirt VMのディスクとして使用可能にするためのコンポーネントである。DataVolumeを通じてストレージ管理を自動化する。

主要機能

  1. ディスクイメージのインポート: WebサーバーやコンテナレジストリからDataVolumeへ
  2. 既存PVCのクローン: PVCからDataVolumeへのデータ複製
  3. ローカルイメージのアップロード: ローカルディスクイメージからDataVolumeへ

CDIのインストール

# CDI Operatorのデプロイ
export CDI_TAG=$(curl -s -w %{redirect_url} \
  https://github.com/kubevirt/containerized-data-importer/releases/latest)
CDI_VERSION=$(echo ${CDI_TAG} | grep -oP 'v\d+\.\d+\.\d+')

kubectl create -f \
  https://github.com/kubevirt/containerized-data-importer/releases/download/${CDI_VERSION}/cdi-operator.yaml
kubectl create -f \
  https://github.com/kubevirt/containerized-data-importer/releases/download/${CDI_VERSION}/cdi-cr.yaml

# 確認
kubectl get pods -n cdi

対応イメージフォーマット

フォーマット圧縮
rawgz, xz
qcow2gz, xz
ISO(ブータブル)-

HTTPからのディスクインポート

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: standard

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

apiVersion: cdi.kubevirt.io/v1beta1
kind: DataVolume
metadata:
  name: fedora-dv
spec:
  source:
    registry:
      url: docker://quay.io/containerdisks/fedora:latest
  storage:
    accessModes:
    - ReadWriteOnce
    resources:
      requests:
        storage: 10Gi

ローカルイメージのアップロード

# virtctl を使用したアップロード
virtctl image-upload dv my-disk \
  --size=10Gi \
  --image-path=/path/to/disk.qcow2 \
  --uploadproxy-url=https://cdi-uploadproxy.cdi.svc \
  --insecure

# 既存のPVCへのアップロード
virtctl image-upload pvc my-existing-pvc \
  --image-path=/path/to/disk.img \
  --no-create

PVCのクローン

apiVersion: cdi.kubevirt.io/v1beta1
kind: DataVolume
metadata:
  name: cloned-dv
spec:
  source:
    pvc:
      namespace: source-namespace
      name: source-pvc
  storage:
    accessModes:
    - ReadWriteOnce
    resources:
      requests:
        storage: 10Gi

運用とベストプラクティス

監視とオブザーバビリティ

Prometheus メトリクス

KubeVirtは標準的なPrometheusメトリクスを公開する:

# ServiceMonitor の設定例
apiVersion: monitoring.coreos.com/v1
kind: ServiceMonitor
metadata:
  name: kubevirt-monitor
  namespace: kubevirt
spec:
  selector:
    matchLabels:
      prometheus.kubevirt.io: "true"
  endpoints:
  - port: metrics
    interval: 30s

主要メトリクス:

メトリクス説明
kubevirt_vmi_phase_countVMIのフェーズ別カウント
kubevirt_vmi_memory_available_bytes利用可能メモリ
kubevirt_vmi_vcpu_secondsvCPU使用時間
kubevirt_vmi_network_receive_bytes_totalネットワーク受信バイト数
kubevirt_vmi_storage_read_traffic_bytes_totalストレージ読み取りバイト数
kubevirt_vmi_migration_data_processed_bytesマイグレーション処理データ量

バックアップとリストア

VMスナップショット

# スナップショットの作成
apiVersion: snapshot.kubevirt.io/v1beta1
kind: VirtualMachineSnapshot
metadata:
  name: my-vm-snapshot
spec:
  source:
    apiGroup: kubevirt.io
    kind: VirtualMachine
    name: my-vm

---
# スナップショットからの復元
apiVersion: snapshot.kubevirt.io/v1beta1
kind: VirtualMachineRestore
metadata:
  name: my-vm-restore
spec:
  target:
    apiGroup: kubevirt.io
    kind: VirtualMachine
    name: my-vm
  virtualMachineSnapshotName: my-vm-snapshot

セキュリティ設定

RBAC設定例

# VM管理者ロール
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
  name: kubevirt-vm-admin
rules:
- apiGroups: ["kubevirt.io"]
  resources: ["virtualmachines", "virtualmachineinstances"]
  verbs: ["get", "list", "watch", "create", "update", "delete"]
- apiGroups: ["kubevirt.io"]
  resources: ["virtualmachineinstances/console", "virtualmachineinstances/vnc"]
  verbs: ["get"]
- apiGroups: ["subresources.kubevirt.io"]
  resources: ["virtualmachines/start", "virtualmachines/stop", "virtualmachines/restart"]
  verbs: ["update"]

---
# VM閲覧者ロール
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
  name: kubevirt-vm-viewer
rules:
- apiGroups: ["kubevirt.io"]
  resources: ["virtualmachines", "virtualmachineinstances"]
  verbs: ["get", "list", "watch"]

アップグレード手順

# 1. 新しいバージョンの確認
export NEW_RELEASE=$(curl https://storage.googleapis.com/kubevirt-prow/release/kubevirt/kubevirt/stable.txt)

# 2. Operator の更新
kubectl apply -f \
  https://github.com/kubevirt/kubevirt/releases/download/${NEW_RELEASE}/kubevirt-operator.yaml

# 3. 更新の完了を確認
kubectl -n kubevirt wait kv kubevirt \
  --for condition=Available \
  --timeout=600s

# 4. バージョン確認
kubectl get kubevirt -n kubevirt -o jsonpath='{.items[0].status.observedKubeVirtVersion}'

ユースケースと適用シナリオ

1. レガシーアプリケーションのモダナイゼーション

コンテナ化が困難なレガシーアプリケーション(Windows Server、特定のLinuxディストリビューション依存のアプリケーション等)を、Kubernetesインフラ上でそのまま実行する。

# Windows Server VM の例
apiVersion: kubevirt.io/v1
kind: VirtualMachine
metadata:
  name: windows-server
spec:
  running: true
  template:
    spec:
      domain:
        clock:
          utc: {}
          timer:
            hpet:
              present: false
            pit:
              tickPolicy: delay
            rtc:
              tickPolicy: catchup
            hyperv: {}
        features:
          acpi: {}
          apic: {}
          hyperv:
            relaxed: {}
            vapic: {}
            spinlocks:
              spinlocks: 8191
        devices:
          disks:
          - name: rootdisk
            disk:
              bus: sata
          - name: virtio-drivers
            cdrom:
              bus: sata
          interfaces:
          - name: default
            masquerade: {}
          tpm: {}
        resources:
          requests:
            memory: 4Gi
            cpu: "2"
      networks:
      - name: default
        pod: {}
      volumes:
      - name: rootdisk
        dataVolume:
          name: windows-dv
      - name: virtio-drivers
        containerDisk:
          image: quay.io/kubevirt/virtio-container-disk:latest

2. 開発・テスト環境

異なるOS環境のテストや、ネットワーク構成のシミュレーションに活用する。

3. NFV(Network Function Virtualization)

SR-IOVやDPDKを活用したネットワーク機能の仮想化に使用する。

4. ハイブリッドワークロード

同一クラスター上でコンテナとVMを混在させ、統一的なオーケストレーションを実現する。


まとめ

KubeVirtは、Kubernetesエコシステムの中で仮想マシンワークロードを管理するための成熟したプラットフォームである。その主要な特徴を以下にまとめる:

側面特徴
アーキテクチャSOA + コレオグラフィパターン。Kubernetesネイティブな拡張
CRDVM, VMI, VMIRS による柔軟なワークロード管理
ストレージCDI連携、DataVolume、多様なボリュームソース対応
ネットワークMasquerade、Bridge、SR-IOV、Passt バインディング
マイグレーションPre-copy、Post-copy、Auto-converge 戦略
運用Prometheus監視、スナップショット、RBAC
拡張性Feature Gates、インスタンスタイプ、プリファレンス

KubeVirtの採用により、組織はレガシーなVMワークロードとクラウドネイティブなコンテナワークロードを統一的に管理し、インフラストラクチャの複雑性を大幅に低減できる。Kubernetes の既存のエコシステム(CI/CD、監視、セキュリティ)をそのまま活用できる点も大きな利点である。