自宅サーバーでKubeVirtに入門

Table of Contents

1. はじめに

私は普段、業務や趣味の自宅サーバーでIaaS基盤の開発・運用をしており、OpenStackKubernetesを日常的に触っています。 そのため、「Kubernetes上で仮想化基盤を構築する」というコンセプトのKubeVirtには以前から興味を持っていました。

そして先日たまたまこちらのOracle JapanのTakuya Niitaさんが公開しているスライド資料を見かけて、なんだか思ったより簡単に動かせそう?と思ったので、自宅サーバーで試してみることにしました。

というわけで今回は、自宅のKubernetesクラスタにKubeVirtをインストールして実際にVMを動かしてみた際の、手順やハマりポイントについて紹介しようと思います。

2. KubeVirtとは

KubeVirtは、Kubernetes上で仮想マシン(VM)を動かすためのプラットフォームとなるOSSです。

コンテナとVMを同じKubernetesクラスタ上で統一的に管理できるのが特徴で、既存のVM資産をKubernetesに移行したい場合や、コンテナ化が難しいワークロードを扱いたい場合に便利なもののようです。

KubernetesのリソースとしてVMを定義し、Podと同じようにKubernetesのエコシステムを使って管理できるのが面白いところです。

3. 環境構築

それでは早速KubeVirtをインストールしていきます。

3.1 Kubernetesクラスタの準備

まず、KubeVirtを動かすためのKubernetesクラスタが必要です。私の場合は、自宅サーバー上にkubeadmで構築したクラスタを使用しました。ネットワークプラグインにはOVN-Kubernetesを採用しています。

クラスタの詳細な構築手順については、「kubeadmとOVN-Kubernetesで自宅Kubernetesクラスタを構築する」という記事で紹介していますので、興味がある方はそちらもご覧ください。

3.2 KubeVirtのインストール

KubeVirtのインストールは、公式のクイックスタートガイドに従って実施しました。

まず、最新の安定版バージョンを取得します:

export VERSION=$(curl -s https://storage.googleapis.com/kubevirt-prow/release/kubevirt/kubevirt/stable.txt)
echo $VERSION

次に、KubeVirt Operatorをデプロイします:

kubectl create -f "https://github.com/kubevirt/kubevirt/releases/download/${VERSION}/kubevirt-operator.yaml"

最後に、KubeVirtのCRをデプロイして実際のコンポーネントを起動します:

kubectl create -f "https://github.com/kubevirt/kubevirt/releases/download/${VERSION}/kubevirt-cr.yaml"

順調にいけばこれで完了…のはずだったのですが、実際にはいくつか問題が発生しました。

4. 遭遇した問題と解決

4.1 CPU命令セットの問題

最初に遭遇したのは、各Worker Node上のVMを管理するコンポーネントである virt-handler Podが起動しないという問題です。

virt-handler Podのログを確認すると、以下のエラーが出ていました:

virt-handler-hxdfn virt-launcher 2025-08-30T22:58:59.360762864+09:00 Fatal glibc error: CPU does not support x86-64-v2

これは、Worker Nodeとして使っているProxmox VMのCPU typeをデフォルトの “kvm64” で動かしており、x86-64-v2命令セットをサポートしていなかったことが原因でした。

解決方法:Proxmox VMのCPU typeを “x86-64-v2-AES” に変更することで解決しました。

4.2 Control Planeノード数の問題

次に遭遇したのは、virt-apivirt-controller といったKubeVirtのコントロールプレーンコンポーネントのPodが起動しない問題でした。

virt-operatorがデフォルトで replicas=2 でこれらのコンポーネントを起動しようとするのですが、私の環境はControl Planeノードが1台しかなかったため、2つ目のPodがSchedulingできない状態になっていました。

解決方法:素直にControl Planeノードを増やしました。本番環境ではHA(High Availability)の観点からも複数ノードが推奨されるためそのうち増やそうと思っていたので、ちょうどいい機会でした。

4.3 Nested Virtualizationの設定

さらに、Proxmoxで “x86-64-v2-AES” のCPU typeを使用していると、VM側にハードウェア仮想化支援機構のフラグ(VMXやSVM)が渡されないという問題がありました。KubeVirtはVM内でさらにQEMU/KVMを動かすため、これらのフラグが必要です。

解決方法:ProxmoxのCPU typeを “host” に変更し、Nested Virtualizationを有効にしました。

ただし、この設定には注意点があります。CPU typeを “host” にすると、CPU命令セットの互換性担保が難しくなり、将来Proxmoxホストを追加した際にライブマイグレーションができなくなる、といった問題が生じる可能性があります。

今回は、まあ自宅サーバーだし別にいっかという判断で進めました。

4.4 OVN-Kubernetesのサブネット問題

KubeVirtのインストール時に、OVN-Kubernetesのサブネット設定に関する問題も発生しました。この問題の詳細と解決方法については、kubeadm × ovn-kubernetesのクラスタでService CIDR問題にハマったという別記事で詳しく紹介していますので、興味がある方はそちらもご覧ください。

5. VMの起動

トラブルを解決した後、公式ドキュメントに従って、テスト用のVMを起動してみました。

以下がVirtualMachineのマニフェストです:

apiVersion: kubevirt.io/v1
kind: VirtualMachine
metadata:
  name: testvm
spec:
  runStrategy: Halted
  template:
    metadata:
      labels:
        kubevirt.io/size: small
        kubevirt.io/domain: testvm
    spec:
      domain:
        devices:
          disks:
            - name: containerdisk
              disk:
                bus: virtio
            - name: cloudinitdisk
              disk:
                bus: virtio
          interfaces:
            - name: default
              masquerade: {}
        resources:
          requests:
            memory: 64M
      networks:
        - name: default
          pod: {}
      volumes:
        - name: containerdisk
          containerDisk:
            image: quay.io/kubevirt/cirros-container-disk-demo
        - name: cloudinitdisk
          cloudInitNoCloud:
            userDataBase64: SGkuXG4=

このマニフェストをapplyしてVMを作成し、virtctlコマンドで起動します:

kubectl apply -f testvm.yaml
virtctl start testvm

VMが起動したら、コンソールに接続することもできます:

$ virtctl console testvm
Successfully connected to testvm console. Press Ctrl+] or Ctrl+5 to exit console.

Password:
Login incorrect
testvm login: cirros
Password:
$ hostname
testvm
$ cat /etc/os-release
NAME=Buildroot
VERSION=2015.05-g31af4e3-dirty
ID=buildroot
VERSION_ID=2015.05
PRETTY_NAME="Buildroot 2015.05"

Worker Node上でも確認してみると、ちゃんとqemuプロセスが動いているのが分かります:

ubuntu@home-k8s-worker03:~$ ps -ef | grep [q]emu-kvm
tcpdump   660197  660046  0 Sep04 ?        00:02:58 /usr/libexec/qemu-kvm -name guest=default_testvm,debug-threads=on ...

6. まとめ

今回は自宅サーバー環境でKubeVirtを実際に触ってみました。

Kubernetes上でVMを動かすという体験はとても面白く、特にVMをPodのように扱えるところが新鮮で、コンテナとVMを統一的に管理できる可能性を感じました。

今後は、KubeVirtの様々な機能も試してみながら、OpenStackのコンポーネントなどの実際のワークロードをKubeVirt上で動かすことに挑戦しようと思います。

最後まで読んでいただき、ありがとうございました。

7. 参考資料