Virtualization KVM QEMU libvirt

仮想化技術 KVM/QEMU/libvirt 完全ガイド

目次

  1. はじめに
  2. 仮想化の基本概念
  3. KVM アーキテクチャ
  4. インストールと初期設定
  5. libvirt 管理レイヤー
  6. virsh コマンド詳細
  7. virt-install による VM 作成
  8. virt-manager GUI
  9. VM 設定(XML ドメイン定義)
  10. ストレージ管理
  11. ネットワーク設定
  12. CPU/メモリピンニングと NUMA
  13. スナップショットとクローニング
  14. cloud-init 統合
  15. パフォーマンス最適化
  16. トラブルシューティング
  17. ベストプラクティス
  18. 参考文献

1. はじめに

仮想化技術は現代の IT インフラストラクチャにおいて不可欠な基盤技術である。物理サーバーのリソースを効率的に活用し、柔軟なインフラ管理を可能にする。本ドキュメントでは、Linux における主要な仮想化スタックである KVM(Kernel-based Virtual Machine)、QEMU、および libvirt について、アーキテクチャから実践的な運用までを詳細に解説する。


2. 仮想化の基本概念

2.1 仮想化の種類

種類説明代表的な実装
完全仮想化 (Full Virtualization)ゲスト OS を無修正で実行KVM, VMware ESXi, Hyper-V
準仮想化 (Paravirtualization)ゲスト OS を修正して最適化Xen (PV), virtio ドライバ
ハードウェア支援仮想化CPU の仮想化拡張を利用KVM + VT-x/AMD-V
コンテナ型仮想化OS レベルの分離Docker, LXC, Podman
ハイパーバイザ型(Type 1)ハードウェア上で直接動作VMware ESXi, Xen
ホスト型(Type 2)ホスト OS 上で動作VirtualBox, VMware Workstation

2.2 完全仮想化

完全仮想化では、ゲスト OS のカーネルを一切修正せずに仮想環境上で実行できる。ハイパーバイザがハードウェアを完全にエミュレーションする。

┌─────────────────────────────────────────┐
│           ゲスト OS(無修正)              │
│     ┌──────────┐  ┌──────────┐          │
│     │ ゲスト1   │  │ ゲスト2   │          │
│     │ (Linux)  │  │ (Windows)│          │
│     └──────────┘  └──────────┘          │
├─────────────────────────────────────────┤
│         ハイパーバイザ / VMM              │
│    (ハードウェアエミュレーション)           │
├─────────────────────────────────────────┤
│           物理ハードウェア                 │
└─────────────────────────────────────────┘

2.3 準仮想化

準仮想化では、ゲスト OS のカーネルを修正し、ハイパーバイザと直接通信する「ハイパーコール」を使用する。virtio デバイスドライバは準仮想化の一形態である。

2.4 ハードウェア支援仮想化

Intel VT-x / AMD-V が提供する CPU レベルの仮想化支援機能により、効率的な仮想化を実現する。

# CPU の仮想化支援機能の確認
# Intel VT-x
$ grep -c vmx /proc/cpuinfo
8

# AMD-V
$ grep -c svm /proc/cpuinfo
0

# 詳細な確認
$ lscpu | grep -i virtualization
Virtualization:                     VT-x
Virtualization type:                full

# IOMMU の確認(VT-d / AMD-Vi)
$ dmesg | grep -i iommu
[    0.123456] DMAR: IOMMU enabled

3. KVM アーキテクチャ

3.1 KVM の概要

KVM (Kernel-based Virtual Machine) は Linux カーネルに統合されたハイパーバイザである。Linux カーネルそのものをハイパーバイザとして使用し、QEMU と連携してゲスト VM を実行する。

┌──────────────────────────────────────────────┐
│  ゲスト VM 1       ゲスト VM 2                 │
│  ┌────────────┐   ┌────────────┐             │
│  │ ゲスト OS   │   │ ゲスト OS   │             │
│  │ (Linux)    │   │ (Windows)  │             │
│  └────────────┘   └────────────┘             │
│  ┌────────────┐   ┌────────────┐             │
│  │ QEMU プロセス│   │ QEMU プロセス│            │
│  └────────────┘   └────────────┘             │
├──────────────────────────────────────────────┤
│                 libvirt                       │
│          (管理レイヤー / API)                  │
├──────────────────────────────────────────────┤
│           Linux カーネル + KVM モジュール       │
│  ┌────────────┐ ┌────────────┐               │
│  │ kvm.ko     │ │kvm_intel.ko│               │
│  └────────────┘ └────────────┘               │
├──────────────────────────────────────────────┤
│              物理ハードウェア                   │
│    CPU (VT-x/AMD-V)  メモリ  ストレージ  NIC   │
└──────────────────────────────────────────────┘

3.2 カーネルモジュール

# KVM カーネルモジュールの確認
$ lsmod | grep kvm
kvm_intel             364544  12
kvm                  1028096   1 kvm_intel
irqbypass              16384   1 kvm

# モジュールの読み込み
$ sudo modprobe kvm
$ sudo modprobe kvm_intel    # Intel の場合
$ sudo modprobe kvm_amd      # AMD の場合

# /dev/kvm の確認
$ ls -la /dev/kvm
crw-rw----+ 1 root kvm 10, 232 Apr 10 09:00 /dev/kvm

# KVM のネスト仮想化有効化
$ cat /sys/module/kvm_intel/parameters/nested
Y
# 無効の場合:
$ sudo modprobe -r kvm_intel
$ sudo modprobe kvm_intel nested=1
# 永続化: /etc/modprobe.d/kvm.conf
# options kvm_intel nested=1

