背景:深夜2時にproduction VMがハングしたとき
午前2時17分。スマートフォンが振動した――顧客からwebアプリが応答しないと連絡が来た。hypervisorホストにSSH接続したが、GUIもwebパネルもなく、あるのは真っ白なターミナルだけ。このとき気づいた:virshを知っているかどうかが、問題を解決してまた眠れるか、朝まで手探りするかの分かれ目だと。
自分はProxmox VEで12台のVMとコンテナを管理するhomelabを運用している――productionに持ち込む前にあれこれ試すplaygroundだ。ProxmoxはWeb UIが便利だが、内部ではlibvirtとQEMUを使っている。データセンターに借りているbare-metalサーバーでは、使えるのはSSHとvirshだけ。この記事は、教科書の理論ではなく、実際にproductionで役立っているものをまとめたものだ。
アーキテクチャを簡単に説明すると:libvirtはKVM/QEMU上の抽象化レイヤーで、覚えにくいパラメーターを大量に並べてQEMUを直接呼び出す代わりに、libvirt APIをすっきり使える。virsh(virtualization shell)はlibvirtのCLIクライアントで、あの深夜2時にターミナルで叩いていたものだ。なぜGUIを使い続けずvirshを学ぶべきなのか?
- リモートサーバーにdesktop environmentがない
- スクリプト自動化:デプロイのたびにスナップショット、定期バックアップ
- 管理ツールのWeb UIにもアクセスできないときのVM障害デバッグ
- 10台以上のVMを同時管理:ループコマンド1つで完結、1台ずつクリックする必要がない
libvirtと関連ツールのインストール
インストール前に、CPUが仮想化をサポートしているか確認する:
grep -E '(vmx|svm)' /proc/cpuinfo | head -1
# vmx = Intel VT-x、svm = AMD-V
# 出力が空の場合 → BIOSでVTが無効 — BIOS設定でVTを有効にする
Ubuntu/Debianへのインストール:
sudo apt update
sudo apt install -y qemu-kvm libvirt-daemon-system libvirt-clients \
bridge-utils virtinst virt-top cpu-checker
# KVMが正常に読み込まれているか確認
sudo kvm-ok
# 期待される出力: INFO: /dev/kvm exists — KVM acceleration can be used
CentOS/RHEL/AlmaLinuxの場合:
sudo dnf install -y qemu-kvm libvirt libvirt-client virt-install virt-top
sudo systemctl enable --now libvirtd
sudoなしでvirshを使えるようにlibvirtグループにユーザーを追加する:
sudo usermod -aG libvirt,kvm $USER
newgrp libvirt # ログアウトせずにすぐ反映
VMの作成から日常運用まで
virt-installで最初のVMを作成する
ISOからVMを作成する最速の方法:
sudo virt-install \
--name ubuntu-server-01 \
--ram 2048 \
--vcpus 2 \
--disk path=/var/lib/libvirt/images/ubuntu-server-01.qcow2,size=20,format=qcow2 \
--os-variant ubuntu22.04 \
--network bridge=virbr0 \
--graphics none \
--console pty,target_type=serial \
--location 'http://archive.ubuntu.com/ubuntu/dists/jammy/main/installer-amd64/' \
--extra-args 'console=ttyS0,115200n8 serial'
# 有効なos-variantの一覧を確認する:
osinfo-query os | grep ubuntu
あるいはcloud imageがある場合 — ISOからのインストールより約15分速く、自分がよく使う方法だ:
# Ubuntu 22.04 cloud imageをダウンロード
wget -O /var/lib/libvirt/images/ubuntu-22.04-base.qcow2 \
https://cloud-images.ubuntu.com/jammy/current/jammy-server-cloudimg-amd64.img
# base imageからVMを作成(copy-on-write、ディスク節約)
sudo qemu-img create -f qcow2 -b /var/lib/libvirt/images/ubuntu-22.04-base.qcow2 \
-F qcow2 /var/lib/libvirt/images/vm-test.qcow2 20G
日常的に使うvirshコマンド
覚えやすいようにグループ分けする:
VM状態の確認:
virsh list --all # 全VMを表示(running + stopped)
virsh dominfo ubuntu-server-01 # 1つのVMの詳細情報
virsh domstate ubuntu-server-01 # 状態のみを確認
virsh vcpuinfo ubuntu-server-01 # CPUアフィニティと使用状況
virsh dommemstat ubuntu-server-01 # リアルタイムメモリ統計
VMの起動/停止:
virsh start ubuntu-server-01 # VMを起動
virsh shutdown ubuntu-server-01 # グレースフルシャットダウン(ACPIシグナル送信)
virsh destroy ubuntu-server-01 # 強制終了 — VMがハングして応答しないときに使用
virsh reboot ubuntu-server-01 # グレースフルリブート
virsh reset ubuntu-server-01 # ハードリセット(リセットボタンを押すのと同等)
あの深夜2時に使ったコマンド:
# VMが全く応答しない — まずグレースフルを試す
virsh shutdown production-web-01
# 30秒待って、シャットダウンしなければ:
virsh destroy production-web-01
# 再起動
virsh start production-web-01
# コンソールでブートログを確認
virsh console production-web-01
# コンソールを終了: Ctrl+]
スナップショット — 最も助けられた機能
デプロイやシステムアップデートの前に、必ずスナップショットを取る。10秒かかるが、問題が発生したときの手動ロールバックに要する時間を大幅に節約できる:
# スナップショットを作成(VMは実行中または停止中)
virsh snapshot-create-as ubuntu-server-01 \
--name "before-nginx-upgrade" \
--description "nginx 1.24アップグレード前のスナップショット" \
--atomic
# スナップショット一覧を表示
virsh snapshot-list ubuntu-server-01
# スナップショットの詳細情報を確認
virsh snapshot-info ubuntu-server-01 before-nginx-upgrade
# 古いスナップショットにロールバック(アップグレード失敗時)
virsh snapshot-revert ubuntu-server-01 before-nginx-upgrade
# 不要なスナップショットを削除
virsh snapshot-delete ubuntu-server-01 before-nginx-upgrade
VMのクローン
クローンは最初からインストールするより約20分速い――テスト用VMを素早く立ち上げたり、ステージング環境を複製するときに便利だ:
# クローン前に元のVMをシャットダウン
virsh shutdown ubuntu-server-01
# クローン実行
sudo virt-clone \
--original ubuntu-server-01 \
--name ubuntu-server-02 \
--auto-clone
# ディスクパスを指定してクローン
sudo virt-clone \
--original ubuntu-server-01 \
--name ubuntu-server-02 \
--file /var/lib/libvirt/images/ubuntu-server-02.qcow2
ストレージプールの管理
デフォルトでlibvirtはディスクイメージを/var/lib/libvirt/images/に保存する。専用SSDやNASをマウントしたときは、そこを指すストレージプールを作成してパフォーマンスを活用する:
# 既存のプールを表示
virsh pool-list --all
# カスタムディレクトリを指すプールを新規作成
virsh pool-define-as ssd-pool dir --target /mnt/ssd/libvirt/images
virsh pool-build ssd-pool
virsh pool-start ssd-pool
virsh pool-autostart ssd-pool
# プール内のボリュームを表示
virsh vol-list default
# ディスクイメージの実パスを取得
virsh vol-path --pool default ubuntu-server-01.qcow2
# VMのディスクをリサイズ(VMは停止中であること)
virsh vol-resize --pool default ubuntu-server-01.qcow2 30G
VM設定の変更
# XML設定を編集(デフォルトのEDITORを使用)
virsh edit ubuntu-server-01
# VMを停止せずRAMを変更(balloon driverがサポートしている場合)
virsh setmem ubuntu-server-01 4096M --live --config
# CPUを追加
virsh setvcpus ubuntu-server-01 4 --live --config
# ホスト再起動時に自動起動
virsh autostart ubuntu-server-01
virsh autostart --disable ubuntu-server-01 # 自動起動を無効化
確認とモニタリング
リアルタイムリソース使用状況の確認
virt-topは、どのVMがCPUやRAMを食いすぎていると疑ったときに最初に叩くコマンドだ:
# VM向けtopコマンド — 非常に便利
virt-top
# 実行中の全VMの統計
virsh domstats --live
# 特定VMのCPU統計
virsh cpu-stats ubuntu-server-01 --total
# ディスクI/O統計
virsh domblkstat ubuntu-server-01 vda
# ネットワーク統計
virsh domifstat ubuntu-server-01 vnet0
VM障害時のログ確認
# libvirtdデーモンのログ
sudo journalctl -u libvirtd -f
# 各VMのQEMUログ(非常に詳細、デバッグ時に使用)
sudo cat /var/log/libvirt/qemu/ubuntu-server-01.log | tail -50
# 現在のVM XML設定を確認(ランタイム情報を含む)
virsh dumpxml ubuntu-server-01
# libvirt接続が正常かチェック
virsh -c qemu:///system version
全VMの簡易バックアップスクリプト
このスクリプトには少なくとも3回助けられた――直近では、カーネルアップデートでVMが起動できなくなったときだ。新しい設定を試す前に毎晩実行している:
#!/bin/bash
# snapshot-all.sh — 実行中の全VMをスナップショット
SNAP_NAME="daily-$(date +%Y%m%d)"
for vm in $(virsh list --name --state-running); do
echo "Snapshotting $vm..."
virsh snapshot-create-as "$vm" \
--name "$SNAP_NAME" \
--description "Auto daily snapshot" \
--atomic && echo "OK: $vm" || echo "FAILED: $vm"
done
echo "Done. Snapshots:"
virsh snapshot-list --all 2>/dev/null || true
よくあるエラー
これら3つのエラーは、初回セットアップ時に最もよく現れる――そしてシステムアップデート後にも再発しがちだ:
エラー: error: Failed to connect socket to '/var/run/libvirt/libvirt-sock'
sudo systemctl start libvirtd
# またはソケットを確認:
ls -la /var/run/libvirt/
エラー: error: Cannot access storage file — VM起動時
# ファイルのパーミッションを確認
ls -la /var/lib/libvirt/images/
# パーミッションを修正
sudo chown libvirt-qemu:kvm /var/lib/libvirt/images/*.qcow2
sudo chmod 660 /var/lib/libvirt/images/*.qcow2
VMがシャットダウンできない(シャットダウンタイムアウト):
# /etc/libvirt/qemu.confでシャットダウンタイムアウトを延長:
# shutdown_timeout = 60 (秒)
# その後libvirtdを再起動
sudo systemctl restart libvirtd
あの深夜2時の一件の後、これらのコマンドを全部virsh-cheatsheet.mdというファイルにまとめてサーバーに置いた。覚えられないからではなく――ストレス下では、cheatsheetを見る方がGoogleで検索するより断然速いからだ。

