Kubernetesで仮想マシンを実行する:自宅ラボへのKubeVirt導入ガイド

HomeLab tutorial - IT technology blog
HomeLab tutorial - IT technology blog

なぜKubernetesで仮想マシンを実行するのか?

多くの自宅ラボ(HomeLab)愛好家は、PlexのようなメディアサーバーやシンプルなWebアプリをホストするために、Dockerや軽量なKubernetesクラスターから使い始めます。しかし、やがて壁に突き当たります。特殊なネットワークアプライアンスや、コンテナ化を拒むレガシーなWindowsアプリ、あるいは特定のLinuxカーネルバージョンが必要になることがあるからです。通常、このような場合はProxmoxやESXiといった別のハイパーバイザーを別途維持管理する必要があります。

2つの異なるコントロールプレーンを使い分けることは、設定の不整合(構成ドリフト)や精神的な疲労の原因になります。私は、すべてを単一のAPIで管理する方法を求めていました。KubeVirtはKubernetesを拡張することでこのギャップを埋め、他のPodと同じように仮想マシン(VM)をスケジュールし、管理できるようにします。私はこの構成を1年以上運用してレガシーなビルドサーバーをホストしていますが、管理の手間を半分に減らしつつ、非常に堅牢な安定性を維持しています。

KubeVirtアプローチのメリット

  • 統合されたネットワーキング: VMを標準のKubernetes ServiceやIngressの背後に配置できます。つまり、Windows VMウェもWebコンテナと同じTraefikやNginxロードバランサーの恩恵を受けられるということです。
  • 宣言的な管理: VMをYAMLファイルで定義できます。インフラ全体をGitでバージョン管理し、kubectl applyだけでデプロイ可能です。
  • リソースの効率化: 専用のハイパーバイザーOSを必要としません。ノードに空きRAMがあれば、そこでVMを実行できます。私のテストでは、KubeVirtランチャーPodのオーバーヘッドはごくわずかで、通常は100MB未満のRAM消費です。

インストール:クラスターの準備

YAMLを記述する前に、ハードウェアが仮想化をサポートしているか確認してください。KubeVirtはPod内でKVMを実行します。Kubernetesノード自体が仮想マシンである場合(入れ子になった仮想化:ネストされた仮想化)、まず基盤となるハイパーバイザーでその機能を有効にする必要があります。

ステップ 1: ハードウェア仮想化の確認

ノードで次のコマンドを実行し、VMX(Intel)またはSVM(AMD)拡張機能が有効かどうかを確認します。

grep -E 'vmx|svm' /proc/cpuinfo

出力が空の場合は、BIOS設定を確認してください。Raspberry PiのようなARMボードで実行する場合、KubeVirtはソフトウェアエミュレーションを使用できます。ただし、ハードウェアアクセラレーションによる仮想化よりも10倍近く遅くなることが多いため、注意が必要です。

ステップ 2: KubeVirt Operatorのデプロイ

KubeVirtは、自身のライフサイクルを管理するためにOperatorパターンを使用します。これにより、必要なカスタムリソース定義(CRD)のインストールといった重労働が処理されます。互換性を確保するため、常に公式リリースから最新のバージョン文字列を取得してください。

# 最新バージョンを取得
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

# KubeVirtカスタムリソースをデプロイ
kubectl create -f https://github.com/kubevirt/kubevirt/releases/download/${VERSION}/kubevirt-cr.yaml

ステップ 3: virtctlのインストール

標準のkubectlコマンドでも基本的なタスクは行えますが、より詳細な制御にはvirtctlバイナリが必要になります。これはVNCコンソール、VMの起動/停止、イメージのアップロードなどを処理します。20MB程度のダウンロードで、運用が大幅に楽になります。

VERSION=$(curl -s https://api.github.com/repos/kubevirt/kubevirt/releases/latest | grep tag_name | cut -d '"' -f 4)
curl -L -o virtctl https://github.com/kubevirt/kubevirt/releases/download/${VERSION}/virtctl-${VERSION}-linux-amd64
chmod +x virtctl
sudo install virtctl /usr/local/bin/virtctl

設定:ストレージとイメージ

数ギガバイトのISOやQCOW2イメージをクラスターに取り込む作業は、通常このプロセスで最も困難な部分です。KubeVirtはContainerized Data Importer (CDI) を使用してこれを自動化します。CDIは、HTTPサーバーやS3バケットから直接イメージをプルし、Persistent Volumeに書き込むことができます。

CDIのインストール

export VERSION=$(curl -s https://api.github.com/repos/kubevirt/containerized-data-importer/releases/latest | grep tag_name | cut -d '"' -f 4)
kubectl create -f https://github.com/kubevirt/containerized-data-importer/releases/download/${VERSION}/cdi-operator.yaml
kubectl create -f https://github.com/kubevirt/containerized-data-importer/releases/download/${VERSION}/cdi-cr.yaml

最初の仮想マシンの作成

CDIが起動したら、VMを定義できます。この例ではFedora Cloudイメージを使用します。DataVolumeセクションは、CDIに400MBのイメージを取得させ、10GBのディスクを自動的に準備するよう指示します。

apiVersion: kubevirt.io/v1
kind: VirtualMachine
metadata:
  name: fedora-vm
spec:
  running: false
  template:
    spec:
      domain:
        devices:
          disks:
          - disk: {bus: virtio}
            name: datavolumedisk
        resources:
          requests:
            memory: 2Gi
      volumes:
      - dataVolume:
          name: fedora-dv
        name: datavolumedisk
  dataVolumeTemplates:
  - metadata:
      name: fedora-dv
    spec:
      storage:
        resources:
          requests:
            storage: 10Gi
        storageClassName: local-path
      source:
        http:
          url: "https://download.fedoraproject.org/pub/fedora/linux/releases/38/Cloud/x86_64/images/Fedora-Cloud-Base-38-1.6.x86_64.qcow2"

マニフェストを適用すると、「importer」Podが起動します。ギガビット接続であれば、VMの起動準備が整うまで、イメージのダウンロードと検証に通常約45秒かかります。

検証とモニタリング

私は通常、最初のYAMLでrunning: falseを設定します。これにより、イメージのダウンロード中にVMが起動しようとするのを防げます。PVCのステータスが「Bound」になったら、準備完了です。

VMの起動

新しいCLIツールを使用してマシンを起動します:

virtctl start fedora-vm

コンソールへのアクセス

KubeVirtのターミナル統合は非常に優れています。IPアドレスを探したりSSHを設定したりすることなく、シリアルコンソールに直接入ることができます:

virtctl console fedora-vm

Windows VMやLinuxデスクトップの場合は、VNCトンネルを使用します。次のコマンドはローカルポートを開き、デフォルトのVNCビューアを起動します:virtctl vnc fedora-vm

現場からの重要なポイント

  • VirtIOを優先する: 常にbus: virtioを使用してください。私のベンチマークでは、VirtIOドライバーはエミュレートされたSATAと比較して最大3倍高速なディスクI/Oを提供します。
  • Cloud-Initで自動化する: ユーザーを手動で作成して時間を無駄にしないでください。cloudInitNoCloudを使用して、最初の起動時にSSH公開鍵やネットワーク設定を注入しましょう。
  • 高度なネットワーキング: VMに(10.x.x.xのクラスターIPではなく)自宅のVLAN上の実際のIPを持たせたい場合は、Multus CNIを検討してください。これにより、VMを物理ネットワークインターフェースに直接ブリッジできます。

KubeVirtをセットアップすることで、Kubernetesクラスターは真のプライベートクラウドへと進化します。YAMLベースのVM管理には多少の学習曲線がありますが、スタック全体を一箇所で管理できるメリットは、あらゆる自宅ラボにとって大きなアップグレードとなるはずです。

Share: