Virshを用いたヘッドレスKVM/QEMU仮想化:CLIによる仮想マシン構築とブリッジネットワーク

Linux tutorial - IT technology blog
Linux tutorial - IT technology blog

クイックスタート(5分)

本番環境で仮想マシンを稼働させるのに、ProxmoxやVMware ESXi、あるいはメモリを大量消費するデスクトップ環境は必須ではありません。LinuxカーネルのKVM、内部動作を担うQEMU、そしてライフサイクルを管理するvirshを組み合わせれば、普段お使いのシェルが高性能で堅牢なハイパーバイザーコンソールへと早変わりします。

まず、お使いのプロセッサがハードウェア仮想化支援機構(Intel VT-xまたはAMD-V)に対応しているか確認します。

grep -E -c '(vmx|svm)' /proc/cpuinfo

出力された数値が0より大きければ、CPUの準備は完了です。続いて、UbuntuまたはDebianにハイパーバイザー関連ツールをインストールします。

sudo apt update
sudo apt install -y qemu-kvm libvirt-daemon-system libvirt-clients virtinst bridge-utils
sudo systemctl enable --now libvirtd

普段使用している一般ユーザーアカウントにアクセス権限を付与し、日々のVM操作でsudoを不要にします。

sudo usermod -aG libvirt,kvm $USER
newgrp libvirt

ローカルのハイパーバイザーソケットへの接続を確認します。

virsh list --all

Id、Name、Stateのヘッダーを持つ空のテーブルが表示されれば、libvirtdが正常にリクエストを受け付けており、VMを展開できる状態です。

詳細解説:Virt-Installを用いたヘッドレスゲストの構築

BashからVMを管理する作業は、実質的にlibvirt向けのXMLドメイン定義を作成することに集約されます。virt-installを使えば、生のXMLを手書きすることなく、コマンドライン引数を検証済みのハードウェア定義へと自動変換してくれます。

ストレージボリュームの準備

Libvirtはデフォルトで/var/lib/libvirt/images配下にディスクイメージを保存します。Rawイメージは前もってディスク領域をすべて確保しますが、QCOW2形式は必要に応じて動的にサイズが拡張されます。ディスク性能とホスト側ストレージ消費のバランスを取るため、メタデータ事前割り当て(metadata preallocation)を有効にした25GBのスパースQCOW2ディスクを作成しましょう。

sudo qemu-img create -f qcow2 -o preallocation=metadata /var/lib/libvirt/images/web-server-01.qcow2 25G

新規作成されたイメージは、ホストのファイルシステム上では約350MBしか占有しませんが、ゲストOS側からは完全な25GBのブロックデバイスとして認識されます。

無人ヘッドレスゲストのプロビジョニング

ヘッドレスサーバーにはディスプレイハードウェアが存在しません。Ubuntu 22.04では従来のdebian-installerからSubiquityへと刷新されたため、ネットブートインストーラーのURLを直接渡す手法は失敗することがよくあります。その代わりに、公式のクラウドイメージまたはISOファイルを用意し、シリアルコンソールのカーネル引数と併せて指定します。

sudo virt-install \
  --name web-server-01 \
  --memory 2048 \
  --vcpus 2 \
  --disk path=/var/lib/libvirt/images/web-server-01.qcow2,format=qcow2,bus=virtio \
  --os-variant ubuntu22.04 \
  --network network=default,model=virtio \
  --graphics none \
  --cdrom /var/lib/libvirt/images/ubuntu-22.04.4-live-server-amd64.iso \
  --console pty,target_type=serial

VirtIOドライバーを採用することで、エミュレーションのオーバーヘッドを大幅に削減できます。一般的なIDEやe1000エミュレーションと比較して、ネットワークおよびディスクのスループットがおよそ15%〜30%向上します。

稼働中いつでも次のコマンドでゲストのテキストコンソールにアタッチできます。

virsh console web-server-01

シリアルコンソールから抜けてホストのプロンプトに戻るには、Ctrl + ]を押します。

日常的なVMライフサイクル管理

日々の運用管理は、わずかなシンプルなコマンドで完結します。

  • VMの起動: virsh start web-server-01
  • ACPI経由の正常なシャットダウン: virsh shutdown web-server-01
  • 強制電源オフ(電源プラグを抜く動作): virsh destroy web-server-01
  • ホスト起動時の自動起動を有効化: virsh autostart web-server-01
  • 仮想ドライブごとゲストを削除: virsh undefine web-server-01 --remove-all-storage

引数なしの単純なvirsh undefineでは、ファイルシステム上に孤立したディスクイメージがそのまま残ってしまう点に注意してください。ストレージ容量を完全に解放したい場合は、必ず--remove-all-storageを付与しましょう。

