KubeVirt: Kubernetes上で仮想マシンを実行する、DevOpsエンジニアのための究極のテクニック

Virtualization tutorial - IT technology blog
Virtualization tutorial - IT technology blog

すべてを一つに:VMとコンテナが「同じ屋根の下」に住むとき

DevOpsエンジニアなら、片手で kubectl を操りコンテナを制御し、もう片方の手でProxmoxやVMwareを操作してレガシーなデータベースを動かす仮想マシン(VM)を管理する、という光景に慣れっこでしょう。このように2つの異なるインフラを維持することは、リソースと人件費を大幅に消費します。私のホームラボでも、コンテナ化できないレガシーアプリのために12台のVMを維持していましたが、ダッシュボードを行ったり来たりするのは本当に苦痛でした。

そこで救世主として登場するのが KubeVirt です。これにより、KubernetesのPod内でKVM仮想マシンを直接実行できるようになります。今や、シンプルなNginxコンテナを定義するのと同じように、YAMLファイルを使ってWindows Serverを定義できるのです。

実例比較:従来の仮想化 vs クラウドネイティブ仮想化

コマンドを打ち始める前に、自分たちがどこに立っているのかを知るために、核心的な違いを振り返ってみましょう。

  • 従来の仮想化(Proxmox, ESXi): 仮想マシンは「第一級市民」です。ネットワークとストレージはVM専用に設計されています。K8sを実行したい場合は、これらのVMの上にインストールする必要があります。
  • クラウドネイティブ仮想化(KubeVirt): Kubernetesが下地(Underlay)の役割を果たします。VMはK8s内の一つのリソース(CRD)となります。SchedulerからRBAC、Monitoring(Prometheus)、Logging(Loki)まで、エコシステム全体を継承します。

個別のVLAN設定に頭を悩ませる代わりに、VMはCalicoやCiliumを介してクラスターのネットワーク帯域を共有します。これがネットワーク構成を大幅にシンプルにする鍵となります。

KubeVirtは本当に万能か? メリットとデメリットを整理

KubeVirtのメリット

最大の利点は一貫性です。PodとVMの両方に対して、全く同じCI/CDパイプパイプラインとアラートシステムを使用できます。次に、リソースの有効活用です。K8sはRAM/CPUに余裕があるノードに自動的にVMを配置するため、手動で細かく計算する必要がありません。

注意すべきデメリット

最大の問題はパフォーマンスです。VMがPodの中でネストして実行されるため、抽象化レイヤーが一つ増えます。KVMのサポートがあっても、CPUのオーバーヘッドはベアメタル実行に比べて通常5〜10%程度発生します。また、K8s上でのVM用ストレージ管理(PVCからのディスクイメージ作成など)は、Proxmoxで数回クリックするのに比べれば、まだ少し手間がかかります。

いつKubeVirtを「導入」すべきか?

既存のVMwareシステムをすぐに捨てる必要はありません。私の経験上、以下の3つのケースでKubeVirtを検討してみてください。

  1. インフラを近代化したいが、Windows Serverや特定のカーネルでしか動作しない古いモジュールが残っている場合。
  2. 開発チーム向けに、1セットのYAMLだけでDB(VM)とアプリ(コンテナ)の両方を迅速に作成できるセルフサービス基盤を構築したい場合。
  3. すべてをGitOpsとKubernetesカスタムリソースで管理し、システム全体の構成を同期させたい場合。

KubeVirtを導入するための実践的ステップ

ステップ1:サーバーの「内功(スペック)」を確認する

KubeVirtをスムーズに動かすには、ノードがハードウェア仮想化をサポートしている必要があります。以下のコマンドで素早く確認しましょう。

virt-host-validate qemu

すべての項目が PASS と表示されれば問題ありません。もし FAIL が出る場合は、エミュレーション(ソフトウェア)モードを使用せざるを得ませんが、速度は亀のように遅くなるため、あくまで検証用として考えてください。

ステップ2:KubeVirt Operatorのインストール

KubeVirtのライフサイクルを最もプロフェッショナルに管理するために、Operatorを使用します。

# GitHubから最新バージョンを取得
export VERSION=$(curl -s https://api.github.com/repos/kubevirt/kubevirt/releases/latest | grep tag_name | cut -d '"' -f 4)

# Operatorとカスタムリソースをインストール
kubectl create -f https://github.com/kubevirt/kubevirt/releases/download/${VERSION}/kubevirt-operator.yaml
kubectl create -f https://github.com/kubevirt/kubevirt/releases/download/${VERSION}/kubevirt-cr.yaml

コーヒーを一杯飲んで、kubevirt ネームスペース内のPodが準備完了になるまで数分待ちましょう。

ステップ3:操作ツール virtctl の準備

コンソールへのアクセスや起動・停止など、VMと深くやり取りするには kubectl だけでは不十分です。virtctl が必要になります。

curl -L -o virtctl https://github.com/kubevirt/kubevirt/releases/download/${VERSION}/virtctl-${VERSION}-linux-amd64
chmod +x virtctl
sudo mv virtctl /usr/local/bin/

ステップ4:最初の仮想マシンを起動する

これは「超軽量」なFedoraを動かすためのYAMLサンプルです。コンテナイメージから起動するため、約30秒でブートが完了します。

apiVersion: kubevirt.io/v1
kind: VirtualMachine
metadata:
  name: itfromzero-vm
spec:
  running: false 
  template:
    spec:
      domain:
        devices:
          disks:
            - name: containerdisk
              disk: {}
          interfaces:
            - name: default
              masquerade: {}
        resources:
          requests:
            memory: 1024Mi
      networks:
        - name: default
          pod: {}
      volumes:
        - name: containerdisk
          containerDisk:
            image: kubevirt/fedora-cloud-container-disk-demo

ファイルを適用した後、以下のコマンドで仮想マシンを目覚めさせます。

virtctl start itfromzero-vm

実践で「ハマらない」ためのヒント

最もよく遭遇するエラーは、Storage ClassがReadWriteMany (RWX)をサポートしていないことです。ライブマイグレーション(ダウンタイムなしでノード間をVM移動)を行いたい場合、ストレージは複数の場所から同時にアクセスできる必要があります。単一ノードでのテストでない限り、ローカルパスは使用しないでください。

また、CDI (Containerized Data Importer) についても調べてみてください。これにより、.qcow2 や .iso ファイルをURLから直接PVCに取り込むことができ、手動でDockerイメージをビルドするよりも遥かに便利です。

KubeVirtは、あらゆるシナリオでVMwareやProxmoxを完全に置き換えるものではないかもしれませんが、「Single Pane of Glass(単一の管理画面)」という集中管理モデルを実現するための鍵となります。ラボの構築が成功することを願っています。困ったことがあれば、下のコメント欄に気軽に残してくださいね!

Share: