コンテンツにスキップ

Linux + KVM で仮想化ホストを構築してみた(基本編)

古いPCをLinux+KVMで仮想化ホストとして再活用。GUIなし・SSH+virsh CLI前提で、KVM/libvirtのインストールからVM作成、管理、スナップショット、シリアル接続までの基本手順をまとめます。


自宅の片隅に眠っていた古いPCを活用しようと思い、LinuxをインストールしてKVM仮想化ホストとして使ってみました。

このPCには常設のモニターがないため、GUIは使わず、SSHによるリモート操作のみを想定しています。そのため、本記事では virsh のCLI を前提に記述しています。

インストール

事前チェック

まずcpu-checker パッケージをインストールして、KVMが動作可能かどうかを確認します。

1
2
3
4
$ sudo apt install cpu-checker
$ sudo kvm-ok
INFO: /dev/kvm exists
KVM acceleration can be used

KVM/QUEMのインストール

必要最小限のパッケージを入れるつもりだったので、こちらのコマンドを使用しました。

1
$ sudo apt install qemu-system-x86 libvirt-daemon-system

ネットでのいろんな記事に、以下のパッケージも必要と記載されていますが、私の場合自動的にインストールしてくれたので明示的に指定する必要はありませんでした。

  • libvirt-clientsは、libvirt-daemon-systemの依存関係にあるため、手動での指定は不要
  • qemu-utilsは、qemu-system-x86の依存関係にあるため、手動での指定は不要
  • ovmfは、qemu-system-x86のRecommendsに入っているため、手動での指定は不要

主なパッケージの用途はこちらです。

パッケージ 用途
qemu-system-x86 Hypervisor、つまり仮想化基盤ソフト
libvirt-daemon-system 仮想化環境を管理するデーモン
libvirt-clients virsh CLIを提供
qemu-utils QCOW2イメージの作成・管理
ovmf:UEFI対応 ゲストOSのUEFI対応

ツール類のインストール

必須ではないものの、効率的な仮想化環境管理に不可欠なツールを入れます。

1
$ sudo apt install virt-install
パッケージ 用途
virt-install virt-installなどの便利ツールを提供(より簡単に仮想マシンの作成が可能に)

virt-installが提供するコマンド

virt-installパッケージは、主に3つの便利なコマンドを提供しています。

  • virt-installコマンド:簡単に仮想マシンを作成するツール
  • virt-cloneコマンド:簡単に仮想マシンをクローンするツール
  • virt-xmlコマンド:簡単に仮想マシンのスペックを編集するツール

初期設定

バージョン確認

1
2
3
4
5
$ virsh version
Compiled against library: libvirt 11.3.0
Using library: libvirt 11.3.0
Using API: QEMU 11.3.0
Running hypervisor: QEMU 10.0.7

接続先URIの設定

libvirt には2種類の接続先があります。

URI 意味 用途
qemu:///system system libvirt daemon サーバ / 本番 / 管理用途
qemu:///session ユーザーごとのlibvirt デスクトップ / テスト

今回はサーバー仮想化(この物理マシンは仮想化ホスト専用)のため、デフォルトでqemu:///systemを使用するように設定します。

1
2
3
4
5
6
$ sudo usermod -aG libvirt,kvm <ユーザー名>
$ echo 'export LIBVIRT_DEFAULT_URI=qemu:///system' >> ~/.bashrc
$ source ~/.bashrc

$ virsh uri
qemu:///system

デフォルトNATの有効化

仮想ネットワークですが、最もシンプルな構成はNATです。NAT仮想ネットワークは、デフォルトで構成されているものの、自動起動(autostart)になっていないため、動いていない状態です。それを起動し、自動起動するように設定します。

1
2
3
4
$ virsh net-list --all
 Name      State      Autostart   Persistent
----------------------------------------------
 default   inactive   no          yes

一覧で確認したのち、IPレンジなどの詳細情報も確認してみます。

libvirt は基本的に すべてのリソースを XML 定義で管理しています。そのため、dumpxmlを使用して情報を確認します。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
 $ virsh net-dumpxml default
<network>
  <name>default</name>
  <uuid>63fe5243-718c-41b4-8ff2-1e9ce4450d32</uuid>
  <forward mode='nat'/>
  <bridge name='virbr0' stp='on' delay='0'/>
  <mac address='52:54:00:54:1f:ef'/>
  <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>

有効化&自動起動を設定します。

1
2
3
4
5
$ virsh net-start default
Network default started

