Raspberry Pi OS で KVM
環境について
64bit版のRaspberry Pi OS Lite(Debian12 Bookworm版)で、KVM のインストール、仮想マシンの作成をしてみます。
Raspberry Pi 4B 8GB版でテストしましたが、CPUの仮想化支援が効くので、低負荷で動作します。
$ cat /etc/os-release
PRETTY_NAME="Debian GNU/Linux 12 (bookworm)"
NAME="Debian GNU/Linux"
VERSION_ID="12"
VERSION="12 (bookworm)"
VERSION_CODENAME=bookworm
ID=debian
HOME_URL="https://www.debian.org/"
SUPPORT_URL="https://www.debian.org/support"
BUG_REPORT_URL="https://bugs.debian.org/"
$ cat /etc/debian_version
12.7
$ uname -a
Linux testpi 6.6.51+rpt-rpi-v8 #1 SMP PREEMPT Debian 1:6.6.51-1+rpt3 (2024-10-08) aarch64 GNU/Linux
NW設定
有線NICに仮想ブリッジを仕込み、KVMではブリッジを利用する想定。
以下のようなファイルをメディアに書き込んでOS起動する。
[connection]
id=br0
uuid=<UUID>
type=bridge
interface-name=br0
timestamp=1720959930
[ethernet]
[bridge]
stp=false
[ipv4]
address1=<IPアドレス>/24,<デフォルトGW>
dns=<プライマリDNSサーバ>;<セカンダリDNSサーバ>;
method=manual
route1=<宛先NWアドレス>/24,<GWアドレス>
[ipv6]
addr-gen-mode=default
method=auto
[proxy]
[connection]
id=bridge-slave-eth0
uuid=<UUID>
type=ethernet
interface-name=eth0
master=br0
slave-type=bridge
[ethernet]
[bridge-port]
作業用領域
ブートドライブの書き込み回数を減らしたいので、作業用領域は別のドライブに用意する。
$ dmesg | tail
$ sudo parted /dev/sda
> print
> rm 1
> mkpart primary 0% 100%
> print
> quit
$ sudo mkfs -t ext4 /dev/sda1
$ sudo mkdir /media/work
$ echo PARTUUID=$(ls -l /dev/disk/by-partuuid | grep sda1 | awk '{print $9}') /media/work ext4 defaults,noatime 0 1 | sudo tee -a /etc/fstab
PARTUUID=74e6849b-01 /media/work ext4 defaults,noatime 0 1
$ sudo mount /media/work
$ df
閑話休題
最初はUSBメモリを利用しようとしたのだが、I/Oの遅さのため断念。
10年以上前のSATAの2.5インチHDDを利用した。80GB。ケースに入れてUSB接続で利用できて便利。
関連パッケージのインストール
必要なパッケージをインストールします。
$ sudo apt install --no-install-recommends qemu-system-arm qemu-utils qemu-system-gui ipxe-qemu bridge-utils qemu-efi-aarch64 kpartx
仮想マシンの作成 Debian編
ここでは例として、Debian12 の仮想マシンを作成します。
https://www.debian.org/CD/netinst/ より、arm64 ネットインストール版CDイメージをダウンロードして利用します。(以下、debian-12.7.0-arm64-netinst.iso)
$ ls -l /media/work/iso/
-rw-r--r-- 1 pi pi 551858176 Nov 4 05:09 debian-12.7.0-arm64-netinst.iso
CDイメージからカーネルと初期化RAMディスクをコピー
インストールCDイメージから、カーネルと初期化RAMディスクをコピーします。
インストールメディアをマウント
$ sudo mkdir /media/iso
$ sudo mount /media/work/iso/debian-12.7.0-arm64-netinst.iso /media/iso
grub.cfg から、カーネルと初期化RAMディスクのパスを確認
$ egrep 'linux|initrd' /media/iso/boot/grub/grub.cfg | awk '{print $2}' | sort | uniq
/install.a64/gtk/initrd.gz
/install.a64/initrd.gz
/install.a64/vmlinuz
カーネルと初期化RAMディスクをコピー。コピーしたらアンマウント。
$ cd /media/work/iso/
$ cp -pi /media/iso/install.a64/vmlinuz debian-12.7.0-arm64-netinst.vmlinuz
$ cp -pi /media/iso/install.a64/initrd.gz debian-12.7.0-arm64-netinst.initrd.gz
$ ls -l /media/work/iso/
total 592188
-r--r--r-- 1 pi pi 21840895 Aug 31 19:41 debian-12.7.0-arm64-netinst.initrd.gz
-rw-r--r-- 1 pi pi 551858176 Nov 4 05:09 debian-12.7.0-arm64-netinst.iso
-r--r--r-- 1 pi pi 32692160 Aug 31 19:41 debian-12.7.0-arm64-netinst.vmlinuz
$ sudo umount /media/iso
仮想ディスクを作成
作業ディレクトリを作成
$ sudo mkdir /media/work/qemu
$ sudo chown pi: /media/work/qemu
$ cd /media/work/qemu/
$ qemu-img create -f qcow2 debian-12.7.0-arm64.qcow2.base 16G
Formatting 'debian-12.7.0-arm64.qcow2.base', fmt=qcow2 cluster_size=65536 extended_l2=off compression_type=zlib size=17179869184 lazy_refcounts=off refcount_bits=16
$ qemu-img info debian-12.7.0-arm64.qcow2.base
image: debian-12.7.0-arm64.qcow2.base
file format: qcow2
virtual size: 16 GiB (17179869184 bytes)
disk size: 196 KiB
cluster_size: 65536
Format specific information:
compat: 1.1
compression type: zlib
lazy refcounts: false
refcount bits: 16
corrupt: false
extended l2: false
$ ls -lhs debian-12.7.0-arm64.qcow2.base
196K -rw-r--r-- 1 pi pi 193K Nov 4 07:44 debian-12.7.0-arm64.qcow2.base
インストール
amd64のKVMでおなじみのパラメータの他に、カーネル、初期化RAMディスクを指定してインストーラを起動する。
$ sudo qemu-system-aarch64 \
-machine virt \
-cpu host \
-m 1024 \
-enable-kvm \
-kernel /media/work/iso/debian-12.7.0-arm64-netinst.vmlinuz \
-initrd /media/work/iso/debian-12.7.0-arm64-netinst.initrd.gz \
-cdrom /media/work/iso/debian-12.7.0-arm64-netinst.iso \
-drive file=debian-12.7.0-arm64.qcow2.base \
-net nic,macaddr=52:54:00:12:34:10 -net tap,ifname=tap1 -vnc 0.0.0.0:0
VNCビューアを実行して KVMホストの 5900ポートに接続する
QEMUコンソールが開いたら、Ctrl + Alt + 2 で画面をシリアルコンソールへ切り替える。
インストールは通常の手順で実行する。
インストール終了したら下記で仮想マシンを終了する。
- QEMUを実行したコマンドプロンプトに戻って、Ctrl + c で終了する。
- または、Ctrl + Alt + 1 で QEMUターミナルに戻り、q で終了する。
仮想ディスクからカーネルと初期化RAMディスクをコピー
仮想ディスクをマウント
$ sudo modprobe nbd
$ sudo qemu-nbd -c /dev/nbd0 debian-12.7.0-arm64.qcow2.base
$ sudo kpartx -av /dev/nbd0
add map nbd0p1 (254:0): 0 997376 linear 43:0 2048
add map nbd0p2 (254:1): 0 30597120 linear 43:0 999424
add map nbd0p3 (254:2): 0 1955840 linear 43:0 31596544
$ sudo mkdir /media/tmp
$ sudo mount /dev/mapper/nbd0p1 /media/tmp
$ df
カーネルと初期化RAMディスクをコピー
$ cp -pi /media/tmp/vmlinuz debian-12.7.0-arm64.vmlinuz
$ cp -pi /media/tmp/initrd.img debian-12.7.0-arm64.initrd.img
$ la -l
アンマウント
$ sudo umount /media/tmp
$ sudo kpartx -dv /dev/nbd0
$ sudo qemu-nbd -d /dev/nbd0
$ sudo rmmod nbd
オーバーレイストレージイメージ作成
インストール完了直後のイメージをバッキングファイルとして、オーバーレイストレージイメージ作成する。
(こうすることで、いつでもインストール直後のまっさらな状態に戻すことができる)
$ qemu-img create -f qcow2 -b debian-12.7.0-arm64.qcow2.base -F qcow2 debian-12.7.0-arm64.qcow2 16G
Formatting 'debian-12.7.0-arm64.qcow2', fmt=qcow2 cluster_size=65536 extended_l2=off compression_type=zlib size=17179869184 backing_file=debian-12.7.0-arm64.qcow2.base backing_fmt=qcow2 lazy_refcounts=off refcount_bits=16
$ qemu-img info debian-12.7.0-arm64.qcow2
image: debian-12.7.0-arm64.qcow2
file format: qcow2
virtual size: 16 GiB (17179869184 bytes)
disk size: 196 KiB
cluster_size: 65536
backing file: debian-12.7.0-arm64.qcow2.base
backing file format: qcow2
Format specific information:
compat: 1.1
compression type: zlib
lazy refcounts: false
refcount bits: 16
corrupt: false
extended l2: false
仮想マシン起動
コピーしたカーネル、初期化RAMディスクで仮想マシンを起動する。
$ sudo qemu-system-aarch64 \
-machine virt \
-cpu host \
-m 1024 \
-enable-kvm \
-kernel debian-12.7.0-arm64.vmlinuz \
-initrd debian-12.7.0-arm64.initrd.img \
-append root=/dev/vda2 \
-drive file=debian-12.7.0-arm64.qcow2 \
-net nic,macaddr=52:54:00:12:34:0 -net tap,ifname=tap1 \
-vnc 0.0.0.0:0 \
-daemonize
VNCビューアを実行して KVMホストの 5900ポートに接続する
QEMUコンソールが開いたら、Ctrl + Alt + 2 で画面をシリアルコンソールへ切り替える。
$ ip a
ipアドレスが付与されていることを確認する。
$ su -
$ apt install --no-install-recommends openssh-server
他のホストからssh 接続をテストする。
接続できたら、VNCビューアは閉じてよい。
仮想マシンの作成 RockyLinux編
https://rockylinux.org/download より、arm64 minimal CDイメージをダウンロードして利用します。(以下、Rocky-9.4-aarch64-minimal.iso)
$ ls -l Rocky-9.4-aarch64-minimal.iso
-rw-r--r-- 1 pi pi 1694892032 Nov 16 05:58 Rocky-9.4-aarch64-minimal.iso
先のDebianのイメージもそうだが、ダウンロードには torrent の利用をお勧めしたい。
aria2 などを利用すれば torrent ファイルのリンクを与えるだけで簡単にDLできる。サーバの負荷を減らし回線を効率よく利用することができる。
CDイメージからカーネルと初期化RAMディスクをコピー
インストールCDイメージから、カーネルと初期化RAMディスクをコピーするため、インストールメディアをマウント。
$ sudo mount Rocky-9.4-aarch64-minimal.iso /media/iso
mount: /media/tmp: WARNING: source write-protected, mounted read-only.
grub.cfg から、カーネルと初期化RAMディスクのパスを確認。
$ awk '$1~/linux|initrd/ {print $2}' /media/iso/EFI/BOOT/grub.cfg | sort | uniq
/images/pxeboot/initrd.img
/images/pxeboot/vmlinuz
カーネルと初期化RAMディスクをコピー。コピーしたらアンマウント。
$ cd /media/work/iso
$ cp /media/iso/images/pxeboot/initrd.img Rocky-9.4-aarch64-minimal.initrd.img
$ cp /media/iso/images/pxeboot/vmlinuz Rocky-9.4-aarch64-minimal.vmlinuz
$ ls -l Rocky-9.4-aarch64-minimal.*
-rw-r--r-- 1 pi pi 92786688 Nov 16 06:12 Rocky-9.4-aarch64-minimal.initrd.img
-rw-r--r-- 1 pi pi 1694892032 Nov 16 05:58 Rocky-9.4-aarch64-minimal.iso
-rwxr-xr-x 1 pi pi 11946497 Nov 16 06:12 Rocky-9.4-aarch64-minimal.vmlinuz
$ sudo umount /media/iso
仮想ディスクを作成
$ cd /media/work/qemu/
$ qemu-img create -f qcow2 Rocky-9.4-aarch64.qcow2.base 16G
Formatting 'Rocky-9.4-aarch64.qcow2.base', fmt=qcow2 cluster_size=65536 extended_l2=off compression_type=zlib size=17179869184 lazy_refcounts=off refcount_bits=16
$ qemu-img info Rocky-9.4-aarch64.qcow2.base
image: Rocky-9.4-aarch64.qcow2.base
file format: qcow2
virtual size: 16 GiB (17179869184 bytes)
disk size: 196 KiB
cluster_size: 65536
Format specific information:
compat: 1.1
compression type: zlib
lazy refcounts: false
refcount bits: 16
corrupt: false
extended l2: false
インストール
-bios
オプションが必要。
$ sudo qemu-system-aarch64 \
-machine virt \
-cpu host \
-m 1024 \
-enable-kvm \
-kernel /media/work/iso/Rocky-9.4-aarch64-minimal.vmlinuz \
-initrd /media/work/iso/Rocky-9.4-aarch64-minimal.initrd.img \
-append "inst.stage2=hd:LABEL=Rocky-9-4-aarch64-dvd ro" \
-cdrom /media/work/iso/Rocky-9.4-aarch64-minimal.iso \
-drive file=Rocky-9.4-aarch64.qcow2.base \
-net nic,macaddr=52:54:00:12:34:11 -net tap,ifname=tap1 -vnc 0.0.0.0:1 \
-bios /usr/share/qemu-efi-aarch64/QEMU_EFI.fd
起動したら、VNCビューアを実行して KVMホストの 5901ポートに接続する
QEMUコンソールが開いたら、Ctrl
+ Alt
+ 2
で画面をシリアルコンソールへ切り替える。
Xが起動しないメッセージが表示されるので、グラフィカルインストールのため、1 Start VNC
を選択。VNC パスワードを指定する。
表示されたアドレスに VNC 接続すると、通常のインストーラの画面が表示される。
インストールは通常の手順で実行する。
(作成したqcow2イメージからカーネル等をコピーする手間を考慮し、LVMは使わない。KVMホストで対応しているファイルシステムを指定する)
インストール終了したら下記で仮想マシンを終了する。
仮想ディスクからカーネルと初期化RAMディスクをコピー
仮想ディスクをマウントして、カーネルと初期化RAMディスクをコピー。
コピーーしたらアンマウント。
$ sudo modprobe nbd
$ sudo kpartx -av /dev/nbd0
$ sudo mount /dev/mapper/nbd0p2 /media/tmp
$ sudo cp /media/tmp/initramfs-5.14.0-427.13.1.el9_4.aarch64.img Rocky-9.4-aarch64.initramfs
$ sudo cp /media/tmp/vmlinuz-5.14.0-427.13.1.el9_4.aarch64 Rocky-9.4-aarch64.vmlinuz
$ sudo umount /media/tmp
$ sudo kpartx -dv /dev/nbd0
$ sudo qemu-nbd -d /dev/nbd0
$ sudo rmmod nbd
オーバーレイストレージイメージ作成
インストール完了直後のイメージをバッキングファイルとして、オーバーレイストレージイメージ作成する。
$ qemu-img create -f qcow2 -b Rocky-9.4-aarch64.qcow2.base -F qcow2 Rocky-9.4-aarch64.qcow2 16G
Formatting 'Rocky-9.4-aarch64.qcow2', fmt=qcow2 cluster_size=65536 extended_l2=off compression_type=zlib size=17179869184 backing_file=Rocky-9.4-aarch64.qcow2.base backing_fmt=qcow2 lazy_refcounts=off refcount_bits=16
$ qemu-img info Rocky-9.4-aarch64.qcow2
image: Rocky-9.4-aarch64.qcow2
file format: qcow2
virtual size: 16 GiB (17179869184 bytes)
disk size: 196 KiB
cluster_size: 65536
backing file: Rocky-9.4-aarch64.qcow2.base
backing file format: qcow2
Format specific information:
compat: 1.1
compression type: zlib
lazy refcounts: false
refcount bits: 16
corrupt: false
extended l2: false
仮想マシン起動
sudo qemu-system-aarch64 \
-machine virt \
-cpu host \
-m 1024 \
-enable-kvm \
-kernel Rocky-9.4-aarch64.vmlinuz \
-initrd Rocky-9.4-aarch64.initramfs \
-append "root=/dev/vda3" \
-drive file=Rocky-9.4-aarch64.qcow2 \
-net nic,macaddr=52:54:00:12:34:11 -net tap,ifname=tap1 \
-vnc 0.0.0.0:1 -daemonize
仮想マシンの作成 FreeBSD編
https://www.freebsd.org/where/ より aarch64 の Boot Only の iso イメージをダウンロードする
$ ls -l FreeBSD-14.1-RELEASE-arm64-aarch64-bootonly.iso
-rw-r--r-- 1 pi pi 373553152 Nov 16 07:56 FreeBSD-14.1-RELEASE-arm64-aarch64-bootonly.iso
インストール実行
仮想ディスク作成
$ qemu-img create -f qcow2 FreeBSD-14.1-RELEASE-arm64-aarch64.qcow2.base 16G
Formatting 'FreeBSD-14.1-RELEASE-arm64-aarch64.qcow2.base', fmt=qcow2 cluster_size=65536 extended_l2=off compression_type=zlib size=17179869184 lazy_refcounts=off refcount_bits=16
$ qemu-img info FreeBSD-14.1-RELEASE-arm64-aarch64.qcow2.base
image: FreeBSD-14.1-RELEASE-arm64-aarch64.qcow2.base
file format: qcow2
virtual size: 16 GiB (17179869184 bytes)
disk size: 196 KiB
cluster_size: 65536
Format specific information:
compat: 1.1
compression type: zlib
lazy refcounts: false
refcount bits: 16
corrupt: false
extended l2: false
インストーラを起動して、コマンドラインコンソールでインストールを実行する。
(カーネルや初期化RAMディスクの取り出しは不要で、ISOイメージから起動できる)
$ sudo qemu-system-aarch64 \
-machine virt \
-cpu host \
-enable-kvm \
-m 2048 \
-drive file=/media/work/iso/FreeBSD-14.1-RELEASE-arm64-aarch64-bootonly.iso,media=cdrom -boot c \
-device virtio-blk,drive=sda -drive id=sda,if=none,format=qcow2,file=FreeBSD-14.1-RELEASE-arm64-aarch64.qcow2.base \
-device virtio-net,netdev=net0,mac=52:54:00:12:34:12 -netdev tap,id=net0,script=/etc/qemu-ifup,downscript=/etc/qemu-ifdown,ifname=tap2 \
-bios /usr/share/qemu-efi-aarch64/QEMU_EFI.fd \
-vnc 0.0.0.0:2 -nographic
インストールができたらShellに落ちて shutdown -p now
で終了
オーバーレイストレージイメージ作成
インストール完了直後のイメージをバッキングファイルとして、オーバーレイストレージイメージ作成する。
$ qemu-img create -f qcow2 -b FreeBSD-14.1-RELEASE-arm64-aarch64.qcow2.base -F qcow2 FreeBSD-14.1-RELEASE-arm64-aarch64.qcow2 16G
Formatting 'FreeBSD-14.1-RELEASE-arm64-aarch64.qcow2', fmt=qcow2 cluster_size=65536 extended_l2=off compression_type=zlib size=17179869184 backing_file=FreeBSD-14.1-RELEASE-arm64-aarch64.qcow2.base backing_fmt=qcow2 lazy_refcounts=off refcount_bits=16
$ qemu-img info FreeBSD-14.1-RELEASE-arm64-aarch64.qcow2
image: FreeBSD-14.1-RELEASE-arm64-aarch64.qcow2
file format: qcow2
virtual size: 16 GiB (17179869184 bytes)
disk size: 196 KiB
cluster_size: 65536
backing file: FreeBSD-14.1-RELEASE-arm64-aarch64.qcow2.base
backing file format: qcow2
Format specific information:
compat: 1.1
compression type: zlib
lazy refcounts: false
refcount bits: 16
corrupt: false
extended l2: false
仮想マシン起動
カーネルや初期化RAMディスクの取り出しは不要で、仮想マシン起動できる
sudo qemu-system-aarch64 \
-machine virt \
-cpu host \
-enable-kvm \
-m 2048 \
-device virtio-blk,drive=sda -drive id=sda,if=none,format=qcow2,file=FreeBSD-14.1-RELEASE-arm64-aarch64.qcow2 \
-device virtio-net,netdev=net0,mac=52:54:00:12:34:12 -netdev tap,id=net0,script=/etc/qemu-ifup,downscript=/etc/qemu-ifdown,ifname=tap2 \
-bios /usr/share/qemu-efi-aarch64/QEMU_EFI.fd \
-vnc 0.0.0.0:2 -daemonize
Discussion