3.3 QEMU との統合

QEMU は汎用のマシンエミュレータおよび仮想化実行環境である。KVM と組み合わせることで、ハードウェア支援による高性能な仮想化を実現する。

KVM なしの QEMU(純粋なエミュレーション):

  • 全てのハードウェアをソフトウェアでエミュレート
  • 非常に低速だが、異なるアーキテクチャのエミュレーションが可能

KVM ありの QEMU:

  • CPU 命令はハードウェアで直接実行
  • I/O デバイスのみ QEMU がエミュレート
  • ネイティブに近い性能を達成

3.4 ハードウェア要件

要件説明確認方法
CPU 仮想化拡張Intel VT-x / AMD-V`grep -E '(vmx
64ビット CPUx86_64 アーキテクチャuname -m
IOMMU (オプション)デバイスパススルー用dmesg | grep -i iommu
十分なメモリホスト + 全ゲストの合計free -h
ストレージSSD 推奨lsblk

4. インストールと初期設定

4.1 パッケージのインストール

# RHEL/CentOS/Rocky Linux 9
$ sudo dnf install qemu-kvm libvirt virt-install virt-viewer \
    libvirt-client bridge-utils virt-manager
$ sudo dnf install libguestfs-tools    # ゲストイメージ操作ツール

# Ubuntu/Debian
$ sudo apt install qemu-kvm libvirt-daemon-system libvirt-clients \
    virtinst virt-manager bridge-utils
$ sudo apt install libguestfs-tools

# パッケージの確認
$ rpm -qa | grep -E '(qemu|libvirt|virt)'   # RHEL系
$ dpkg -l | grep -E '(qemu|libvirt|virt)'    # Debian系

4.2 サービスの起動と確認

# libvirtd の起動
$ sudo systemctl enable --now libvirtd

# サービスの状態確認
$ systemctl status libvirtd
● libvirtd.service - Virtualization daemon
     Loaded: loaded (/usr/lib/systemd/system/libvirtd.service; enabled)
     Active: active (running) since Mon 2026-04-06 09:00:00 JST
       Docs: man:libvirtd(8)
   Main PID: 2345 (libvirtd)
      Tasks: 21 (limit: 32768)
     Memory: 25.6M
     CGroup: /system.slice/libvirtd.service
             └─2345 /usr/sbin/libvirtd --timeout 120

# KVM が利用可能か確認
$ virt-host-validate
  QEMU: Checking for hardware virtualization                                 : PASS
  QEMU: Checking if device /dev/kvm exists                                   : PASS
  QEMU: Checking if device /dev/kvm is accessible                            : PASS
  QEMU: Checking if device /dev/vhost-net exists                             : PASS
  QEMU: Checking if device /dev/net/tun exists                               : PASS
  QEMU: Checking for cgroup 'cpu' controller support                         : PASS
  QEMU: Checking for cgroup 'cpuacct' controller support                     : PASS
  QEMU: Checking for cgroup 'cpuset' controller support                      : PASS
  QEMU: Checking for cgroup 'memory' controller support                      : PASS
  QEMU: Checking for cgroup 'devices' controller support                     : PASS
  QEMU: Checking for cgroup 'blkio' controller support                       : PASS
  QEMU: Checking for device assignment IOMMU support                         : PASS
  QEMU: Checking if IOMMU is enabled by kernel                              : PASS

4.3 ユーザー権限の設定

# libvirt グループにユーザーを追加
$ sudo usermod -aG libvirt $(whoami)
$ sudo usermod -aG kvm $(whoami)

# グループの反映(再ログインまたは newgrp)
$ newgrp libvirt

# 権限の確認
$ groups
user libvirt kvm

# libvirt のポリシーキット設定(必要に応じて)
$ cat /etc/polkit-1/rules.d/50-libvirt.rules
polkit.addRule(function(action, subject) {
    if (action.id == "org.libvirt.unix.manage" &&
        subject.isInGroup("libvirt")) {
        return polkit.Result.YES;
    }
});

5. libvirt 管理レイヤー

5.1 libvirt の概要

libvirt は仮想化プラットフォームの統一管理 API を提供するライブラリおよびデーモンである。KVM/QEMU だけでなく、Xen、LXC、VirtualBox など複数の仮想化技術をサポートする。

5.2 libvirt のアーキテクチャ

┌──────────────────────────────────────────┐
│            管理ツール                      │
│  virsh  virt-manager  virt-install  API   │
├──────────────────────────────────────────┤
│              libvirt API                  │
│         (C, Python, Go, etc.)            │
├──────────────────────────────────────────┤
│           libvirtd デーモン               │
│  ┌──────┐ ┌──────┐ ┌──────┐ ┌──────┐   │
│  │ QEMU │ │ Xen  │ │ LXC  │ │ VBox │   │
│  │Driver│ │Driver│ │Driver│ │Driver│   │
│  └──────┘ └──────┘ └──────┘ └──────┘   │
├──────────────────────────────────────────┤
│         ハイパーバイザ / コンテナ           │
└──────────────────────────────────────────┘

5.3 接続 URI

# ローカル接続(システムモード)
$ virsh -c qemu:///system list --all

# ローカル接続(ユーザーモード)
$ virsh -c qemu:///session list --all

# リモート接続(SSH 経由)
$ virsh -c qemu+ssh://user@remote-host/system list --all

# リモート接続(TLS)
$ virsh -c qemu+tls://remote-host/system list --all

# デフォルト URI の設定
$ export LIBVIRT_DEFAULT_URI="qemu:///system"
# または ~/.config/libvirt/libvirt.conf
# uri_default = "qemu:///system"

6. virsh コマンド詳細

6.1 VM の作成と管理

# VM の一覧表示
$ virsh list --all
 Id   Name          State
-------------------------------
 1    web-server    running
 2    db-server     running
 -    test-vm       shut off
 -    dev-vm        shut off

# VM の詳細情報
$ virsh dominfo web-server
Id:             1
Name:           web-server
UUID:           a1b2c3d4-e5f6-7890-abcd-ef1234567890
OS Type:        hvm
State:          running
CPU(s):         4
CPU time:       1234.5s
Max memory:     8388608 KiB
Used memory:    8388608 KiB
Persistent:     yes
Autostart:      enable
Managed save:   no
Security model: selinux
Security DOI:   0
Security label: system_u:system_r:svirt_t:s0:c123,c456 (enforcing)

# VM の XML 設定を表示
$ virsh dumpxml web-server

# VM の自動起動を有効化
$ virsh autostart web-server
Domain 'web-server' marked as autostarted

# 自動起動を無効化
$ virsh autostart --disable web-server

6.2 VM のライフサイクル管理

# VM の起動
$ virsh start web-server
Domain 'web-server' started

# VM のシャットダウン(ゲスト OS にシャットダウン要求を送信)
$ virsh shutdown web-server
Domain 'web-server' is being shutdown

# VM の強制停止(電源ボタン長押しに相当)
$ virsh destroy web-server
Domain 'web-server' destroyed

# VM のリブート
$ virsh reboot web-server
Domain 'web-server' is being rebooted

# VM のサスペンド(一時停止)
$ virsh suspend web-server
Domain 'web-server' suspended

# VM のレジューム(再開)
$ virsh resume web-server
Domain 'web-server' resumed

# VM の保存(メモリ状態をファイルに保存して停止)
$ virsh save web-server /var/lib/libvirt/save/web-server.save
Domain 'web-server' saved to /var/lib/libvirt/save/web-server.save

# VM の復元
$ virsh restore /var/lib/libvirt/save/web-server.save
Domain restored from /var/lib/libvirt/save/web-server.save

# VM の削除(定義の解除)
$ virsh undefine web-server
Domain 'web-server' has been undefined

# ストレージも含めて削除
$ virsh undefine web-server --remove-all-storage --nvram

# コンソール接続
$ virsh console web-server
Connected to domain 'web-server'
Escape character is ^] (Ctrl + ])

6.3 スナップショット管理

# スナップショットの作成
$ virsh snapshot-create-as web-server \
    --name "before-update" \
    --description "Snapshot before system update"
Domain snapshot before-update created

# スナップショット一覧
$ virsh snapshot-list web-server
 Name              Creation Time               State
-------------------------------------------------------
 before-update     2026-04-10 10:00:00 +0900   running
 initial-setup     2026-04-01 09:00:00 +0900   shutoff

# スナップショットの詳細
$ virsh snapshot-info web-server --snapshotname before-update
Name:           before-update
Domain:         web-server
Current:        yes
State:          running
Location:       internal
Parent:         initial-setup
Children:       0
Descendants:    0
Metadata:       yes

# スナップショットへの復元
$ virsh snapshot-revert web-server --snapshotname before-update
Domain snapshot before-update reverted

# スナップショットの削除
$ virsh snapshot-delete web-server --snapshotname before-update
Domain snapshot before-update deleted

6.4 ライブマイグレーション

# ライブマイグレーション(VM 稼働中に別ホストへ移行)
$ virsh migrate --live web-server \
    qemu+ssh://dest-host/system \
    --verbose --persistent --undefinesource
Migration: [100 %]

# ライブマイグレーション(共有ストレージなし - ディスクコピーあり)
$ virsh migrate --live --copy-storage-all web-server \
    qemu+ssh://dest-host/system \
    --verbose

# マイグレーション速度の設定
$ virsh migrate-setspeed web-server 1000    # MiB/s

# マイグレーションのモニタリング
$ virsh domjobinfo web-server
Job type:       Unbounded
Operation:      Outgoing migration
Time elapsed:   15,234 ms
Data processed: 2.048 GiB
Data remaining: 512.000 MiB
Data total:     8.000 GiB
Memory processed: 2.048 GiB
Memory remaining: 512.000 MiB
Memory total:   8.000 GiB

7. virt-install による VM 作成

7.1 基本的な VM 作成

# CentOS 9 VM の作成
$ virt-install \
    --name centos9-vm \
    --ram 4096 \
    --vcpus 2 \
    --disk path=/var/lib/libvirt/images/centos9-vm.qcow2,size=40,format=qcow2 \
    --os-variant centos-stream9 \
    --network network=default \
    --graphics vnc,listen=0.0.0.0 \
    --cdrom /var/lib/libvirt/images/CentOS-Stream-9-latest-x86_64-dvd1.iso \
    --boot uefi

# Ubuntu 24.04 VM の作成
$ virt-install \
    --name ubuntu2404-vm \
    --ram 4096 \
    --vcpus 2 \
    --disk path=/var/lib/libvirt/images/ubuntu2404-vm.qcow2,size=40,format=qcow2 \
    --os-variant ubuntu24.04 \
    --network network=default \
    --graphics spice \
    --cdrom /var/lib/libvirt/images/ubuntu-24.04-live-server-amd64.iso

# 利用可能な OS バリアントの確認
$ osinfo-query os | grep -i centos
 centos-stream9       | CentOS Stream 9                    | 9        | http://centos.org/centos-stream/9
$ osinfo-query os | grep -i ubuntu
 ubuntu24.04          | Ubuntu 24.04 LTS                   | 24.04    | http://ubuntu.com/ubuntu/24.04

7.2 高度な設定オプション

# PXE ブートによる VM 作成
$ virt-install \
    --name pxe-vm \
    --ram 4096 \
    --vcpus 4 \
    --disk path=/var/lib/libvirt/images/pxe-vm.qcow2,size=40,format=qcow2,bus=virtio \
    --network bridge=br0,model=virtio \
    --pxe \
    --boot network,hd \
    --os-variant centos-stream9

# Kickstart による自動インストール
$ virt-install \
    --name auto-vm \
    --ram 4096 \
    --vcpus 4 \
    --disk path=/var/lib/libvirt/images/auto-vm.qcow2,size=40 \
    --location http://mirror.centos.org/centos/9-stream/BaseOS/x86_64/os/ \
    --initrd-inject /path/to/ks.cfg \
    --extra-args "inst.ks=file:/ks.cfg console=ttyS0,115200n8" \
    --os-variant centos-stream9 \
    --graphics none \
    --console pty,target_type=serial

# 既存ディスクからのインポート
$ virt-install \
    --name imported-vm \
    --ram 4096 \
    --vcpus 2 \
    --disk /var/lib/libvirt/images/existing-disk.qcow2 \
    --import \
    --os-variant centos-stream9 \
    --network network=default

# CPU とメモリの詳細設定
$ virt-install \
    --name optimized-vm \
    --ram 8192 \
    --vcpus 4,maxvcpus=8,sockets=1,cores=4,threads=1 \
    --cpu host-passthrough,cache.mode=passthrough \
    --memorybacking hugepages=yes \
    --disk path=/var/lib/libvirt/images/optimized-vm.qcow2,size=100,format=qcow2,bus=virtio,cache=writeback,io=threads \
    --network bridge=br0,model=virtio \
    --os-variant centos-stream9 \
    --cdrom /path/to/iso

8. virt-manager GUI

virt-manager は libvirt のグラフィカルフロントエンドであり、VM の作成・管理・コンソールアクセスを GUI で行える。

# virt-manager の起動
$ virt-manager

# リモートホストへの接続
$ virt-manager -c qemu+ssh://user@remote-host/system

# SSH X11 フォワーディングでリモートから使用
$ ssh -X user@remote-host virt-manager

virt-manager の主要機能:

  • VM の作成ウィザード
  • VM コンソール(VNC/SPICE)
  • ハードウェア構成の変更
  • ストレージプール管理
  • ネットワーク管理
  • スナップショット管理
  • パフォーマンスグラフ(CPU、メモリ、ディスク I/O、ネットワーク)

9. VM 設定(XML ドメイン定義)

9.1 XML 構造の概要

<domain type='kvm'>
  <name>web-server</name>
  <uuid>a1b2c3d4-e5f6-7890-abcd-ef1234567890</uuid>
  <metadata>
    <description>Production web server</description>
  </metadata>
  <memory unit='GiB'>8</memory>
  <currentMemory unit='GiB'>8</currentMemory>
  <vcpu placement='static'>4</vcpu>
  <os>
    <type arch='x86_64' machine='pc-q35-8.2'>hvm</type>
    <boot dev='hd'/>
    <boot dev='cdrom'/>
  </os>
  <features>
    <acpi/>
    <apic/>
  </features>
  <cpu mode='host-passthrough' check='none' migratable='on'>
    <topology sockets='1' dies='1' cores='4' threads='1'/>
  </cpu>
  <clock offset='utc'>
    <timer name='rtc' tickpolicy='catchup'/>
    <timer name='pit' tickpolicy='delay'/>
    <timer name='hpet' present='no'/>
  </clock>
  <on_poweroff>destroy</on_poweroff>
  <on_reboot>restart</on_reboot>
  <on_crash>destroy</on_crash>
  <devices>
    <!-- ディスク -->
    <disk type='file' device='disk'>
      <driver name='qemu' type='qcow2' cache='writeback' io='threads' discard='unmap'/>
      <source file='/var/lib/libvirt/images/web-server.qcow2'/>
      <target dev='vda' bus='virtio'/>
    </disk>
    <!-- ネットワーク -->
    <interface type='bridge'>
      <mac address='52:54:00:ab:cd:ef'/>
      <source bridge='br0'/>
      <model type='virtio'/>
    </interface>
    <!-- VNC コンソール -->
    <graphics type='vnc' port='-1' autoport='yes' listen='0.0.0.0'>
      <listen type='address' address='0.0.0.0'/>
    </graphics>
    <!-- シリアルコンソール -->
    <serial type='pty'>
      <target port='0'/>
    </serial>
    <console type='pty'>
      <target type='serial' port='0'/>
    </console>
    <!-- QEMU Guest Agent -->
    <channel type='unix'>
      <target type='virtio' name='org.qemu.guest_agent.0'/>
    </channel>
  </devices>
</domain>

9.2 主要な設定セクション

CPU 設定:

<!-- ホスト CPU のパススルー(最高性能) -->
<cpu mode='host-passthrough' check='none' migratable='on'/>

<!-- ホストモデルの使用(マイグレーション互換性重視) -->
<cpu mode='host-model' check='partial'/>

<!-- 特定の CPU モデルを指定 -->
<cpu mode='custom' match='exact' check='partial'>
  <model fallback='allow'>Skylake-Server-IBRS</model>
  <feature policy='require' name='vmx'/>
</cpu>

<!-- CPU ピンニング -->
<vcpu placement='static'>4</vcpu>
<cputune>
  <vcpupin vcpu='0' cpuset='2'/>
  <vcpupin vcpu='1' cpuset='3'/>
  <vcpupin vcpu='2' cpuset='4'/>
  <vcpupin vcpu='3' cpuset='5'/>
  <emulatorpin cpuset='0-1'/>
</cputune>

メモリ設定:

<!-- 基本的なメモリ設定 -->
<memory unit='GiB'>8</memory>
<currentMemory unit='GiB'>8</currentMemory>

<!-- Hugepages の使用 -->
<memoryBacking>
  <hugepages>
    <page size='2048' unit='KiB'/>
  </hugepages>
  <nosharepages/>
  <locked/>
</memoryBacking>

<!-- NUMA 設定 -->
<numatune>
  <memory mode='strict' nodeset='0'/>
</numatune>

9.3 XML の編集と適用

# 現在の XML を表示
$ virsh dumpxml web-server > web-server.xml

# XML を直接編集
$ virsh edit web-server
# エディタが開き、保存すると自動的に適用される

# XML ファイルから VM を定義
$ virsh define web-server.xml
Domain 'web-server' defined from web-server.xml

# XML ファイルから VM を作成して起動
$ virsh create web-server.xml
Domain 'web-server' created from web-server.xml

# 動的にデバイスを追加
$ virsh attach-disk web-server \
    /var/lib/libvirt/images/data-disk.qcow2 \
    vdb --driver qemu --subdriver qcow2 --persistent

# 動的にデバイスを削除
$ virsh detach-disk web-server vdb --persistent

# ネットワークインターフェースの追加
$ virsh attach-interface web-server \
    --type bridge --source br0 --model virtio --persistent

10. ストレージ管理

10.1 ディスクイメージ形式

形式特徴用途
qcow2Copy-on-Write、スナップショット対応、圧縮可能、スパースファイル一般的な用途(推奨)
raw最高の I/O 性能、シンプル高性能要求の環境
vmdkVMware 互換VMware からの移行
vdiVirtualBox 互換VirtualBox からの移行
vpc/vhdHyper-V 互換Microsoft 環境との互換
# qcow2 イメージの作成
$ qemu-img create -f qcow2 disk.qcow2 40G
Formatting 'disk.qcow2', fmt=qcow2 cluster_size=65536 extended_l2=off compression_type=zlib size=42949672960

# qcow2 イメージの情報確認
$ qemu-img info disk.qcow2
image: disk.qcow2
file format: qcow2
virtual size: 40 GiB (42949672960 bytes)
disk size: 196 KiB
cluster_size: 65536
Format specific information:
    compat: 1.1
    compression type: zlib
    lazy refcounts: false

# raw イメージの作成
$ qemu-img create -f raw disk.raw 40G

# 形式変換(qcow2 → raw)
$ qemu-img convert -f qcow2 -O raw disk.qcow2 disk.raw

# 形式変換(raw → qcow2、圧縮付き)
$ qemu-img convert -f raw -O qcow2 -c disk.raw disk.qcow2

# イメージのリサイズ
$ qemu-img resize disk.qcow2 +20G
Image resized.

# スナップショット一覧
$ qemu-img snapshot -l disk.qcow2

10.2 ストレージプール

# ストレージプールの一覧
$ virsh pool-list --all
 Name       State    Autostart
---------------------------------
 default    active   yes
 images     active   yes
 iso        active   yes

# デフォルトプールの情報
$ virsh pool-info default
Name:           default
UUID:           12345678-abcd-efgh-ijkl-123456789012
State:          running
Persistent:     yes
Autostart:      yes
Capacity:       500.00 GiB
Allocation:     120.50 GiB
Available:      379.50 GiB

# ディレクトリベースのストレージプール作成
$ virsh pool-define-as images dir \
    --target /var/lib/libvirt/images
Pool images defined

$ virsh pool-build images
Pool images built

$ virsh pool-start images
Pool images started

$ virsh pool-autostart images
Pool images marked as autostarted

# LVM ストレージプール作成
$ virsh pool-define-as lvm-pool logical \
    --source-name vg_vms \
    --target /dev/vg_vms
Pool lvm-pool defined

# NFS ストレージプール作成
$ virsh pool-define-as nfs-pool netfs \
    --source-host nfs-server.example.com \
    --source-path /exports/vms \
    --target /var/lib/libvirt/nfs-pool

# iSCSI ストレージプール
$ virsh pool-define-as iscsi-pool iscsi \
    --source-host iscsi-server.example.com \
    --source-dev iqn.2026-04.com.example:storage \
    --target /dev/disk/by-path

# ストレージプールの削除
$ virsh pool-destroy images
$ virsh pool-undefine images

10.3 ストレージボリューム

# ボリューム一覧
$ virsh vol-list default
 Name                Path
-----------------------------------------------------------
 web-server.qcow2    /var/lib/libvirt/images/web-server.qcow2
 db-server.qcow2     /var/lib/libvirt/images/db-server.qcow2

# ボリュームの作成
$ virsh vol-create-as default new-disk.qcow2 40G --format qcow2
Vol new-disk.qcow2 created

# ボリュームの情報
$ virsh vol-info /var/lib/libvirt/images/web-server.qcow2
Name:           web-server.qcow2
Type:           file
Capacity:       40.00 GiB
Allocation:     12.50 GiB

# ボリュームのクローン
$ virsh vol-clone web-server.qcow2 web-server-clone.qcow2 --pool default

# ボリュームの削除
$ virsh vol-delete web-server.qcow2 --pool default

# ボリュームのリサイズ
$ virsh vol-resize web-server.qcow2 60G --pool default

11. ネットワーク設定

11.1 NAT ネットワーク

libvirt のデフォルトネットワークは NAT モードで構成される。

# ネットワーク一覧
$ virsh net-list --all
 Name      State    Autostart   Persistent
---------------------------------------------
 default   active   yes         yes

# デフォルトネットワークの情報
$ virsh net-dumpxml default
<network>
  <name>default</name>
  <uuid>12345678-1234-1234-1234-123456789012</uuid>
  <forward mode='nat'>
    <nat>
      <port start='1024' end='65535'/>
    </nat>
  </forward>
  <bridge name='virbr0' stp='on' delay='0'/>
  <mac address='52:54:00:00:00:01'/>
  <ip address='192.168.122.1' netmask='255.255.255.0'>
    <dhcp>
      <range start='192.168.122.2' end='192.168.122.254'/>
    </dhcp>
  </ip>
</network>

# カスタム NAT ネットワークの作成
$ cat > /tmp/isolated-net.xml << 'EOF'
<network>
  <name>isolated</name>
  <forward mode='nat'/>
  <bridge name='virbr1' stp='on' delay='0'/>
  <ip address='10.10.10.1' netmask='255.255.255.0'>
    <dhcp>
      <range start='10.10.10.100' end='10.10.10.200'/>
      <host mac='52:54:00:aa:bb:cc' name='web-vm' ip='10.10.10.10'/>
    </dhcp>
  </ip>
</network>
EOF

$ virsh net-define /tmp/isolated-net.xml
$ virsh net-start isolated
$ virsh net-autostart isolated

11.2 ブリッジネットワーク

VM が物理ネットワークに直接接続するブリッジ構成は、本番環境で最も一般的である。

# NetworkManager を使用したブリッジ作成(RHEL 9 推奨)
$ sudo nmcli connection add type bridge ifname br0 con-name br0
$ sudo nmcli connection modify br0 ipv4.addresses '192.168.1.100/24'
$ sudo nmcli connection modify br0 ipv4.gateway '192.168.1.1'
$ sudo nmcli connection modify br0 ipv4.dns '192.168.1.1'
$ sudo nmcli connection modify br0 ipv4.method manual

# 物理 NIC をブリッジに追加
$ sudo nmcli connection add type bridge-slave ifname eth0 master br0
$ sudo nmcli connection up br0

# ブリッジの確認
$ bridge link show
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 master br0 state forwarding
$ ip addr show br0
3: br0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500
    inet 192.168.1.100/24 brd 192.168.1.255 scope global br0

# ブリッジネットワークを libvirt に定義
$ cat > /tmp/bridge-net.xml << 'EOF'
<network>
  <name>host-bridge</name>
  <forward mode='bridge'/>
  <bridge name='br0'/>
</network>
EOF

$ virsh net-define /tmp/bridge-net.xml
$ virsh net-start host-bridge
$ virsh net-autostart host-bridge

11.3 macvtap

macvtap は物理 NIC に直接仮想インターフェースを作成し、ブリッジを必要としない。

<!-- macvtap の設定(VM XML) -->
<interface type='direct'>
  <mac address='52:54:00:11:22:33'/>
  <source dev='eth0' mode='bridge'/>
  <model type='virtio'/>
</interface>

macvtap のモード:

モード説明
bridgeVM 間通信とホスト外部通信が可能(最も一般的)
vepa外部スイッチ経由で VM 間通信(Hairpin 転送)
privateVM 間通信を禁止
passthrough物理 NIC を単一 VM に専有

11.4 Open vSwitch

# Open vSwitch のインストール
$ sudo dnf install openvswitch
$ sudo systemctl enable --now openvswitch

# OVS ブリッジの作成
$ sudo ovs-vsctl add-br ovsbr0
$ sudo ovs-vsctl add-port ovsbr0 eth0

# libvirt ネットワーク定義
$ cat > /tmp/ovs-net.xml << 'EOF'
<network>
  <name>ovs-network</name>
  <forward mode='bridge'/>
  <bridge name='ovsbr0'/>
  <virtualport type='openvswitch'/>
</network>
EOF

12. CPU/メモリピンニングと NUMA

12.1 CPU ピンニング

# ホストの CPU トポロジー確認
$ lscpu
Architecture:          x86_64
CPU(s):                32
Thread(s) per core:    2
Core(s) per socket:    8
Socket(s):             2
NUMA node(s):          2
NUMA node0 CPU(s):     0-7,16-23
NUMA node1 CPU(s):     8-15,24-31

# CPU ピンニングの設定
$ virsh vcpupin web-server 0 2
$ virsh vcpupin web-server 1 3
$ virsh vcpupin web-server 2 4
$ virsh vcpupin web-server 3 5

# 現在のピンニング状態の確認
$ virsh vcpupin web-server
 VCPU   CPU Affinity
-----------------------
 0      2
 1      3
 2      4
 3      5

# エミュレータスレッドのピンニング
$ virsh emulatorpin web-server 0-1

12.2 NUMA アウェアネス

<!-- NUMA トポロジーの指定 -->
<cpu>
  <topology sockets='1' dies='1' cores='4' threads='1'/>
  <numa>
    <cell id='0' cpus='0-3' memory='4' unit='GiB'/>
  </numa>
</cpu>

<!-- NUMA チューニング -->
<numatune>
  <memory mode='strict' nodeset='0'/>
  <memnode cellid='0' mode='strict' nodeset='0'/>
</numatune>
# ホストの NUMA 情報確認
$ numactl --hardware
available: 2 nodes (0-1)
node 0 cpus: 0 1 2 3 4 5 6 7 16 17 18 19 20 21 22 23
node 0 size: 65536 MB
node 0 free: 32000 MB
node 1 cpus: 8 9 10 11 12 13 14 15 24 25 26 27 28 29 30 31
node 1 size: 65536 MB
node 1 free: 48000 MB

# VM の NUMA 配置状況
$ virsh numatune web-server
numa_mode      : strict
numa_nodeset   : 0

12.3 メモリ設定

<!-- メモリバルーニング(動的メモリ調整) -->
<memory unit='GiB'>8</memory>
<currentMemory unit='GiB'>4</currentMemory>
<devices>
  <memballoon model='virtio'>
    <stats period='10'/>
  </memballoon>
</devices>
# メモリの動的変更
$ virsh setmem web-server 6G

# Hugepages の設定(ホスト側)
$ echo 1024 > /proc/sys/vm/nr_hugepages
# 永続化
$ echo "vm.nr_hugepages = 1024" >> /etc/sysctl.conf

# Hugepages の確認
$ cat /proc/meminfo | grep Huge
AnonHugePages:         0 kB
ShmemHugePages:        0 kB
FileHugePages:         0 kB
HugePages_Total:    1024
HugePages_Free:      512
HugePages_Rsvd:        0
HugePages_Surp:        0
Hugepagesize:       2048 kB

13. スナップショットとクローニング

13.1 スナップショットの種類

種類説明対応形式
内部スナップショットディスクイメージ内に保存qcow2 のみ
外部スナップショット別ファイルとして作成任意の形式
メモリ付きスナップショットメモリ状態も保存稼働中の VM
ディスクのみスナップショットディスク状態のみ停止中の VM
# 内部スナップショットの作成
$ virsh snapshot-create-as web-server \
    --name "snap-$(date +%Y%m%d)" \
    --description "Daily snapshot"

# 外部スナップショットの作成
$ virsh snapshot-create-as web-server \
    --name "external-snap" \
    --disk-only \
    --diskspec vda,file=/var/lib/libvirt/images/web-server-snap.qcow2

# スナップショットツリーの表示
$ virsh snapshot-list web-server --tree
initial-setup
  |
  +- before-update
  |   |
  |   +- after-update
  |
  +- test-config

13.2 クローニング

# VM のクローン作成
$ virt-clone \
    --original web-server \
    --name web-server-clone \
    --file /var/lib/libvirt/images/web-server-clone.qcow2
Allocating 'web-server-clone.qcow2'  |  40 GB  00:00:30
Clone 'web-server-clone' created successfully.

# virt-sysprep によるクローンのカスタマイズ(ホスト固有情報の削除)
$ virt-sysprep -d web-server-clone \
    --hostname new-hostname \
    --operations defaults,-ssh-userdir

# virt-sysprep で実行される操作の一覧
$ virt-sysprep --list-operations
bash-history          Remove bash history
crash-data            Remove crash data
hostname              Change hostname
logfiles              Remove log files
machine-id            Remove machine-id
net-hostname          Remove hostname in network config
net-hwaddr            Remove MAC address
package-manager-cache Remove package manager cache
ssh-hostkeys          Remove SSH host keys
ssh-userdir           Remove SSH user directories
tmp-files             Remove temporary files
udev-persistent-net   Remove udev persistent net rules

14. cloud-init 統合

cloud-init を使用すると、VM の初期設定を自動化できる。

# cloud-init 用のメタデータとユーザーデータを作成
$ mkdir -p /tmp/cloud-init

$ cat > /tmp/cloud-init/meta-data << 'EOF'
instance-id: web-server-001
local-hostname: web-server
EOF

$ cat > /tmp/cloud-init/user-data << 'EOF'
#cloud-config
hostname: web-server
fqdn: web-server.example.com
manage_etc_hosts: true

users:
  - name: admin
    sudo: ALL=(ALL) NOPASSWD:ALL
    groups: wheel, adm
    shell: /bin/bash
    ssh_authorized_keys:
      - ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQ... admin@workstation

packages:
  - nginx
  - vim
  - htop
  - git

runcmd:
  - systemctl enable --now nginx
  - firewall-cmd --permanent --add-service=http
  - firewall-cmd --reload

write_files:
  - path: /etc/nginx/conf.d/default.conf
    content: |
      server {
          listen 80;
          server_name _;
          root /var/www/html;
      }

timezone: Asia/Tokyo

power_state:
  mode: reboot
  message: "Rebooting after cloud-init"
  timeout: 30
  condition: true
EOF

# cloud-init ISO の作成
$ genisoimage -output /var/lib/libvirt/images/cloud-init.iso \
    -volid cidata -joliet -rock \
    /tmp/cloud-init/meta-data \
    /tmp/cloud-init/user-data

# cloud-init 対応 VM の作成
$ virt-install \
    --name web-server \
    --ram 4096 \
    --vcpus 2 \
    --disk /var/lib/libvirt/images/CentOS-Stream-GenericCloud-9-latest.x86_64.qcow2 \
    --disk /var/lib/libvirt/images/cloud-init.iso,device=cdrom \
    --import \
    --os-variant centos-stream9 \
    --network network=default \
    --graphics none \
    --noautoconsole

15. パフォーマンス最適化

virtio ドライバの使用

# ディスク: virtio-blk or virtio-scsi
# ネットワーク: virtio-net
# メモリバルーン: virtio-balloon

# virt-install での virtio 指定
$ virt-install \
    --disk path=/path/to/disk.qcow2,bus=virtio \
    --network network=default,model=virtio

ディスク I/O の最適化

設定説明推奨値
cacheキャッシュモードwriteback (性能重視) / none (安全性重視)
ioI/O モードthreads (推奨) / native
discardTRIM/Discardunmap (SSD 環境で推奨)
formatディスク形式qcow2 (柔軟性) / raw (最高性能)
<disk type='file' device='disk'>
  <driver name='qemu' type='qcow2' cache='writeback' io='threads' discard='unmap'/>
  <source file='/var/lib/libvirt/images/vm.qcow2'/>
  <target dev='vda' bus='virtio'/>
</disk>

ネットワークの最適化

<!-- vhost-net の有効化 -->
<interface type='bridge'>
  <source bridge='br0'/>
  <model type='virtio'/>
  <driver name='vhost' queues='4'/>
</interface>

CPU の最適化

# CPU ホストパススルー(最高性能、マイグレーション制限あり)
$ virt-install --cpu host-passthrough

# I/O スレッドの設定
$ virsh iothreadadd web-server 1
$ virsh iothreadpin web-server 1 0-1

チューニングのまとめ

<domain type='kvm'>
  <!-- CPU: ホストパススルー + ピンニング -->
  <cpu mode='host-passthrough'>
    <topology sockets='1' cores='4' threads='1'/>
  </cpu>
  <cputune>
    <vcpupin vcpu='0' cpuset='4'/>
    <vcpupin vcpu='1' cpuset='5'/>
    <vcpupin vcpu='2' cpuset='6'/>
    <vcpupin vcpu='3' cpuset='7'/>
    <emulatorpin cpuset='0-1'/>
  </cputune>

  <!-- メモリ: Hugepages + NUMA -->
  <memoryBacking>
    <hugepages/>
    <nosharepages/>
    <locked/>
  </memoryBacking>
  <numatune>
    <memory mode='strict' nodeset='0'/>
  </numatune>

  <!-- I/O スレッド -->
  <iothreads>2</iothreads>
  <iothreadids>
    <iothread id='1'/>
    <iothread id='2'/>
  </iothreadids>

  <devices>
    <!-- ディスク: virtio + writeback + io threads -->
    <disk type='file' device='disk'>
      <driver name='qemu' type='qcow2' cache='writeback' io='threads' discard='unmap' iothread='1'/>
      <source file='/var/lib/libvirt/images/vm.qcow2'/>
      <target dev='vda' bus='virtio'/>
    </disk>

    <!-- ネットワーク: virtio + vhost + multiqueue -->
    <interface type='bridge'>
      <source bridge='br0'/>
      <model type='virtio'/>
      <driver name='vhost' queues='4'/>
    </interface>
  </devices>
</domain>

16. トラブルシューティング

VM が起動しない

# libvirt ログの確認
$ sudo journalctl -u libvirtd -n 50
$ sudo cat /var/log/libvirt/qemu/web-server.log

# QEMU プロセスの確認
$ ps aux | grep qemu

# KVM モジュールの確認
$ lsmod | grep kvm

# SELinux の問題
$ sudo ausearch -m avc --start today | grep -i qemu
$ sudo setsebool -P virt_use_nfs on    # NFS ストレージ使用時

# AppArmor の問題 (Ubuntu)
$ sudo aa-status | grep libvirt

ネットワークの問題

# 仮想ネットワークの状態確認
$ virsh net-list --all
$ ip link show virbr0
$ iptables -t nat -L -n | grep virbr0

# ブリッジの状態確認
$ bridge link show
$ brctl show

# VM のネットワーク設定確認
$ virsh domiflist web-server
$ virsh domifstat web-server vnet0

ストレージの問題

# ディスクイメージの整合性チェック
$ qemu-img check /var/lib/libvirt/images/vm.qcow2
No errors were found on the image.

# ディスク使用率の確認
$ qemu-img info /var/lib/libvirt/images/vm.qcow2
$ df -h /var/lib/libvirt/images/

# ストレージプールのリフレッシュ
$ virsh pool-refresh default

パフォーマンスの問題

# VM の CPU 使用率
$ virsh cpu-stats web-server
Total:
  cpu_time         1234567890000 ns
  user_time         987654321000 ns
  system_time       246913569000 ns

# VM のブロック I/O 統計
$ virsh domblkstat web-server vda
rd_req 1234567
rd_bytes 12345678901
wr_req 234567
wr_bytes 2345678901

# VM のネットワーク統計
$ virsh domifstat web-server vnet0
vnet0 rx_bytes 1234567890
vnet0 rx_packets 1234567
vnet0 tx_bytes 987654321
vnet0 tx_packets 987654

# virt-top によるリアルタイム監視
$ virt-top

17. ベストプラクティス

  1. virtio ドライバを常に使用する - ディスクとネットワークの両方で virtio を使用し、最適な性能を確保する
  2. CPU ピンニングを検討する - 性能が重要な VM では CPU ピンニングと NUMA アウェアネスを設定する
  3. Hugepages を活用する - メモリ集約型ワークロードでは 2MB/1GB Hugepages を使用する
  4. スナップショットを定期的に取得する - 変更前のスナップショットは必須。ただし長期保持はパフォーマンスに影響する
  5. qcow2 形式を標準とする - スナップショット、圧縮、シンプロビジョニングの利点を活かす
  6. ブリッジネットワークを本番環境で使用する - NAT は開発・テスト環境にのみ使用する
  7. QEMU Guest Agent をインストールする - ゲスト内でのファイルシステムフリーズやネットワーク情報取得に必要
  8. cloud-init で初期設定を自動化する - 手動設定を排除し、再現性を確保する
  9. セキュリティを考慮する - SELinux/AppArmor の sVirt 機能を活用し、VM 間の分離を強化する
  10. 定期的なバックアップを実施する - VM の XML 定義とディスクイメージの両方をバックアップする

18. 参考文献


本ドキュメントは 2026年4月時点の情報に基づいています。最新の情報は各ソフトウェアの公式ドキュメントを参照してください。