$ virsh net-autostart default
Network default marked as autostarted

仮想マシンの管理

仮想マシンの作成

libvirt / KVM で 仮想マシンを作成する方法は大きく2つあります。

1つは、XML を直接定義する方法です。こちらはlibvirtの本来の方法で、XMLファイルを書いて、virsh defineコマンドで作成します。

もう1つはvirt-install を使う方法です。virt-installはlibvirtに含まれておらず、別途インストールする必要がありますが、CLIツールで XMLを自動生成してくれます。先ほどの手順でvirt-installをダウンロード済みなので、こちらの方法で進めます。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
$ virt-install \
    --name vm1 \
    --memory 4096 \
    --vcpus 2 \
    --disk size=20,format=qcow2 \
    --cdrom /var/lib/libvirt/images/debian/debian13.iso \
    --network network=default,model=virtio \
    --os-variant debian13 \
    --graphics vnc,keymap=ja,listen=0.0.0.0 \
    --noautoconsole

このように仮想マシンを作成します。OSインストール用のISOファイルは、事前にダウンロードしてどこかに格納しておく必要があります。

また、これによってVNCも設定される形になり、TigerVNCなどでリモートで接続してセットアップします。

VNCのキーマップ設定 keymap=ja

キーマップを正しく設定しないと、例えVNCのサーバー側とクライアント側が同じキーボード設定であっても、正しくマッピングできず、押されたキーと異なる文字が入力されてしまいます。

os-variantの確認

os-variantは、OSの種類を指定するパラメータです。使用できる値の一覧を確認するには、以下のコマンドを使用します:

1
2
3
4
5
6
7
$ virt-install --os-variant list
almalinux10
almalinux9
almalinux8
almalinux-kitten10
alpinelinux3.21
...

仮想マシンの接続

仮想マシンのOSインストール段階で、シリアルリダイレクトで接続することも可能ですが、多くのインストーラーが対応していないため、無理せずVNCで接続すると良いでしょう。

1
2
3
4
$ virsh list --all
 Id   Name       State
--------------------------
 2    vm1        running

念のためVNCの状況を確認します。

1
2
$ virsh vncdisplay vm1
:0

これでVNC接続が可能になります。

仮想マシンの起動、停止と削除

仮想マシンを電源レベルでシャットダウンするに、destroyを使用します。ここでは、仮想マシンのことが「domain」と呼ばれています。

1
2
$ virsh destroy vm1
Domain 'vm1' destroyed

再度起動するには、startを使用します。

1
2
$ virsh start vm1
Domain 'vm1' started

仮想マシンを削除するには、undefineを使用します。ただし、undefineだけでは仮想ディスクは削除されないので、手動で削除する必要があります。

1
2
3
4
$ virsh undefine vm1
Domain 'vm1' has been undefined

$ sudo rm /var/lib/libvirt/images/vm1.qcow2

仮想マシンの起動と停止

他には、reboot(OSレベル再起動)やreset(電源レベル再起動)、shutdown(OSレベルシャットダウン)、suspendresumeなどのvirshコマンドがあります。

仮想マシンの情報確認

仮想マシンの基本的な情報を確認します。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
$ virsh dominfo vm1
Id:             3
Name:           vm1
UUID:           35d60609-b649-4cff-baaa-35cdec0c333b
OS Type:        hvm
State:          running
CPU(s):         2
CPU time:       54.5s
Max memory:     4194304 KiB
Used memory:    4194304 KiB
Persistent:     yes
Autostart:      disable
Autostart Once: disable
Managed save:   no
Security model: apparmor
Security DOI:   0
Security label: libvirt-35d60609-b649-4cff-baaa-35cdec0c333b (enforcing)

仮想マシンの定義を確認したい場合、dumpxmlを使用します。

1
2
3
4
5
6
$ virsh dumpxml vm1
<domain type='kvm' id='13'>
  <name>vm1</name>
  <uuid>fd040a4b-a8f0-4595-97e6-be68bdbf086c</uuid>
  ...
</domain>

IPアドレスを確認します(特に、DHCPからIPアドレスを取得する場合は有用です)。

1
2
3
4
$ virsh domifaddr vm1
 Name       MAC address          Protocol     Address
-------------------------------------------------------------------------------
 vnet10     52:54:00:f5:5c:44    ipv4         192.168.122.49/24

ディスクを確認します。

1
2
3
4
5
$ virsh domblklist vm1
 Target   Source
