それマグで!

知識はカップより、マグでゆっくり頂きます。 takuya_1stのブログ

習慣に早くから配慮した者は、 おそらく人生の実りも大きい。

Raspberry Pi4 にKVM+qemu で仮想マシンの仮想環境を作る/raspi+kvm

Raspberry Pi4 にKVM+qemu仮想マシンの実行環境を作る

Raspberry Pi4 もメモリが8GBもあれば、仮想マシンを動かすのに十分な性能があると思うんですね。

仮想マシンを動かしたらいろいろ便利そうなので、仮想マシンを動かすことにした

SDカードにOSを準備

KVMが有効な仮想マシンを動かすために、通常のRaspbianではちょっと厳しい。

Raspbian はKVMのサポートが無効化された32bit版が配布されている。動くには動くだろうが、KVMのサポートは欲しい。

そこで、KVMサポートがされたOSをインストールする。

選択肢はこの通りになる。

  • Raspbian 64bit
  • Ubuntu for raspi arm64 server
  • Arch とか

raspbianの64bit版は、KVMが有効化された状態でコンパイルされているので、Raspbianなら64bit版を使う。

わたしは、初回インストールの手間を考えて、ubuntuにした。

ubuntu には、arm4でraspiようにビルドされたイメージが配布されているので楽そうだった。

ubuntuの場合は、次のイメージを探してきて、SDカードに書き込む

ubuntu-20.04.2-preinstalled-server-arm64+raspi.img

初回起動後

初回起動したら、そのままSDカード容量に合わせて、ext4がリサイズされる。

初回アップデートも初回起動時に行われる。

ssh など必要な初回インストール作業が少なくて済むのがubuntu-server版の魅力

いつもの通り、piユーザーの代わりになる、自分のユーザーを作り、piユーザーはログインを無効化しておく。

ubuntu版の場合は、piユーザーではなく id/pw=ubuntu/ubuntu がプリインされている。

ユーザー作成

sudo adduser takuya
sudo usermod -aG ubuntu takuya
sudo usermod -aG adm takuya
sudo usermod -aG dialout takuya
sudo usermod -aG cdrom takuya
sudo usermod -aG floppy takuya
sudo usermod -aG sudo takuya
sudo usermod -aG audio takuya
sudo usermod -aG dip takuya
sudo usermod -aG video takuya
sudo usermod -aG plugdev takuya
sudo usermod -aG netdev takuya
sudo usermod -aG lxd takuya

ssh 設定

PasswordAuthentication no
Match User ubuntu Address 192.168.100.0/24
  PasswordAuthentication yes

カーネル確認

ubuntu で raspi4 にインストールしたら、この表記になった。

takuya@ubuntu:~$ uname -a
Linux ubuntu 5.4.0-1030-raspi #33-Ubuntu SMP PREEMPT Wed Feb 24 11:20:11 UTC 2021 aarch64 aarch64 aarch64 GNU/Linux

apt 設定

インストールを最小限にしておく。

echo -e  "APT::Install-Suggests 0;\nAPT::Install-Recommends 0;" | sudo tee /etc/apt/apt.conf.d/00-no-install-recommends

