いまさら感はありますが、VitualBox で サポートされた Nested Virtualization を試してみました。
VirtualBox 6.0 で AMD CPU、VirtualBox 6.1 で Intel CPU での Nested Virtualization がサポートされました。
(VirtualBox 6.0.0)
(VirtualBox 6.1.0)
Nested Virtualization とは
Nested Virtualization とは、仮想マシンの中で Hypervisor を実行できる機能のことです。
簡単に言うと、仮想マシンの入れ子です。
以下のレイヤが連携して動きます。
- Level 0 layer (L0) : 実ハードウェア上で動作する Hypervisor
- Level 1 layer (L1) : L0上で仮想マシンとして動作する Hypervisor
- Level 2 layer (L2) : L1上で動作する仮想マシン
試してみる
今回使った環境は、以下の通りです。
VitualBox と Vagrant はインストール済みという前提です。
$ sw_vers
ProductName: Mac OS X
ProductVersion: 10.15.5
BuildVersion: 19F101
$ sysctl -a | grep brand_string
machdep.cpu.brand_string: Intel(R) Core(TM) i7-6567U CPU @ 3.30GHz
$ vboxmanage | head -n 1
Oracle VM VirtualBox Command Line Management Interface Version 6.1.10
$ vagrant version | head -n 1
Installed Version: 2.2.9
レイヤは以下のような感じです。
Vagrant + VirtualBox を使用して、L1 仮想マシンとなる CentOS 7.8.2003 (centos/7) をインストールします。
(L0)$ vagrant box add centos/7
(L0)$ vagrant init centos/7
Vagrantfile を編集して、L1 仮想マシンで CPU 仮想化支援機能が有効になるように設定します。
また、Nested Virtualization はオーバーヘッドが大きいので、普段 VirtualBox で仮想マシンを動かすよりもマシンリソースを多めにします。
config.vm.provider "virtualbox" do |vb|
vb.cpus = "2"
vb.memory = "2048"
vb.customize ["modifyvm", :id, "--nested-hw-virt", "on"]
end
仮想マシンを起動して、ssh ログインします。
(L0)$ vagrant up
(L0)$ vagrant ssh
CPU 仮想化支援機能フラグ (Intel CPU : vmx / AMD CPU : svm) が立っていることを確認します。
(L1)$ cat /etc/centos-release
CentOS Linux release 7.8.2003 (Core)
(L1)$ egrep '(vmx|svm)' /proc/cpuinfo
flags : fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov pat pse36 clflush mmx fxsr sse sse2 ht syscall nx rdtscp lm constant_tsc rep_good nopl xtopology nonstop_tsc eagerfpu pni pclmulqdq vmx ssse3 cx16 pcid sse4_1 sse4_2 x2apic movbe popcnt aes xsave avx rdrand hypervisor lahf_lm abm 3dnowprefetch invpcid_single tpr_shadow flexpriority fsgsbase avx2 invpcid rdseed clflushopt md_clear flush_l1d
flags : fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov pat pse36 clflush mmx fxsr sse sse2 ht syscall nx rdtscp lm constant_tsc rep_good nopl xtopology nonstop_tsc eagerfpu pni pclmulqdq vmx ssse3 cx16 pcid sse4_1 sse4_2 x2apic movbe popcnt aes xsave avx rdrand hypervisor lahf_lm abm 3dnowprefetch invpcid_single tpr_shadow flexpriority fsgsbase avx2 invpcid rdseed clflushopt md_clear flush_l1d
L1 仮想マシンに KVM 環境を構築して、L2 仮想マシンを起動します。
今回は、Vagrant + Libvirt を使用して、L2 仮想マシンとなる Debian 10.4 (debian/buster64) をインストールします。
まず、L1 仮想マシンに、KVM 関連パッケージと Vagrant をインストールします。
(L1)$ sudo yum install -y qemu-kvm libguestfs libvirt libvirt-client libvirt-devel virt-manager virt-top virt-viewer virt-who virt-install bridge-utils nfs-utils
(L1)$ sudo yum install -y https://releases.hashicorp.com/vagrant/2.2.9/vagrant_2.2.9_x86_64.rpm
libvirt グループに現在のユーザを追加します。
(L1)$ sudo gpasswd -a vagrant libvirt
Vagrant の provider として libvirt が使用できるように、vagrant-libvirt プラグインをインストールします。
(L1)$ vagrant plugin install vagrant-libvirt
L1 仮想マシンを再起動して、ssh ログインします。
(L0)$ vagrant reload
(L0)$ vagrant ssh
KVM に必要なカーネルモジュールが有効になっているか確認します。
(L1)$ lsmod | grep 'kvm'
kvm_intel 188688 0
kvm 636965 1 kvm_intel
irqbypass 13503 1 kvm
libvirt 用の box をダウンロードします。
(L1)$ vagrant box add --provider libvirt debian/buster64
(L1)$ vagrant box list
debian/buster64 (libvirt, 10.4.0)
L2 仮想マシンを起動して、ssh ログインします。
(L1)$ vagrant init debian/buster64
(L1)$ vagrant up --provider libvirt
(L1)$ vagrant ssh
L2 仮想マシンを確認します。
(L2)$ cat /etc/debian_version
10.4
(L2)$ uname -a
Linux buster 4.19.0-9-amd64 #1 SMP Debian 4.19.118-2 (2020-04-29) x86_64 GNU/Linux
まとめ
VirtualBox の Nested Virtualization 機能を使用して、macOS -> CentOS 7.8.2003 -> Debian 10.4 という仮想マシンの入れ子環境が構築できました。
L2 仮想マシンのパフォーマンスは確認していませんが、検証環境が簡単に準備できるようになって良いかもと感じました。