Windows11 の WSL2 では Nested VM が有効になっています。これまで Windows版 qemu を使用してきましたが、ググって調べたときに出てくる qemu の記事は殆どが Linux 上の kvm を使用した物で、Windows版 qemu には適用できない事が多い状況でした。折角 WSL2 で使えるようになったようですので、Nested kvm で qemu 仮想マシンを起動できるか試してみました。また、whpx option 有効の Windows版 qemu 、Windows11 の Hyper-V や Virtualbox、実機で起動した Ubuntu やその上で起動した qemu についても速度を比較しました。
- はじめに
- WSL2 で Nested VM が有効かどうか確認
- WSL2 Ubuntu に qemu を install
- WSL2 qemu-kvm 起動確認
- WSL2 qemu-kvm に Debian11 を install
- Windows qemu-whpx に Debian11 を install
- Unix Bench
- まとめ
はじめに
Windows11 の WSL2 を徐々に使い始めています。仮想環境とは思えないほど反応が良く、WSLg で GUI も使えるようになり便利になりました。先ずは初期設定を済ませて、少しずつ出来る内容を確かめている段階です。
hiro20180901.hatenablog.com
このような中で気になったのが、Windows11 の WSL2 では Nested VM が有効になっている事です。qemu には Windows native 版がありますが、ググって調べたときに出てくる記事は Linux 版 kvm を使用した物が殆どであり、便利な機能があっても Windows版 qemu には適用できない事が多い状況でした。(例えば libvirtd や virt-manager、virsh等)
折角 WSL2 で Nested VM が使えるようになったので、Nested kvm で qemu 仮想マシンを起動させてみました。また、二重に仮想化された環境では速度が遅くなり実用的でない事もありえますので、以下に示す他の環境と Unix Bench で速度を比較してみました。
No. | Host | 仮想化 | OS | Core |
---|---|---|---|---|
1 | Windows11 | WSL2 | Ubuntu 20.04 LTS | 8c16t |
2 | Windows11 | WSL2 Nested qemu-kvm | Debian11 | 4c |
3 | Windows11 | qemu-whpx | Debian11 | 4c |
4 | Windows11 | qemu (whpxなし) | Debian11 | 4c |
5 | Windows11 | Hyper-V | Ubuntu 21.10 | 4c |
6 | Windows11 | Virtualbox | Ubuntu 21.10 | 4c |
7 | Ubuntu | なし | Ubuntu 21.10 | 8c16t |
8 | Ubuntu | qemu-kvm | Debian11 | 4c |
実機で起動した Ubuntu は、内蔵 128GB SSD に Hyper-V の Path through で install して、実機でも Hyper-V でも起動できるようにしているものです。Hyper-V の Path through による install 方法については下記の過去記事を参照ください。
WSL2 で Nested VM が有効かどうか確認
以下の記事では Windows10 insider program で対応、と書かれていますが、Windows11 では Nested VM が使用できるようです。
ascii.jp
$ ls -l /dev/kvm* crw------- 1 root root 10, 232 2月 12 20:19 /dev/kvm $ egrep -c '(vmx|svm)' /proc/cpuinfo 16 $ kvm-ok INFO: /dev/kvm exists KVM acceleration can be used
/proc/cpuinfo の flag に svm が CPU 8c16t の 16 threads 分ありましたので、WSL2 で Nested VM が有効になっています。また、cpu-checker
package 内の kvm-ok
command でも確認できます。
WSL2 Ubuntu に qemu を install
$ sudo apt install qemu-kvm $ dpkg -l | grep qemu ii ipxe-qemu 1.0.0+git-20190109.133f4c4-0ubuntu3.2 all PXE boot firmware - ROM images for qemu ii ipxe-qemu-256k-compat-efi-roms 1.0.0+git-20150424.a25a16d-0ubuntu4 all PXE boot firmware - Compat EFI ROM images for qemu ii qemu-block-extra:amd64 1:4.2-3ubuntu6.19 amd64 extra block backend modules for qemu-system and qemu-utils ii qemu-kvm 1:4.2-3ubuntu6.19 amd64 QEMU Full virtualization on x86 hardware ii qemu-system-common 1:4.2-3ubuntu6.19 amd64 QEMU full system emulation binaries (common files) ii qemu-system-data 1:4.2-3ubuntu6.19 all QEMU full system emulation (data files) ii qemu-system-gui:amd64 1:4.2-3ubuntu6.19 amd64 QEMU full system emulation binaries (user interface and audio support) ii qemu-system-x86 1:4.2-3ubuntu6.19 amd64 QEMU full system emulation binaries (x86) ii qemu-utils 1:4.2-3ubuntu6.19 $ dpkg -L qemu-system-x86 /. /usr /usr/bin /usr/bin/qemu-system-i386 /usr/bin/qemu-system-x86_64 /usr/share /usr/share/doc /usr/share/doc/qemu-system-x86 /usr/share/doc/qemu-system-x86/NEWS.Debian.gz /usr/share/doc/qemu-system-x86/README.Debian /usr/share/doc/qemu-system-x86/copyright /usr/share/man /usr/share/man/man1 /usr/share/man/man1/qemu-system-i386.1.gz /usr/share/man/man1/qemu-system-x86_64.1.gz /usr/share/doc/qemu-system-x86/changelog.Debian.gz /usr/share/doc/qemu-system-x86/common $ dpkg -L qemu-kvm /. /usr /usr/bin /usr/bin/kvm /usr/share /usr/share/doc /usr/share/doc/qemu-kvm /usr/share/doc/qemu-kvm/NEWS.Debian.gz /usr/share/doc/qemu-kvm/copyright /usr/share/man /usr/share/man/man1 /usr/share/man/man1/kvm.1.gz /usr/bin/kvm-spice /usr/bin/qemu-system-x86_64-spice /usr/share/doc/qemu-kvm/changelog.Debian.gz
kvm
command は qemu-system-x86_64 -enable-kvm
の wrapper です。
WSL2 qemu-kvm 起動確認
WSL2 qemu-kvm 起動 (失敗)
まずは command line で起動してみます。option は使用せず、起動できるかどうかの確認です。
$ kvm Could not access KVM kernel module: Permission denied qemu-system-x86_64: failed to initialize KVM: Permission denied
Permission denied で起動できません。
/dev/kvm の permission を適切に設定する
github に issue が出ていました。
github.com
/proc/config.gz
を見ると kvm 関連の module は kernel に組み込まれています。
WSL2 を起動した直後の状態で、/dev/kvm
は以下の owner と permission になっています。
$ ls -l /dev/kvm crw------- 1 root root 10, 232 2月 13 17:50 /dev/kvm
qemu-kvm
の deb-src を確認すると、qemu-4.2/debian/qemu-kvm-init
に以下の行があります。
…略… if systemd-detect-virt --quiet --container; then mknod /dev/kvm c 10 232 || true chown root:kvm /dev/kvm || true chmod g+rw /dev/kvm || true fi …略…
systemd-detect-virt --quiet --container
が有効の場合には chown root:kvm
と chmod g+rw
されているはずなので、本来は qemu-kvm
を install した段階で以下の owner と permission になっているはずです。
$ ls -l /dev/kvm crw-rw---- 1 root kvm 10, 232 2月 13 17:50 /dev/kvm
前記の issue によれば udev が起動していない為に、再起動しても owner と permission が維持されないようです。
回避策は /etc/wsl.conf
に以下の内容を追記します。
[boot] command = /bin/bash -c 'chown root:kvm /dev/kvm && chmod 660 /dev/kvm'
(上記 link 先は typo があるので注意) これで再起動しても /dev/kvm
の owner と permission が固定されます。
Windows11 の下記の version では /etc/wsl.conf
に対応しています。
Ubuntu bash :
$ cmd.exe /c "systeminfo" | grep "^OS Version" '\\wsl.localhost\Ubuntu\home\username' CMD.EXE was started with the above path as the current directory. UNC paths are not supported. Defaulting to Windows directory. OS Version: 10.0.22000 N/A Build 22000
WSL2 qemu-kvm に Debian11 を install
BIOS の起動まで確認できましたので、WSL2 qemu-kvm に Debian11 を install してみます。手順は以前に試した Windows版 qemu への install と同様です。
hiro20180901.hatenablog.com
仮想 HDD (qcow2) の作成
$ mkdir ~/qemu_hdd $ qemu-img create -f qcow2 ~/qemu_hdd/Debian11_UEFI.qcow2 32G
UEFI image の準備
UEFI で install します。UEFI image は ovmf
package に含まれています。
$ dpkg -l | grep ovmf ii ovmf 0~20191122.bd85bf54-2ubuntu3.3 all UEFI firmware for 64-bit x86 virtual machines $ dpkg -L ovmf /. /usr /usr/share /usr/share/OVMF /usr/share/OVMF/OVMF_CODE.fd /usr/share/OVMF/OVMF_CODE.secboot.fd /usr/share/OVMF/OVMF_VARS.fd /usr/share/OVMF/OVMF_VARS.ms.fd /usr/share/OVMF/OVMF_VARS.snakeoil.fd /usr/share/doc /usr/share/doc/ovmf /usr/share/doc/ovmf/README.Debian /usr/share/doc/ovmf/changelog.Debian.gz /usr/share/doc/ovmf/copyright /usr/share/ovmf /usr/share/ovmf/OVMF.fd /usr/share/ovmf/PkKek-1-snakeoil.key /usr/share/ovmf/PkKek-1-snakeoil.pem /usr/share/qemu /usr/share/qemu/firmware /usr/share/qemu/firmware/40-edk2-x86_64-secure-enrolled.json /usr/share/qemu/firmware/50-edk2-x86_64-secure.json /usr/share/qemu/firmware/60-edk2-x86_64.json /usr/share/OVMF/OVMF_CODE.ms.fd /usr/share/qemu/OVMF.fd
仮想 HDD と同じ folder に UEFI image を copy します。
$ cp /usr/share/OVMF/OVMF_VARS.fd ~/qemu_hdd
OVMF_CODE.fd
は書き換えしない部分なので copy しなくても良いです。
install 用 ISO image
Windows11 側にある ISO image を使用します。
その他の設定
- Virtio 使用 : Network 及び Block device
- display は gtk (標準)
- GPT 形式で仮想 HDD を format
install 用 script
CPU 4個、Memory 8GB で install しました。
$ kvm -m 8G -smp 4 \ -drive if=pflash,format=raw,readonly=on,file=/usr/share/OVMF/OVMF_CODE.fd \ -drive if=pflash,format=raw,file=OVMF_VARS.fd \ -drive file=Debian11_UEFI.qcow2,if=virtio \ -net nic,model=virtio -net user \ -cdrom /mnt/e/ISO/debian-11.2.0-amd64-netinst.iso -boot once=d -no-reboot
GPT 形式で install しました。
起動用 script
ISO image の行を削除すれば qcow2 仮想 HDD から起動します。
$ kvm -m 8G -smp 4 \ -drive if=pflash,format=raw,readonly=on,file=/usr/share/OVMF/OVMF_CODE.fd \ -drive if=pflash,format=raw,file=OVMF_VARS.fd \ -drive file=Debian11_UEFI.qcow2,if=virtio \ -net nic,model=virtio \ -net user
Windows qemu-whpx に Debian11 を install
WSL2 qemu-kvm と出来るだけ同じ条件となるように、Windows qemu-whpx でも Debian をinstall しました。過去の経験から、
- whpx 有効では UEFI では起動できなかった為、BIOS で install
- install 段階で whpx を有効にすると keyboard が効かないので、install 時には whpx 無効とし、実際の起動時には whpx を有効
- SPICE を使用すると freeze してしまう現象が出た為、gtk で表示
- 右 Shift が使用できないので左 Shift で代用しました。
install 用 script
WSL2 qemu-kvm と同様に CPU 4個、Menory 8GB で install しました。
cmd.exe :
> "C:\Program Files\qemu\qemu-system-x86_64.exe" ^ -m 8G -smp 4 ^ -drive file=Debian11_BIOS.qcow2,if=virtio ^ -net nic,model=virtio ^ -net user ^ -cdrom E:\ISO\debian-11.2.0-amd64-netinst.iso -boot once=d -no-reboot
cmd.exe で複数行を接続する場合には、行末に "^" を入れます。
起動用 script
whpx の行を追加し、cdrom 行を消去すれば起動用 script になります。
cmd.exe :
> "C:\Program Files\qemu\qemu-system-x86_64.exe" ^ -accel whpx ^ -m 8G -smp 4 ^ -drive file=Debian11_BIOS.qcow2,if=virtio ^ -net nic,model=virtio ^ -net user
Unix Bench
各仮想マシンの速度を比較するために Unix Bench を使用しました。
github.com
Unix Bench の環境構築と実行
環境構築は以下のページを参考にしました。
armadillo.atmark-techno.com
実行内容については以下のページが詳しいです。
blog.idcf.jp
git
と build-essential
を install し、git で byte-unixbench を clone してから Benchmark 実行用の script を起動します。
$ sudo apt install git build-essential $ git clone https://github.com/kdlucas/byte-unixbench.git $ cd byte-unixbench/UnixBench $ ./Run
CPU の速度とは関係なく、約1時間で Benchmark は終了します。
実行した結果は次のように表示されます。~/byte-unixbench/UnixBench/results
以下にも保存されています。
Unix Bench 結果 (WSL2 qemu-kvm) :
…省略… ------------------------------------------------------------------------ Benchmark Run: 月 2月 21 2022 11:29:54 - 11:57:51 4 CPUs in system; running 1 parallel copy of tests Dhrystone 2 using register variables 32287433.0 lps (10.0 s, 7 samples) Double-Precision Whetstone 6152.4 MWIPS (9.7 s, 7 samples) Execl Throughput 3856.4 lps (30.0 s, 2 samples) File Copy 1024 bufsize 2000 maxblocks 1272923.4 KBps (30.0 s, 2 samples) File Copy 256 bufsize 500 maxblocks 326251.0 KBps (30.0 s, 2 samples) File Copy 4096 bufsize 8000 maxblocks 2083261.4 KBps (30.0 s, 2 samples) Pipe Throughput 2162419.5 lps (10.0 s, 7 samples) Pipe-based Context Switching 100199.3 lps (10.0 s, 7 samples) Process Creation 6216.7 lps (30.0 s, 2 samples) Shell Scripts (1 concurrent) 8753.8 lpm (60.0 s, 2 samples) Shell Scripts (8 concurrent) 2012.4 lpm (60.0 s, 2 samples) System Call Overhead 2448122.4 lps (10.0 s, 7 samples) System Benchmarks Index Values BASELINE RESULT INDEX Dhrystone 2 using register variables 116700.0 32287433.0 2766.7 Double-Precision Whetstone 55.0 6152.4 1118.6 Execl Throughput 43.0 3856.4 896.8 File Copy 1024 bufsize 2000 maxblocks 3960.0 1272923.4 3214.5 File Copy 256 bufsize 500 maxblocks 1655.0 326251.0 1971.3 File Copy 4096 bufsize 8000 maxblocks 5800.0 2083261.4 3591.8 Pipe Throughput 12440.0 2162419.5 1738.3 Pipe-based Context Switching 4000.0 100199.3 250.5 Process Creation 126.0 6216.7 493.4 Shell Scripts (1 concurrent) 42.4 8753.8 2064.6 Shell Scripts (8 concurrent) 6.0 2012.4 3354.0 System Call Overhead 15000.0 2448122.4 1632.1 ======== System Benchmarks Index Score 1521.1 ------------------------------------------------------------------------ Benchmark Run: 月 2月 21 2022 11:57:51 - 12:25:58 4 CPUs in system; running 4 parallel copies of tests Dhrystone 2 using register variables 106672092.4 lps (10.0 s, 7 samples) Double-Precision Whetstone 20574.4 MWIPS (10.1 s, 7 samples) Execl Throughput 10409.3 lps (30.0 s, 2 samples) File Copy 1024 bufsize 2000 maxblocks 1180525.1 KBps (30.0 s, 2 samples) File Copy 256 bufsize 500 maxblocks 271859.1 KBps (30.0 s, 2 samples) File Copy 4096 bufsize 8000 maxblocks 2115232.4 KBps (30.0 s, 2 samples) Pipe Throughput 6840086.0 lps (10.0 s, 7 samples) Pipe-based Context Switching 551905.4 lps (10.0 s, 7 samples) Process Creation 29964.7 lps (30.0 s, 2 samples) Shell Scripts (1 concurrent) 15901.9 lpm (60.0 s, 2 samples) Shell Scripts (8 concurrent) 2532.8 lpm (60.1 s, 2 samples) System Call Overhead 6943611.5 lps (10.0 s, 7 samples) System Benchmarks Index Values BASELINE RESULT INDEX Dhrystone 2 using register variables 116700.0 106672092.4 9140.7 Double-Precision Whetstone 55.0 20574.4 3740.8 Execl Throughput 43.0 10409.3 2420.8 File Copy 1024 bufsize 2000 maxblocks 3960.0 1180525.1 2981.1 File Copy 256 bufsize 500 maxblocks 1655.0 271859.1 1642.7 File Copy 4096 bufsize 8000 maxblocks 5800.0 2115232.4 3647.0 Pipe Throughput 12440.0 6840086.0 5498.5 Pipe-based Context Switching 4000.0 551905.4 1379.8 Process Creation 126.0 29964.7 2378.2 Shell Scripts (1 concurrent) 42.4 15901.9 3750.4 Shell Scripts (8 concurrent) 6.0 2532.8 4221.3 System Call Overhead 15000.0 6943611.5 4629.1 ======== System Benchmarks Index Score 3343.9
前半が Sinble CPU の結果、後半が Multi CPU の結果です。それぞれの最後の行に System Benchmarks Index Score が表示されます。
比較した仮想マシン 一覧
比較した環境を再掲します。
No. | Host | 仮想化 | OS | Core |
---|---|---|---|---|
1 | Windows11 | WSL2 | Ubuntu 20.04 LTS | 8c16t |
2 | Windows11 | WSL2 Nested qemu-kvm | Debian11 | 4c |
3 | Windows11 | qemu-whpx | Debian11 | 4c |
4 | Windows11 | qemu (whpxなし) | Debian11 | 4c |
5 | Windows11 | Hyper-V | Ubuntu 21.10 | 4c |
6 | Windows11 | Virtualbox | Ubuntu 21.10 | 4c |
7 | Ubuntu | なし | Ubuntu 21.10 | 8c16t |
8 | Ubuntu | qemu-kvm | Debian11 | 4c |
以上、8つの環境で Unix Bench を実行しました。Multi の No.1 と 7 の結果は core 数が異なりますが、そのまま載せています。
Unix Bench 結果比較 グラフ
結果をグラフにしてみました。
Single 個別結果 :
Single Index Score 結果のみ :
Single core の結果から以下の事が分かりました。
- 速い順に (1) 実機 Ubuntu、(2) 実機 Ubuntu qemu-kvm、(3) Windows11 qemu-whpx、(4) Windows11 WSL2、でした。個別の結果で実機 Ubuntu と 実機 Ubuntu qemu-kvm の Disk の Read / Write の結果が伸びていないのは、Storage が SATA 接続の古い SSD の為です。他の Windows11 上の仮想マシンは全て NVMe M.2 SSD に仮想 HDD がありますので、幾分高めに出ていると思います。
- SATA SSD と NVMe M.2 SSD の違いはありますが、WSL2 はかなりよい結果でした。特に Shell Scripts (8 concurrent) の結果が実機 Ubuntu と遜色ない結果でしたので、WSL2 の軽量 Container と専用 kernel の tuning が Shell Script の実行に最適化されているのだと思います。
- WSL2 qemu-kvm は Nested kvm による落ち込みも思ったほどではありませんでした。Index Score でも Hyper-V より落ちますが Virtualbox よりも良い結果でした。
- qemu-whpx も WSL2 と遜色ない結果でした。Windows Hypervisor Platform を有効に使えているのだと思います。install 時に whpx option を有効で起動できない等、minor trouble が解消できれば良い選択肢になると思います。
- Hyper-V は qemu-whpx より遅いですが、WSL2 とは異なり完全な仮想環境ですので、その分遅くなっていると推測します。
- Hyper-V と比較して Virtualbox が考えていたより遅い結果でした。Windows Hypervisor Platform を使いこなせてないのでしょうか。WSL2 等を OFF にすれば改善されるのかは分かりません。
- 実機 Ubuntu 上の qemu-kvm は、Single core では実機とほぼ変わらない結果でした。
- 流石に Windows11 qemu (whpx option なし) はかなり遅い結果でした。準仮想化を使用できない場合には、実機 Ubuntu の 1/20 の速度しか出ません。ただし別CPU を emulate できるのは qemu 以外にありませんから、他の仮想マシンと並べて比較するのが間違っているのでしょう。
Multi 個別結果 :
Multi Index Score 結果のみ :
Multi core の結果から以下の事が分かりました。
- 速度順は、8c16t では (1) 実機 Ubuntu、(2) Windows11 WSL2、ですが横並び。4c では (1) Windows11 qemu-whpx、(2) 実機 Ubuntu qemu-kvm = Windows11 Hyper-V、(3) Windows11 Virtualbox、(4) Windows11 WSL2 qemu-kvm、(5) Windows11 qemu (whpx optionなし) の順でした。
- 実機 Ubuntu と実機 Ubuntu qemu-kvm の File Copy の結果が低めに出ていますので、仮想HDD の条件をそろえれば、両者の Score が伸びるはずです。
- Pipe Throughput と Shell Scripts の結果が実機 Ubuntu と Windows11 WSL2 でほぼ変わらないので、Multicore でも WSL2 の速さが目立ちます。やはり Shell 周りの最適化が WSL2 の強みなのでしょう。
- 4c 同士の比較では、Single core の時と同様に Windows11 qemu-whpx が最も速い結果でした。とはいえ、Hyper-V や Virtualbox との差は僅かであり、Windows11 WSL2 qemu-kvm も Windows11 Virtualbox の 70% 程度ですので、CPU個数を増やす事で実用できる範囲かと思います。
まとめ
WSL2 上の Nested kvm を使用して、qemu-kvm を起動してみました。systemd が起動していない事による WSL2 由来の不具合 (といっていいのかは微妙ですが) はありますが設定で回避できる内容でした。実機の Linux と変わらず qemu-kvm が起動できました。
WSL2 の Nested kvm ですので速度低下が心配でしたが、他の仮想環境と比較しても大きく低下する事はありませんでした。実際に Debian を使用していても、whpx option を使用しない Windows版 qemu とは比較にならない位の速さで、実用上は問題にならないと思います。
8種類の環境で Unix Bench の結果を比較しました。Ryzen 7 3800x の 8c16t を全て使用できる WSL2 と実機 Ubuntu の結果が良いのは当然ですが、実機 Ubuntu 上の qemu-kvm も single core では index の結果にほとんど差がない事からも、実機 Linux 上で qemu-kvm が広く使われている理由が分かります。
また、WSL2 Ubuntu の結果が実機 Ubuntu の結果に肉薄しているのは驚きでした。WSL2 は仮想化された環境なので実機 Ubuntu よりも遅い結果になると推測していましたが、実際にはほとんど変わらない結果でした。特に Shell script の結果が速く、WSL2 の使われ方を考えれば Microsoft が特に tuning に注力している部分なのでしょう。
思いのほか Virtualbox の結果が良くありませんでしたが、Windows Hypervisor Platform 有効の状態で起動しているので、能力を十分に発揮していない可能性もあります。とはいえ、私は Windows Hypervisor Platform 有効状態での Virtualbox の起動に拘りますので、最適化が進むことに期待します。
以上、Nested VM の WSL2 qemu-kvm の使い方と8種類の環境の Unix Bench の結果を比較しました。Unix Bench の結果を元にすれば、Windows11 上で使用するなら WSL2 を使うのが最適だと思います。どうしても完全な仮想環境を使用したい場合には qemu-whpx を、Windows11 の機能のみで手軽に使いたい場合には Hyper-V を、拘りがある場合には Virtualbox を、という使い分けになるでしょうか。
WSL2 の Nested VM を使用した qemu-kvm も、他の仮想環境より速度は落ちますが CPU や memory の割り当てを増やすことでカバーできますので、Linux 上の過去の知見が使用できるという点で有用な手段かと思います。また、Windows 版 qemu では gtk で表示される画面で右 Shift が使えませんでしが、WSL2 qemu-kvm では問題なく使用できていましたので、完成度は Linux 版 qemu の方が上かと思います。
なお、今回の結果は Gnome 環境まで全て install した上で Unix Bench を実行したものです。Unix Bench の実行には GUI は必須ではありませんし、GUI を起動するに伴って各種 daemon も起動しますので、CUI と比較して結果が低く出ているかも知れません。Unix Bench の graphic の結果についても興味がありますので、後日記事にするかも知れません (他にも試してたい事があるので後回しになりますが)。
参考になれば幸いです。