仮想環境メモ

とある仕事でUbuntu+vagrant -> CentOS7を動かさないといけなくて試行錯誤したメモ。ハマりどころが多い。

要件

Ubuntu+vagrantの上でCentOS7を動かしていろいろする。

ユーザー環境はNote PCに直接Ubuntuをインストールしているんだが、そんなマシンは手元にないので有りもので間に合わせる。

  • M1 Macbook Air (2021)
  • Windows 10 pro (Haswell/Intel Core i7 4790)

結局のところ

  • Windows10のHyper-VでNested-VMして、Ubuntuを入れてvagrant+virtualboxが本番に一番近く、ちゃんと動く
  • Windows10のWSL2なUbuntuからだといろいろハマるが、WSL2使いたいんだよな
  • M1 Macからは制限がありまくり。Ubuntuでなく生MacOSからvagrantでも大半の作業はできるんで、これも併用
  • M1 Macはqemuの2段重ねを使う手もある。2段目がvagrant-qemuになるので、ネットワークなどの制限はある

Hyper-VをPowershellで操作

Hyper-V上で仮想環境を入れ子

Set-VMProcessor -VMName <VMName> -ExposeVirtualizationExtensions $true

環境変数メモ

export VAGRANT_NO_COLOR="1"
export VAGRANT_WSL_ENABLE_WINDOWS_ACCESS="1"
export PATH="$PATH:/mnt/c/Program Files/Oracle/VirtualBox"
export VAGRANT_WSL_WINDOWS_ACCESS_USER_HOME_PATH="/mnt/c/vagrant"
export VAGRANT_LOG=debug vagrant up

Nested Virtualization

vagrant boxの保存と再利用

vagrant hostとguestのバージョンが不一致だとファイル共有できない

VMWare Toolsみたいなもん

自動的にバージョンを合わせてくれるプラグインがある

vagrant plugin install vagrant-vbguest

自動更新したくない場合は、Vagrantfile に設定追加

if Vagrant.has_plugin?("vagrant-vbguest")
    config.vbguest.auto_update = false
end
if Vagrant.has_plugin?("vagrant-vbguest")
    config.vbguest.no_remote = true
end

vagrantとvirtualbox

copyを取る

$ vagrant status
$ vagrant package [:VN_name] --output [:output_file_name].box

できたboxをvagrant box addで追加する

$ vagrant box add [:VM name] [:box file path]
$ vagrant box list
$ vagrant init [:VM name]
$ vagrant up
  • vagrant環境のboxをバックアップする方法 - Qiita - https://qiita.com/rakuraku0615/items/5fcd59b1c6f263142ec5

snapshotを取る

バージョンが古いとVM名が省略できない?(2.2.6で確認)

$ vagrant snapshot save [VM名]  {セーブポイント名}
$ vagrant snapshot restore [VM名]  {セーブポイント名}
$ vagrant snapshot list
$ vagrant snapshot delete [VM名]  {セーブポイント名}

vagrant global-status / status

環境によって微妙に表示が違う。仮想環境ソフトの返事をそのまま表示しているようだ。

Virtualizestatustestedfrom?
virtualboxpoweroffubuntu+virtualbox, Windows+virtualboxVBoxManage showvminfo
hypervoffWindows+hyper-v, WSL+hyper-vHyper-V\Get-VM
qemustoppedM1 Mac+qemu
vmware_desktopnot runningM1 Mac+VMwarevmxを直接見ている?
libvirtshutoffubuntu+libvirtvirsh?

いろんな環境

以下さまざまな環境で試してみた。

M1 mac + vagrant-qemu -> CentOS7

MacOSから直接vagrant/CentOS7を起動する。 Ubuntuを経由しないのでテスト環境としてはいまいちだが、簡単で速い。

Vagrant.configure("2") do |config|
  config.vm.box = "ppggff/centos-7-aarch64-2009-4K"
  config.vm.boot_timeout = 600
  config.vm.synced_folder ".", "/vagrant", disabled: true
  config.vm.provider :qemu do |qemu|
    qemu.memory = "3G"
    qemu.cpu = "host"
    qemu.machine = "virt,accel=hvf,highmem=off"
  end
end

M1 mac + vagrant-qemu -> Ubuntu arm + vagrant-qemu(TCG) -> CentOS7

vagrant-qemuの2段重ね。M1はNested-VMに対応していないので、2段目はTCG(Tiny Code Generator)を使う。 遅いけど、1段目をTCGにするよりは快適。

Vagrant.configure("2") do |config|
  config.vm.box = "ppggff/centos-7-aarch64-2009-4K"
  config.vm.box_version = "1.0.0"
  config.vm.provider "qemu" do |qe|
    qe.qemu_dir = '/usr/local/share/qemu'
    qe.memory = "3G"
    qe.machine = 'virt,accel=tcg,highmem=off'
  end
end

M1 mac + vagrant-vmware_desktop -> Ubuntu arm

CentOSのboxは動かなかった(なかった)。Ubuntuは動くので作ればいいのか? ドキュメントでは2.2.18でないと動かなかったとあるが、2.2.19で動いた。

Vagrant.configure("2") do |config|
  config.vm.box = "spox/ubuntu-arm"
  config.vm.box_version = "1.0.0"
  config.vm.provider "vmware_desktop" do |v|
    v.gui = true
    v.memory = "1024"
    v.linked_clone = false
    v.vmx["ethernet0.pcislotnumber"] = "160"
  end
end

M1 mac + utm -> Ubuntu 22.04/aarch64 + vagrant-libvirt -> CentOS7/x86_64

Ubuntuはutmの仮想化で動かし、CentOSをx86エミュレーションする。遅いけど、思ったよりは速い。 CentOS7/aarch64なboxがあれば、エミュレーション無しでいけるか? (と、思ったけどM1はNested-VMの制限があるのでダメだと思う。vagrant-qemu TCGを使えば良いはず)

  • kvm - E: Package 'libvirt-bin' has no installation candidate - Ask Ubuntu - https://askubuntu.com/questions/1089753/e-package-libvirt-bin-has-no-installation-candidate
sudo apt -y install qemu qemu-system-x86
sudo apt -y install libvirt0 libvirt-clients libvirt-daemon libvirt-daemon-config-qemu libvirt-daemon-config-network libvirt-daemon-system libvirt-daemon-systemd
sudo apt -y install vagrant vagrant-libvirt
sudo systemctl start libvirtd
sudo adduser $USER libvirt
(logout/login)
vagrant up --provider=libvirt
Vagrant.configure("2") do |config|
  config.vm.box = "centos/7"
  config.vm.boot_timeout = 600
  config.vm.provider :libvirt do |libvirt|
    libvirt.driver = "qemu"
    libvirt.cpu_mode = "custom"
    libvirt.emulator_path = "/usr/bin/qemu-system-x86_64"
    libvirt.machine_arch = "x86_64"
  end
end

M1 mac + utm -> Ubuntu 22.04/x86_64 + vagrant -> CentOS7/x86_64

1つ前と違って、Ubuntu側もx86_64エミュレート。めっちゃ遅いけど動くことは動く。非常手段

M1 mac + utm -> CentOS7/aarch64

vagrant抜きだと(当たり前に)動く。Vagrant抜きでCentOS7の機能を調べるだけなら、これでもいい。

M1 mac+vagrant/vmware

普通に動く。aarch64なboxが必要。

Vagrant.configure("2") do |config|
  config.vm.box = "spox/ubuntu-arm"
  config.vm.box_version = "1.0.0"
  config.vm.provider "vmware_desktop" do |v|
    v.gui = true
    v.memory = "1024"
    v.linked_clone = false
    v.vmx["ethernet0.pcislotnumber"] = "160"
  end
end

Windows10+Hyper-V -> Ubuntu+vagrant/virtualbox -> CentOS7

普通に動く。本番に近い環境なので最後はこれでテストする。

VMに仮想化を許す必要がある。

Set-VMProcessor -VMName <VMName> -ExposeVirtualizationExtensions $true

Hyper-Vマネージャーの 設定->ハードウェア->セキュリティ->セキュアブートのチェックを外す必要もある。

Windows10 + Hyper-V -> Ubuntu + vagrant/hyperv -> CentOS7

