UbuntuでKVMをインストール・使用するガイド:ゼロから最初の仮想マシンを起動するまで

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

問題: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-clientsvirshを含むCLIツール群 — 日常的に使うメインコマンド
  • bridge-utils:VMがLAN上で直接IPを取得したい場合(ブリッジネットワーク)に必要
  • virtinstvirt-installvirt-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で十分だ — シンプルで、ホストのネットワーク設定を変更する必要がない。

Share: