🧛

Raspberry Pi OS で libvirt(KVM)

2024/11/09に公開

環境

https://zenn.dev/mnod/articles/55c1f3b953d2ef の環境で、Libvirt を通じて、KVM の操作をしてみます。

インストール

追加で必要なパッケージをインストールします。

$ sudo apt install --no-install-recommends libvirt0 libvirt-daemon-system libvirt-clients virtinst

利用する環境のバージョン

$ virsh version
Compiled against library: libvirt 9.0.0
Using library: libvirt 9.0.0
Using API: QEMU 9.0.0
Running hypervisor: QEMU 7.2.13

$ sudo virsh uri
qemu:///system

ストレージプール

初期状態では存在しないので作成する。

$ sudo virsh pool-list --all
 Name   State   Autostart
---------------------------

$ sudo mkdir -p /media/work/libvirt/images
$ sudo virsh pool-define-as default dir --target /media/work/libvirt/images
Pool default defined

$ sudo virsh pool-list --all
 Name      State      Autostart
---------------------------------
 default   inactive   no

自動スタートの設定

$ sudo virsh pool-autostart default
Pool default marked as autostarted

$ sudo virsh pool-list --all
 Name      State    Autostart
-------------------------------
 default   active   yes

xmlの内容を確認

$ sudo virsh pool-dumpxml default
<pool type='dir'>
  <name>default</name>
  <uuid>540bfe27-9560-49cb-ba56-d65112a80937</uuid>
  <capacity unit='bytes'>78176350208</capacity>
  <allocation unit='bytes'>3104030720</allocation>
  <available unit='bytes'>75072319488</available>
  <source>
  </source>
  <target>
    <path>/media/work/libvirt/images</path>
    <permissions>
      <mode>0755</mode>
      <owner>0</owner>
      <group>0</group>
    </permissions>
  </target>
</pool>

仮想ネットワークの管理

初期状態で default が存在する

$ sudo virsh net-list --all
 Name      State      Autostart   Persistent
----------------------------------------------
 default   inactive   no          yes

$ sudo virsh net-dumpxml default
<network>
  <name>default</name>
  <uuid>762f2838-3f25-4ffc-8086-67031fb37a42</uuid>
  <forward mode='nat'/>
  <bridge name='virbr0' stp='on' delay='0'/>
  <mac address='52:54:00:6a:3c:7d'/>
  <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>

仮想ブリッジ br0 を利用したブリッジ接続をおこなうため、以下のファイルを作成

host-bridge.xml
<network>
  <name>host-bridge</name>
  <forward mode="bridge"/>
  <bridge name="br0"/>
</network>

作成したファイルを利用して仮想ネットワークを定義。起動と自動起動設定を行う。

$ sudo virsh net-define host-bridge.xml
Network host-bridge defined from host-bridge.xml

$ sudo virsh net-start host-bridge
Network host-bridge started

$ sudo virsh net-autostart host-bridge
Network host-bridge marked as autostarted

$ sudo virsh net-list --all
 Name          State      Autostart   Persistent
--------------------------------------------------
 default       inactive   no          yes
 host-bridge   active     yes         yes

xml の内容を確認

$ sudo virsh net-dumpxml host-bridge
<network>
  <name>host-bridge</name>
  <uuid>e71bf706-5c05-45ee-9917-0907d5a2bf5c</uuid>
  <forward mode='bridge'/>
  <bridge name='br0'/>
</network>

仮想マシンの作成 Debian編

ここでは例として、Debian12 の仮想マシンを作成します。

インストーラ実行

--boot オプションで、カーネル、初期化RAMディスク、カーネルオプションを指定する。
(カーネル、初期化RAMディスクは、インストールCDイメージからコピーしたものを利用)

$ sudo virt-install --virt-type kvm \
--features acpi=off \
--connect qemu:///system \
--name debian-12.7.0-arm64 \
--os-variant debian11 \
--memory 1024 \
--cdrom debian-12.7.0-arm64-netinst.iso \
--boot kernel=debian-12.7.0-arm64-netinst.vmlinuz,initrd=debian-12.7.0-arm64-netinst.initrd.gz,kernel_args='root=/dev/vda1' \
--disk size=16 \
--network network=host-bridge \
--graphics vnc,listen=0.0.0.0,port=5900

なんやかんややった後のストレージプールを覗いてみる

$ sudo virsh pool-list --all
 Name      State    Autostart
-------------------------------
 default   active   yes
 iso       active   yes

$ sudo virsh vol-list default
 Name                        Path
-----------------------------------------------------------------------------------
 debian-12.7.0-arm64.qcow2   /media/work/libvirt/images/debian-12.7.0-arm64.qcow2

$ sudo virsh vol-list iso
 Name                                    Path
------------------------------------------------------------------------------------------------
 debian-12.7.0-arm64-netinst.initrd.gz   /media/work/iso/debian-12.7.0-arm64-netinst.initrd.gz
 debian-12.7.0-arm64-netinst.iso         /media/work/iso/debian-12.7.0-arm64-netinst.iso
 debian-12.7.0-arm64-netinst.vmlinuz     /media/work/iso/debian-12.7.0-arm64-netinst.vmlinuz