apt ミラーサーバー設定(わからない

apt ミラー設定は、ミラーサーバーの設定がわからない・・・ちょっと特殊なバイナリ( arm64 )なのであとに回す

たとえばJAISTミラーには、ARM64がない。arm/arm64バイナリはミラー郡の提供に含まれないっぽい。

ちょっと特殊みたいなので、いつものUbuntuミラーサーバーは使えないっぽい。

gihyo の ubuntu weekly recipe (柴田充也氏)の記事によると。

ちなみにarm64やarmhfなどamd64以外のアーキテクチャーパッケージについては,ports.ubuntu.comで提供されています。こちについては「公式のミラーサーバー」は用意されていないため,Raspberry Piなどでは原則として「ports.ubuntu.com」を指定することになります。 https://gihyo.jp/admin/serial/01/ubuntu-recipe/0677?page=2

ということです。

apt の更新

sudo apt update && sudo apt upgrade -y

タイムゾーンの設定

sudo timedatectl set-timezone Asia/Tokyo

ロケール設定

sudo apt-get install language-pack-ja
sudo update-locale LANG=ja_JP.UTF-8
sudo locale-gen
sudo locale -a

または

sudo dpkg-reconfigure locales

GUIでやるなら後者が確実。

http://www.dreamedge.net/archives/111

LXD 最初から入ってる。つおい

ちなみに、ubuntuだと、Snapcraftの snapd がLXDで最初から導入されているので、qemu/libvirtを使わなくても仮想マシン(コンテナ)を手軽に作れる。

わざわざqemukvmを動かさなくても、殆どの場合LXC/lxd で十分な気もする。

takuya@ubuntu:~$ sudo snap list
Name    Version   Rev    Tracking       Publisher   Notes
core18  20210128  1990   latest/stable  canonical✓  base
lxd     4.0.4     19040  4.0/stable/…   canonical✓  -
snapd   2.49      11115  latest/stable  canonical✓  snapd

kvm qemulibvirt で仮想環境を作る

kvm が使えるかどうか、念のためにチェック

sudo apt install cpu-checker

KVM が使える!。raspberry Pi4 でもKVMが使えます。

takuya@ubuntu:~$ sudo kvm-ok
INFO: /dev/kvm exists
KVM acceleration can be used

kvm qemu 一式をインストールする

kvmqemulibvirt 経由で使うために、つぎをインストール。

sudo apt -y install qemu-kvm libvirt-daemon-system \
libvirt-daemon virtinst bridge-utils libguestfs-tools virt-top

uefi をインストール

qemu-efi がないと動かない。(aarch64用)

sudo apt install qemu-efi

virtio で ネットワークを扱う。

インストールしてないと、failed to find romfile "efi-virtio.rom" になり、ネットワークを扱えない仮想マシンになった。

sudo apt install ipxe-qemu

virbr0 を使う。

libvirtd が提供する virbr0 を使うために、dnsmasq が必要だった。インストールが必要だった。

sudo apt install dnsmasq

virt/kvm グループに参加

自分のユーザーで、system virshを使いたいのでグループに参加しておく。ユーザーセッションでもいいんだけど、qemu://system も使えたほうが楽だし。

sudo usermod -aG libvirt takuya
sudo usermod -aG libvirt-qemu takuya
sudo usermod -aG kvm takuya

qemu仮想マシンを起動(openwrt)

とりあえず、OpenWRTでも動かしてみようか。

openwrt には、arm64の仮想マシンで動かすための armvirt/64bit のバイナリが配布されていて、起動方法も公式Wikiに記載されていたのでこれを起動しようと思う。

openwrtの公式→ https://openwrt.org/docs/guide-user/virtualization/qemu#openwrt_in_qemu_aarch64

イメージをダウンロード → https://downloads.openwrt.org/releases/19.07.6/targets/armvirt/64/

ダウンロードしたら、ext4squashfs は qcow2 に変えておく qemu-img convert -f raw $in -O qcow2 $out

とりあえず、起動してみる。

KERNEL_IMAGE=/var/lib/libvirt/images/openwrt-19.07.7-armvirt-64-Image
INITRAMFS=/var/lib/libvirt/images/openwrt-19.07.7-armvirt-64-Image-initramfs
DISK=/var/lib/libvirt/images/openwrt-19.07.7-armvirt-64-root.squashfs.qcow2
sudo qemu-system-aarch64 --enable-kvm -m 1024 -smp 2 -cpu host -M virt -nographic \
  -kernel $INITRAMFS \
  -drive if=none,file=$DISK,id=hd0 \
  -device virtio-blk-device,drive=hd0 \

OpenWRTがちゃんと起動する。

qemuの起動方法をよく知らないので、マニュアルが助かった。

virt-install仮想マシンを作成

qemukvm 仮想マシン起動ができたので、同じように、virt-install から libvirt経由で使える仮想マシンとしてインストールしてみる。

ネットワークはとりあえず、br0 を作ってそれを使うことに。

br0を作成

sudo brctl addbr br0
sudo brctl addif br0 eth1
sudo ip link set br0 up

eth1 を使ってるのは SSH接続が切れないように。USB-LANをRaspiに挿してeth1として使ってる。SSH経由で作業するeth0 (メイン・オンボード)をbr0に入れるとSSH経由で完結しなくなる面倒が起きる。それを避けるために eth1を使った。

virt-install仮想マシン作成。(openwrt)

KERNEL_IMAGE=/var/lib/libvirt/images/openwrt-19.07.7-armvirt-64-Image
INITRAMFS=/var/lib/libvirt/images/openwrt-19.07.7-armvirt-64-Image-initramfs
DISK=/var/lib/libvirt/images/openwrt-19.07.7-armvirt-64-root.ext4.qcow2

sudo virt-install   \
  --connect qemu:///system \
  --name=wrt01  \
  --disk path=$DISK,format=qcow,device=disk,bus=virtio  \
  --ram=512 \
  --arch=aarch64 \
  --cpu host-passthrough \
  --virt-type kvm \
  --graphics none \
  --network bridge=br0,model=virtio \
  --boot kernel=$KERNEL_IMAGE,initrd=$INITRAMFS,kernel_args='root=fe00' \
  --import \
  --features acpi=off \
 

acpiをOFFにしないとエラーなる。仕方ないこととはいえ、ちょっとめんどくさい。

acpiが使えないので、virsh から shutdown が使えない。デメリットである。終了はdestroyをする必要がある。

ただ、macvtap などネットワークの管理がvirt-managerに任せられるのでメリットである。

ubuntu仮想マシンを起動。

qemuubuntu 仮想マシンを起動しよう。とおもったんだけど、LXCあるから別にいらないのでパス。

raspbian の仮想マシンを起動

Raspbianがちゃんと動かせたら、RaspiAP のプロジェクトRaspberry Pi - Wifi Routerのプロジェクトの成果物を仮想マシンで動かせるじゃん。

って思ったんだけど、よく考えたら、仮想マシンWifi渡せないしRaspApプロジェクト動かせないんだよね。。どうせWifiバイスをUSBパススルーは地獄なんだし。OpenWRTが仮想マシンで動いてたら、スマホから扱えるルーターにはなるわけだし。

とりあえずraspbian を このraspi ubuntu で起動しよう。とおもったんだけど、よく考えたら、raspiのarmのあれこれだとか吸収しても、ちょっと風変わりなDebianになるだけなので、労苦の割に使いにくいものにしかならない。Debian欲しいならLXDで素のDebian起動したらいいじゃないかと思ったのでパス。

adguard home

Raspiにadguard homeとか入れたら面白そうだと思ってて、仮想マシンでやろうと思ってたんだけど、UbuntuにしたのでLXD/Docker使えるので、これもVMじゃなくても良くなってしまった。

kvm+qemuな wrtから iperf3をやってみる。

仮想マシンで起動したwrt から

root@OpenWrt:~# iperf3 -c 192.168.100.1
(...
[ ID] Interval           Transfer     Bitrate         Retr
[  5]   0.00-10.00  sec  1.06 GBytes   912 Mbits/sec  352             sender
[  5]   0.00-10.05  sec  1.06 GBytes   905 Mbits/sec                  receiver
iperf Done.

ubuntuをインストールしたraspiから

takuya@ubuntu:~$ iperf3 -c 192.168.100.1
[ ID] Interval           Transfer     Bitrate         Retr
[  5]   0.00-10.00  sec  1.10 GBytes   941 Mbits/sec  119             sender
[  5]   0.00-10.01  sec  1.09 GBytes   937 Mbits/sec                  receiver

仮想マシン化による速度低下は気にならないレベルだった

まとめ raspi4で kvm + qemu 起動

8GBのメモリがあると快適に動く。

Ubuntuを使うと楽ちん。ubuntuのRaspi arm64 server版だと、最初からKVMが有効になってた。

らくにqemu と libvirtdで仮想マシンを扱えるのだけど、UbuntuだとSnapdとLXDがインストール済みで配布されているので。よくあるLinux仮想マシンを扱う場合ではdocker / lxd が使えるんでそんなにメリットはないかも。

WindowsのArmかOpenWrtくらいしか動かしてメリットあるものはないと思うんだ。仮想マシンでwrt動かせるから、Raspi4をルーターとして放置しつつ他の用途にも使えそうで熱い感じはある。自分で、arm64用になにかプログラミングするならとてもいいと思うんだけどね。

今回は、Ubuntuサーバー版をつかって仮想マシン作ったんだけど、GUIを扱うときにqemuでそこそこそ軽快に動かせるから管理は楽になるかもしれない。

純粋なサーバーとしてRaspiの4K2画面出せるグラフィック系の機能を殆ど使わないので、だいぶ勿体ない贅沢な使い方だとは思う。

参考

http://www.rcps.jp/doku.php?id=linux:kvm

https://www.kkaneko.jp/tools/container/ubuntu_qemu.html

https://kb.novaordis.com/index.php/Virt-install#Optional_Installation_Method_Option

https://dustymabe.com/2020/01/30/virt-install-boot-from-specific-kernel/initrd-just-for-install/

http://manpages.ubuntu.com/manpages/eoan/man1/virt-install.1.html

https://translatedcode.wordpress.com/2017/07/24/installing-debian-on-qemus-64-bit-arm-virt-board/

https://openwrt.org/docs/guide-user/virtualization/qemu#openwrt_in_qemu_aarch64

https://kitsunemimi.pw/notes/posts/running-windows-10-for-arm64-in-a-qemu-virtual-machine.html