高度な活用法:ブリッジネットワークと動的チューニング

libvirtはデフォルトで、仮想マシンをプライベートNATネットワーク(virbr0、通常は192.168.122.0/24)の背後に配置します。パッケージのダウンロード用途などには十分ですが、社内LANや自宅ラボのサブネットからインバウンドトラフィックをルーティングするには煩雑なポートフォワーディング設定が必要になります。ネットワークブリッジを利用すれば、仮想インターフェースを物理NICに直接バインドできるため、この手間を解消できます。

システムブリッジへのゲスト接続

ここでは、LinuxホストがNetplanやNetworkManagerを介して物理NIC eth0をbr0にブリッジ設定済みであると仮定します。既存のホストファイアウォールルールを崩すことなく、このブリッジをlibvirtに公開できます。

以下のネットワーク定義をhost-bridge.xmlとして保存します。

<network>
  <name>host-bridge</name>
  <forward mode="bridge"/>
  <bridge name="br0"/>
</network>

libvirtにこのブリッジ構成を登録・有効化します。

virsh net-define host-bridge.xml
virsh net-start host-bridge
virsh net-autostart host-bridge

virt-installのパラメータを--network network=host-bridge,model=virtioに変更します。これでゲストは物理スイッチ経由で直接DHCPリクエストをブロードキャストし、物理ラックマウントサーバーと同様に通常のLAN内IPアドレス(例:192.168.1.145)を取得します。

稼働中リソース割り当ての動的変更

RAM容量を変更するためだけに、本番環境のデータベースやWebノードを再起動するのは望ましくありません。幸い、KVMとQEMUはvirtioバルーンドライバーを利用したメモリおよびCPUのホットプラグに対応しています。

ドメインXMLで最大メモリ上限(例:ベースライン2GB、最大8GB)が定義されていれば、キビバイト単位で割り当てRAMを即座に増減できます。

virsh setmem web-server-01 4194304 --live

実行中のデータベース接続を切断することなく、わずか数秒でゲスト内の利用可能メモリが4GBへ拡張されます。同様に、アクティブなvCPU数もハードウェア上限までスケール可能です。

virsh setvcpus web-server-01 4 --live

割り当て中のリソース上限は、virsh dominfo web-server-01でいつでも確認できます。

本番ワークロード向けの実践的ヒント

ヘッドレス仮想化を安定稼働させるには、規律あるリソース配分計画が欠かせません。管理の行き届かないメモリの膨張や暴走したI/Oは、物理ノード全体を停止させてしまう恐れがあります。

ホストのメモリ枯渇を防ぐ

稼働中の本番ゲスト間でRAMをオーバーコミットすることは避けてください。32GBの物理ホスト上で、それぞれ6GBを割り当てた6台のVMを動かしている場合、急激なトラフィック急増によってカーネルのOut-Of-Memory(OOM)キラーが発動する危険があります。これが起きると、ホストカーネルが主要なqemu-system-x86_64プロセスを強制終了してしまうことがあります。ホストカーネルのタスクやI/Oキャッシュ専用として、未割り当てのホストRAMを最低でも2GB〜4GBは確保しておきましょう。

迅速なデプロイ前スナップショット

重要なシステムアップグレードやリバースプロキシの再構成を実行する前に、アトミックなクラッシュ整合性スナップショットを取得しておきます。

virsh snapshot-create-as --domain web-server-01 \
  --name "pre-nginx-upgrade" \
  --description "カスタムOpenRestyビルドのコンパイル前スナップショット" \
  --atomic

万が一アップデートによってシステムライブラリが破損した場合でも、約2秒で保存済みのベースラインへロールバックできます。

virsh snapshot-revert web-server-01 pre-nginx-upgrade

トラブルシューティング:シリアルコンソールのフリーズ

virsh console web-server-01を実行すると、Connected to domain web-server-01と表示されたままシェルプロンプトが出ず、応答が止まったように見えることがあります。この場合、Enterキーを押すと復帰することがよくあります。それでも画面に何も表示されない場合は、ゲストOS側でttyS0に対するgettyリスナーが起動していません。

一度SSH経由でログインし、systemdのシリアルgettyユニットを有効化してください。

sudo systemctl enable --now [email protected]

軽量なQCOW2ストレージとネイティブなブリッジネットワークを組み合わせることで、極めて高速かつスクリプト制御しやすいハイパーバイザー環境が整います。不要なデスクトップ環境によるリソース消費を完全に排除し、緻密な制御性とネイティブクラスのパフォーマンスを手に入れましょう。

Share: