問題:GUIなしのLinuxサーバーで仮想マシンを動かしたい
新しいディストリビューションをテストしたい、危険なスクリプトを試すためのサンドボックス環境を構築したい、あるいは複数のシステムを同時に動かしたい — そんな場面は多い。VirtualBoxはお馴染みの選択肢だが、モニターのないUbuntuサーバーにVirtualBoxを入れても意味がない。それどころか、モニターがある環境でも、カーネルアップデートのたびにモジュールが壊れてsudo /sbin/vboxconfigを実行し直す羽目になる — 正直うんざりする。
自分はProxmox VEで12台のVMとコンテナを管理するhomelabを動かしている。本番環境に上げる前に何でも試せるplaygroundだ。ProxmoxはKVMをベースに構築されている。それなら、独自のディストリビューションを丸ごとインストールせずにシンプルなセットアップが必要なとき、直接UbuntuでKVMを使えばいいじゃないか?
分析:KVMとVirtualBoxの重要な違い
KVM(Kernel-based Virtual Machine)はタイプ1ハイパーバイザーで、CPUの仮想化拡張機能(Intel VT-xまたはAMD-V)を通じてハードウェア上で直接動作する。Linux 2.6.20カーネルから統合されているため、追加インストール不要であらゆるモダンなディストリビューションで利用できる。一方VirtualBoxはタイプ2ハイパーバイザーで、ホストOS上の通常のアプリケーションとして動作し、その分オーバーヘッドが生じる。
サーバー環境でVirtualBoxからKVMに完全移行した3つの理由:
- ネイティブに近いパフォーマンス:KVM上のVMは実機の95〜98%のパフォーマンスを発揮できる。特にvirtioドライバー使用時のディスクI/OとネットワークはVirtualBoxと比べ物にならない
- カーネルアップデートで壊れない:KVMは公式のカーネルモジュールであり、VirtualBoxのような外部DKMSモジュールではない。カーネルを更新してもそのまま動く
- 柔軟な管理方法:virsh(CLI)、virt-manager(GUI)、Cockpit(Web UI)と、環境に合わせてツールを選べる
UbuntuへのKVMインストール手順
ステップ1:CPUがハードウェア仮想化をサポートしているか確認する
このステップを省略してインストールを進めると、CPUが対応していないことが後でわかる — 最初からやり直しになるので必ず確認しよう:
egrep -c '(vmx|svm)' /proc/cpuinfo
0より大きい数値が出ればOK。0が返った場合はBIOSに入ってVT-x(Intel)またはAMD-Vを有効にする必要がある。より明確に確認する方法:
sudo apt install cpu-checker -y
kvm-ok
期待されるOutput:KVM acceleration can be used
ステップ2:KVMと関連ツールをインストールする
sudo apt update
sudo apt install -y \
qemu-kvm \
libvirt-daemon-system \
libvirt-clients \
bridge-utils \
virtinst \
virt-manager
各パッケージの役割:
qemu-kvm:ハードウェアをエミュレートしてVMを動かすコアエンジンlibvirt-daemon-system:Unixソケット経由でVMを管理するデーモン。統一APIを提供するlibvirt-clients:virshを含むCLIツール群 — 日常的に使うメインコマンドbridge-utils:VMがLAN上で直接IPを取得したい場合(ブリッジネットワーク)に必要virtinst:virt-installとvirt-cloneを提供するvirt-manager:VM管理のGUI(デスクトップ環境がある場合のみ必要)
ステップ3:現在のユーザーをlibvirtおよびkvmグループに追加する
このステップを省略すると、virshのコマンドをすべてsudoで実行しなければならなくなる — かなり面倒だ:
sudo usermod -aG libvirt $USER
sudo usermod -aG kvm $USER
ログアウトして再ログインする。ログアウトせずにすぐ反映させたい場合:
newgrp libvirt
ステップ4:libvirtデーモンが起動していることを確認する
sudo systemctl enable --now libvirtd
systemctl status libvirtd
Statusがactive (running)であればOK。初回インストール時、libvirtのデフォルトNATネットワーク(virbr0)が自動起動しないことがある — 手動で有効にする:
virsh net-list --all
virsh net-start default
virsh net-autostart default
ベストプラクティス:virsh + virt-installでVMを作成・管理する
ISOから最初のVMを作成する
まずISOをダウンロードし(例:Ubuntu Server 22.04)、virt-installを実行する:
virt-install \
--name ubuntu-test \
--ram 2048 \
--vcpus 2 \
--disk path=/var/lib/libvirt/images/ubuntu-test.qcow2,size=20,format=qcow2 \
--os-variant ubuntu22.04 \
--network network=default \
--graphics none \
--console pty,target_type=serial \
--location /home/user/ubuntu-22.04-live-server-amd64.iso \
--extra-args 'console=ttyS0,115200n8 serial'
よく混乱しがちな3つのパラメーター:
--disk format=qcow2:シンプロビジョニングのディスク — ホスト上のファイルは実際に使用している容量しか占有せず、最初から20GB全部を使うわけではない--os-variant ubuntu22.04:KVMはこの情報を使ってIOスケジューラやクロックなどの設定を最適化する — 間違ったOS variantを指定するとパフォーマンスに影響が出る。一覧確認:osinfo-query os | grep ubuntu--graphics none --console pty:VNC/SPICEの代わりにシリアルコンソールを使用 — モニターのないサーバーやSSHでリモート管理する環境に適している
日常的に使うvirshコマンド
# VMの一覧を表示(停止中のものも含む)
virsh list --all
# VMの起動・停止
virsh start ubuntu-test
virsh shutdown ubuntu-test # 安全なシャットダウン(ACPIシグナルを送信)
virsh destroy ubuntu-test # 強制停止(電源プラグを抜くのと同じ)
# コンソールに接続
virsh console ubuntu-test
# コンソールの終了:Ctrl + ]
# リスクのある作業の前にスナップショットを取る
virsh snapshot-create-as ubuntu-test snap-before-upgrade
virsh snapshot-revert ubuntu-test snap-before-upgrade
virsh snapshot-list ubuntu-test
# VMとすべてのディスクを削除
virsh undefine ubuntu-test --remove-all-storage
VMのクローン — 大幅な時間節約
新しいVMが必要なたびに最初からインストールするのは時間の無駄だ。実用的なアプローチは、OSと基本パッケージを入れた「ベース」VMを用意しておき、必要なときにクローンすること。virt-cloneならOSインストールに数時間かかる代わりに数十秒で完了する:
# 元のVMをシャットダウン
virsh shutdown ubuntu-base
# クローンを実行
virt-clone \
--original ubuntu-base \
--name ubuntu-clone-1 \
--auto-clone
クローン後、新しいVMにSSHでログインし、ホスト名の変更とSSHホストキーの再生成を行う:
sudo hostnamectl set-hostname ubuntu-clone-1
sudo rm /etc/ssh/ssh_host_*
sudo dpkg-reconfigure openssh-server
リソースの確認とディスクのリサイズ
# VMのCPU/RAMをリアルタイムモニタリング
virt-top
# 現在のディスクイメージを確認
virsh vol-list --pool default
# ディスクのリサイズ(VMを停止してから実行)
sudo qemu-img resize /var/lib/libvirt/images/ubuntu-test.qcow2 +10G
# その後VMの中でgrowpart + resize2fsを実行してOSに新しいディスクサイズを認識させる
よくあるエラーと対処法
グループに追加したのにvirshが「permission denied」を返す
最もよくある原因:usermod後にログアウト/ログインをしていない。groupsコマンドを実行してlibvirtが出力に含まれていなければ、それが問題だ。ログアウトなしの即効解決策:
newgrp libvirt
virsh list --all
VMを作成したが起動すると画面が真っ黒
--os-variantが正しくないことが多い。新しいディストリビューションの場合、古いlibvirtにはエントリがない可能性がある — osinfo-query os | grep ubuntuで正確な名前を確認しよう。見つからなければ--os-variant linux2022を使う。
VMからインターネットにpingが届かない
デフォルトネットワークはNATを使用している — defaultネットワークが起動しているか確認しよう:
virsh net-list --all
# 「default」が「inactive」状態の場合:
virsh net-start default
VMがホストと同じLANセグメントで独自のIPを持つ必要があれば、次のステップとしてブリッジネットワークを設定する。ただしラボやテスト目的であれば、デフォルトのNATで十分だ — シンプルで、ホストのネットワーク設定を変更する必要がない。