Windowsで動かさないとダメ? WSL+Ubuntuなら動くんだけどな Windows環境のvagrant.exeを見てるような?

$ vagrant up --provider=hyperv
The provider 'hyperv' that was requested to back the machine
'default' is reporting that it isn't usable on this system. The
reason is shown below:

The Hyper-V provider only works on Windows. Please try to
use another provider.

Windows10 + wsl2 -> Ubuntu + vagrant/hyperv -> CentOS7

Windowsのフォルダ(/mnt/cなど)の下にvagrant環境をつくらないと失敗する。ubuntuのfile system内ではダメ。 たぶん、Windows環境のvagrant.exeを使ってるのだと思う。 (次節に書いたように、vagrant.exe up などとしても動くし)

export VAGRANT_WSL_ENABLE_WINDOWS_ACCESS="1"

Hyper-VのDefault SwitchとWSL2の間の通信ができなくて失敗する場合

==> default: Waiting for machine to boot. This may take a few minutes...
    default: SSH address: 172.28.163.72:22
    default: SSH username: vagrant
    default: SSH auth method: private key
Timed out while waiting for the machine to boot. This means that
Vagrant was unable to communicate with the guest machine within
the configured ("config.vm.boot_timeout" value) time period.

Windows10+wsl2 -> Ubuntu+Windowsのvagrant/hyperv -> CentOS7

wsl2のubuntuでalias vagrant 'vagrant.exe' すると、それっぽく動く。インチキくさいw

vagrant ssh すると秘密鍵のパーミッションで怒られる

vagrant up したときにエラーが出る場合

"The executable 'cmd.exe' Vagrant is trying to run was not found in the PATH variable. This is an error. Please verify this software is installed and on the path."

  • メッセージの通り、PATHが通っていない
    • WSL下のlinuxに直接sshでログインするとダメ。Windowsからwsl.exeで入るとOK
    • 実はwsl.exeがPATHを通している

Windows10+wsl2 -> Ubuntu+vagrant/virtualbox -> CentOS7

ハマりどころが多い。オススメしない。

export PATH="$PATH:/mnt/c/Program Files/Oracle/VirtualBox"

kernel-headersとバージョンが合わないとVirtualboxが起動しない

2段重ねのオーバーヘッド

UnixBench Index. Single CPU / Multi CPU

値が変なのは何故だろうか?タイマーが怪しい?? TCG遅いなあ。同じアーキテクチャーなら速くなったりしないのか?

|VM |dhry2reg |←multi |whetstone-double|← multi | |--------------------------------|-------------------|----------------|----------------------------| |M1 |5440.8 |29876.1/8CPU |1379.1 |8204.5/8CPU| |M1+qemu aarch64 |6033.3 |11688.5/2CPU |1465.8 |2844.0/2CPU| |M1+qemu aarch64/TCG |323.2 |603.9/2CPU |164.7 |322.2/2CPU | |M1+qemu aarch64+qemu aarch64/TCG|333.4 |638.5/2CPU |80.1 |155.2/2CPU |

以下はi7-4790@3.60GHz

|VM |dhry2reg |←multi |whetstone-double|← multi | |--------------------------------|-------------------|----------------|----------------------------| |WSL |3230.3 |16029.6/8CPU |1113.8 |7325.3/8CPU| |Hyper-V |3243.5 |6207.9/2CPU |1114.3 |2201.5/2CPU| |Hyper-V + virtual box | | | | |

要調査

  • vagrant plugin install vagrant-vmware-desktop
  • QEMU → Use Hypervisor をoffにしないとinstallできない(DVD boot後、installerに行かない)
  • M1の仮想化抜きでQEMU+aarch64を動かす方法
    • TGSを使えば良いようだ
  • Stderr: VBoxManage: error: Implementation of the USB 2.0 controller not found!
    • sudo apt install virtualbox-ext-pack
  • Timed out while waiting for the machine to boot. This means that Vagrant was unable to communicate with the guest machine within the configured ("config.vm.boot_timeout" value) time period.
    • vagrant ssh-config
    • ssh-keygen -yf /home/user/.vagrant.d/insecure_private_key > public_key