--------------------------------------------------------
 hda      /var/lib/libvirt/images/vm1.qcow2
 hdb      /var/lib/libvirt/images/debian/debian13.iso

CD/フロッピードライブのメディア取り出し、交換

現在マウントしているISOを他のISOに変更します。

1
2
$ virsh change-media vm1 hdb /var/lib/libvirt/images/another/another.iso
Successfully updated media.

ISOを取り出します。

1
2
$ virsh change-media vm1 hdb --eject
Successfully ejected media.

スナップショット

スナップショットを作成します。

1
2
$ virsh snapshot-create-as vm1 clean-installation
Domain snapshot clean-installation created

snapshot-createsnapshot-create-as

snapshot-createはXML定義を渡して、スナップショットを作成するコマンドです。より高度なスナップショット作成が可能です。

snapshot-create-asは、コマンドラインから直接snapshotを作る簡易版です。

作成済みのスナップショットを確認します。

1
2
3
4
$ virsh snapshot-list vm1
 Name                 Creation Time               State
-----------------------------------------------------------
 clean-installation   2026-03-04 16:46:53 +0900   shutoff

スナップショットから復元します。

1
2
$ virsh snapshot-revert vm1 clean-installation
Domain snapshot clean-installation reverted

スナップショットを削除します(スナップの状態をマージします)。

1
2
3
4
5
6
$ virsh snapshot-delete vm1 clean-installation
Domain snapshot clean-installation deleted

$ virsh snapshot-list vm1
 Name   Creation Time   State
-------------------------------

仮想マシンのスペック変更/設定変更

仮想マシンの各種変更には、XMLを編集する必要があります。

最もシンプルな方法は、virsh editコマンドを使用する方法です。このコマンドを実行すると、viやnanoなどのエディタでXMLが開かれ、直接編集できるようになります。

1
$ virsh edit vm1

例えばメモリを2GBから4GBに変更するには、以下のようなセクションにある「2048」を「4096」に変更して、XMLを保存してから、仮想マシンを再起動すれば良いです。

1
2
3
4
<domain>
  <memory unit='MiB'>2048</memory>
  <vcpu>2</vcpu>
</domain>

しかし、XMLを直接編集することはリスクが高く、また自動化の難しい操作となります。そこで、virt-xmlコマンドを利用すると良いでしょう。例えば、メモリを4GBに変更するには、以下のコマンドを使用します。

1
virt-xml vm1 --edit --memory 4096

仮想マシンのクローン

仮想マシンをクローンするには、virt-cloneコマンドを使用します。

1
2
3
4
5
6
7
$ virsh shutdown vm1
Domain 'vm1' is being shutdown

$ virt-clone --original vm1 --name vm2 --auto-clone
Allocating 'vm2.qcow2'                                      |  20 GB  00:00:02

Clone 'vm2' created successfully.

シリアル接続(オプション)

ゲストOSへのアクセスは、Linuxであれば基本的にSSHを使用すべきですが、ネットワーク関連のトラブルでネットワークが繋がらない場合に備えて、予備としてシリアルアクセスを有効にしておくと良いでしょう。

もちろんその場合SVNCアクセスは利用可能ですが、VNCはセキュリティ上のリスクが高いとされているため、OSインストール後はOFFにしたほうが良いでしょう。

シリアル接続の有効化

ここでは、VNCもしくはSSHで、インストール済みのゲストOSにログインしていることを前提とします。

ゲストOSで、シリアル通信のサービスを有効化します。

1
2
sudo systemctl enable serial-getty@ttyS0.service
sudo systemctl start serial-getty@ttyS0.service

このサービスを有効にするだけで、シリアルでゲストOSに接続できますが、ブート時は画面表示もシリアルにリダイレクトする場合、さらに追加で以下のGRUB設定をします。

1
sudo vi /etc/default/grub

以下の内容を適用します。

1
2
3
GRUB_CMDLINE_LINUX="console=tty0 console=ttyS0,115200n8"
GRUB_TERMINAL="console serial"
GRUB_SERIAL_COMMAND="serial --speed=115200 --unit=0 --word=8 --parity=no --stop=1"

保存後、GRUBをアップデートします。

1
sudo update-grub

シリアルアクセス

ホストから、以下のコマンドでシリアルアクセスします。

1
2
3
$ virsh console vm1
Connected to domain 'vm1'
Escape character is ^] (Ctrl + ])

VNCの無効化

1
$ virt-xml vm1 --remove-device --graphics vnc

一度停止して、再度起動すると有効になります。