ボリュームの確認

$ sudo virsh vol-info /media/work/libvirt/images/debian-12.7.0-arm64.qcow2
Name:           debian-12.7.0-arm64.qcow2
Type:           file
Capacity:       16.00 GiB
Allocation:     2.66 GiB

$ sudo virsh vol-dumpxml /media/work/libvirt/images/debian-12.7.0-arm64.qcow2
<volume type='file'>
  <name>debian-12.7.0-arm64.qcow2</name>
  <key>/media/work/libvirt/images/debian-12.7.0-arm64.qcow2</key>
  <capacity unit='bytes'>17179869184</capacity>
  <allocation unit='bytes'>2852315136</allocation>
  <physical unit='bytes'>17182752768</physical>
  <target>
    <path>/media/work/libvirt/images/debian-12.7.0-arm64.qcow2</path>
    <format type='qcow2'/>
    <permissions>
      <mode>0600</mode>
      <owner>64055</owner>
      <group>64055</group>
    </permissions>
    <timestamps>
      <atime>1730701453.996149827</atime>
      <mtime>1730702631.205532093</mtime>
      <ctime>1730702631.841526170</ctime>
      <btime>0</btime>
    </timestamps>
    <compat>1.1</compat>
    <features>
      <lazy_refcounts/>
    </features>
  </target>
</volume>

--features acpi=off を指定したので、shutdown が効かない。destroy で強制停止する。

$ sudo virsh list
 Id   Name                  State
-------------------------------------
 2    debian-12.7.0-arm64   running

$ sudo virsh destroy debian-12.7.0-arm64
Domain 'debian-12.7.0-arm64' destroyed

$ sudo virsh list --all
 Id   Name                  State
--------------------------------------
 -    debian-12.7.0-arm64   shut off

カーネルと初期化RAMディスクをコピー

qcow2イメージからカーネルと初期化RAMディスクをコピーする。

$ ls -l /media/work/libvirt/images/
total 2847196
-rw-r--r-- 1 root root    30520216 Nov  4 15:41 debian-12.7.0-arm64.initrd.img
-rw------- 1 root root 17182752768 Nov  4 16:05 debian-12.7.0-arm64.qcow2
-rw-r--r-- 1 root root    32692160 Oct  1 04:08 debian-12.7.0-arm64.vmlinuz

xml の書き換え

コピーしたカーネル、初期化RAMディスクを利用するようにxmlを書き換え。ついでにcd も外しておく。

$ sudo virsh dumpxml debian-12.7.0-arm64 | tee debian-12.7.0-arm64.xml

$ sudo EDITOR=/usr/bin/vim.tiny virsh edit debian-12.7.0-arm64
Domain 'debian-12.7.0-arm64' XML configuration edited.

$ sudo virsh dumpxml debian-12.7.0-arm64 | diff -u - debian-12.7.0-arm64.xml
--- -   2024-11-04 16:14:48.410993779 +0900
+++ debian-12.7.0-arm64.xml     2024-11-04 16:09:38.518176477 +0900
@@ -11,9 +11,9 @@
   <vcpu placement='static'>2</vcpu>
   <os>
     <type arch='aarch64' machine='virt-7.2'>hvm</type>
-    <kernel>/media/work/libvirt/images/debian-12.7.0-arm64.vmlinuz</kernel>
-    <initrd>/media/work/libvirt/images/debian-12.7.0-arm64.initrd.img</initrd>
-    <cmdline>root=/dev/vda2</cmdline>
+    <kernel>/media/work/iso/debian-12.7.0-arm64-netinst.vmlinuz</kernel>
+    <initrd>/media/work/iso/debian-12.7.0-arm64-netinst.initrd.gz</initrd>
+    <cmdline>root=/dev/vda1</cmdline>
     <boot dev='hd'/>
   </os>
   <features>
@@ -32,6 +32,12 @@
       <target dev='vda' bus='virtio'/>
       <address type='pci' domain='0x0000' bus='0x05' slot='0x00' function='0x0'/>
     </disk>
+    <disk type='file' device='cdrom'>
+      <driver name='qemu' type='raw'/>
+      <target dev='sda' bus='scsi'/>
+      <readonly/>
+      <address type='drive' controller='0' bus='0' target='0' unit='0'/>
+    </disk>
     <controller type='usb' index='0' model='qemu-xhci' ports='15'>
       <address type='pci' domain='0x0000' bus='0x02' slot='0x00' function='0x0'/>
     </controller>

仮想マシン起動

$ sudo virsh start debian-12.7.0-arm64
Domain 'debian-12.7.0-arm64' started

$ sudo virsh list --all
 Id   Name                  State
-------------------------------------
 1    debian-12.7.0-arm64   running

仮想マシンの作成 RockyLinux編

Rocky9.4 の例です。

インストーラ実行

$ sudo virt-install --virt-type kvm \
--features acpi=off \
--connect qemu:///system \
--name Rocky-9.4-aarch64 \
--os-variant rocky9 \
--memory 1024 \
--cdrom /media/work/libvirt/images/Rocky-9.4-aarch64-minimal.iso \
--boot kernel=/media/work/libvirt/images/Rocky-9.4-aarch64-minimal.vmlinuz,initrd=/media/work/libvirt/images/Rocky-9.4-aarch64-minimal.initrd.img,kernel_args='inst.stage2=hd:LABEL=Rocky-9-4-aarch64-dvd ro' \
--disk size=16 \
--network network=host-bridge \
--graphics vnc,listen=0.0.0.0,port=5901 \
--boot loader=/usr/share/qemu-efi-aarch64/QEMU_EFI.fd
$ sudo virsh list --all
 Id   Name                           State
-----------------------------------------------
 1    debian-12-genericcloud-arm64   running
 4    Rocky-9.4-aarch64              running
 -    debian-12.7.0-arm64            shut off



$ sudo virsh destroy Rocky-9.4-aarch64
Domain 'Rocky-9.4-aarch64' destroyed

カーネルと初期化RAMディスクをコピー

$ sudo modprobe nbd
$ sudo qemu-nbd -c /dev/nbd0 /media/work/libvirt/images/Rocky-9.4-aarch64.qcow2

$ sudo kpartx -av /dev/nbd0
$ sudo mount /dev/mapper/nbd0p4 /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

xml の書き換え

$ sudo virsh dumpxml Rocky-9.4-aarch64 >> ../Rocky-9.4-aarch64.xml

$ sudo EDITOR=/usr/bin/vim.tiny virsh edit Rocky-9.4-aarch64
Domain 'Rocky-9.4-aarch64' XML configuration edited.

$ sudo virsh dumpxml Rocky-9.4-aarch64 | diff -u - ../Rocky-9.4-aarch64.xml
--- -   2024-11-16 15:29:03.309081137 +0900
+++ ../Rocky-9.4-aarch64.xml    2024-11-16 15:24:10.689485698 +0900
@@ -12,9 +12,9 @@
   <os>
     <type arch='aarch64' machine='virt-7.2'>hvm</type>
     <loader type='rom'>/usr/share/qemu-efi-aarch64/QEMU_EFI.fd</loader>
-    <kernel>/media/work/libvirt/images/Rocky-9.4-aarch64.vmlinuz</kernel>
-    <initrd>/media/work/libvirt/images/Rocky-9.4-aarch64.initramfs</initrd>
-    <cmdline>root=/dev/vda2</cmdline>
+    <kernel>/media/work/libvirt/images/Rocky-9.4-aarch64-minimal.vmlinuz</kernel>
+    <initrd>/media/work/libvirt/images/Rocky-9.4-aarch64-minimal.initrd.img</initrd>
+    <cmdline>inst.stage2=hd:LABEL=Rocky-9-4-aarch64-dvd ro</cmdline>
     <boot dev='hd'/>
   </os>
   <features>
@@ -33,6 +33,12 @@
       <target dev='vda' bus='virtio'/>
       <address type='pci' domain='0x0000' bus='0x05' slot='0x00' function='0x0'/>
     </disk>
+    <disk type='file' device='cdrom'>
+      <driver name='qemu' type='raw'/>
+      <target dev='sda' bus='scsi'/>
+      <readonly/>
+      <address type='drive' controller='0' bus='0' target='0' unit='0'/>
+    </disk>
     <controller type='usb' index='0' model='qemu-xhci' ports='15'>
       <address type='pci' domain='0x0000' bus='0x02' slot='0x00' function='0x0'/>
     </controller>

仮想マシン起動

$ sudo virsh start Rocky-9.4-aarch64
Domain 'Rocky-9.4-aarch64' started

仮想マシンの作成 FreeBSD編

インストーラ実行

$ sudo virt-install --virt-type kvm \
--features acpi=off \
--connect qemu:///system \
--name FreeBSD-14.1 \
--os-variant freebsd13.1 \
--memory 1024 \
--cdrom /media/work/iso/FreeBSD-14.1-RELEASE-arm64-aarch64-bootonly.iso \
--disk size=16 \
--network network=host-bridge \
--graphics vnc,listen=0.0.0.0,port=5903 \
--boot loader=/usr/share/qemu-efi-aarch64/QEMU_EFI.fd

インストール終了後、インストーラのメニューで shutdown を選択しても (acpi=offなので) 電源は落ちない

仮想マシン起動

destroy した後、start する。

$ sudo virsh list
 Id   Name                           State
----------------------------------------------
 1    debian-12-genericcloud-arm64   running
 9    FreeBSD-14.1                   running

$ sudo virsh destroy FreeBSD-14.1
Domain 'FreeBSD-14.1' destroyed


$ sudo virsh start FreeBSD-14.1
Domain 'FreeBSD-14.1' started

GitHubで編集を提案

Discussion