bhyveでCentOSとUbuntuを動かす

ちょっとLinux系のTCP/IPスタックが入用になって bhyveCentOSUbuntu を 載せてみた。

事実上初めてbhyveを触るのでいろいろ誤解・理解不足があるとは思うが、 動作報告ということでご容赦願いたい。

まずOS等の環境は下の通り。 bhyveが動くハードウェアにFreeBSD12を積んで vm-bhyve (portsのsysutils/vm-bhyve) を導入して初期設定を済ませたものを想定する。

  • Intel(R) Xeon(R) CPU E3-1270 v6
  • 64GB memory
  • 43TB ZFS (ZRAID)
  • FreeBSD 12.0-RELEASE-p9 amd64
  • vm-bhyve: Bhyve virtual machine management v1.3 (rev. 103101)

このvm-bhyveを使ってLinuxを動かそうという趣向である。

CentOSの場合

(bhyveにおけるCentOSの動かし方は KANNOSEさん(?)のMy ScrapBookより「FREEBSD BHYVE+VM-BHYVEでCENTOS7をUEFIで入れてみる」 で学びました。 ありがとうございます。 インストール画面のスナップショットも載ってたりするのでおすすめです。)

bhyveのCentOS対応はちょっとまだいろいろあるようで、grub2ベースの インストールでは次のような問題がある。

  • CentOS7になる時にdefaultのファイルシステムがExt4からXFSに変わったが、 portsのsysutils/grub2-bhyveはXFSには対応していないのでインストールは できてもその(仮想)ディスクからbootできない 。
  • CentOS7のGUIインストーラからならばインストーラでファイルシステムを 変更できるが、CUIインストールでは選択の余地なくXFSになってしまう。

そこで、grubではなくUEFI(sysutils/uefi-edk2-bhyve)を使うことで XFSなCentOS7でもbootできるようにすることを考える。

vm-bhyveを使うので、最初は.templates/の下の設定ファイル(テンプレートと 呼ぶべきか)である。

# cat .templates/centos7ueficui.conf
cpu=1
disk0_name="disk0.img"
disk0_size="50g"
disk0_type="virtio-blk"
graphics="no"
loader="uefi"
memory=512M
network0_switch="public"
network0_type="virtio-net"
utctime="yes"

これを使ってVMを作るには次のようにする。 テンプレートでのメモリサイズなどは、このコマンドの実行時の コマンドラインオプションで上書きできる。

$ sudo vm create -t centos7ueficui -s 20G -m 1G myCentOS7
$ sudo vm list
NAME     DATASTORE  LOADER  CPU  MEMORY  VNC  AUTOSTART  STATE
myCentOS7  default    uefi    1    1G    -    No         Stopped

さらにインストーラを起動する。

$ sudo vm install -f centos0 /path/to/CentOS-7-x86_64-DVD-1804.iso
Starting centos0
  * found guest in /ztank/vm/centos0
  * booting...

一瞬上が表示されて画面が自動で切り替わるというかCentOSのインストール画 面へ進む。 インストールメディアは7.5相当のもの(1804)。 7.6相当の1810を使うとエラーが出て次画面へいけない。 古いUEFIで出る現象とか。

CentOSのインストール画面は次のようなもので、2行目の “Test this media & install CentOS 7”が選択された状態である。 このまま進むのではなくて、grubの設定をCUIインストールに変更するために ‘e’を押下して編集する。

Install CentOS 7
Test this media & install CentOS 7                     <==
Troubleshooting -->


Use the ^ and v keys to change the selection.
Press 'e' to edit the selected item, or 'c' for a command prompt.
The selected entry will be started automatically in 40s.

すると下のような画面になるので、二行目のvmlinuz行のrd.live.check quietを 削除して、代わりにtext console=ttyS0,115200を追加する。

setparams 'Test this media & install CentOS 7'

  linuxefi  /images/pxeboot/vmlinuz inst.stage2=hd:LABEL=CentOS\x207\x20x\86_64 rd.live.check quiet
  initrdefi /images/pxeboot/initrd.img

Press Ctrl-x to start, Ctrl-c for a command prompt or Escape to
discard edits and return to the menu. Pressing Tab lists possible
completions.

これでCtrl-Xで起動続行するとCentOSのCUIインストール画面になるので、 適宜指定してインストールする。 (minimal installだとifconfigすらないので、Infrastructure Serverくらいかなぁ。 あれはあれで余計なdaemonがいっぱい走るんだけど。)

インストール終了後にrebootしてCentOSのファイルシステム内で grubx64.efiをコピーすること。 これをやらないとVMを終了してから再び立ち上げる時にbootできなくなる。

$ sudo cp -i /boot/efi/EFI/centos/grubx64.efi /boot/efi/EFI/BOOT

これと同じ作業はホスト側からも実行可能で、ゲストのCentOSを終了したあとで

$ sudo mdconfig -a -t vnode ./myCentOS7/disk0.img
md0
$ sudo mount -t msdos /dev/md0p1 /mnt
$ sudo cp -i /mnt/EFI/centos/grubx64.efi /mnt/EFI/BOOT

でも良い。

いずれにしても、EFIアプリとしてのgrubx64.efiのコピーは一度で十分。

これでインストーラを一旦終了して、もう一度起動する。

$ sudo vm start centos0
Starting centos0
  * found guest in /ztank/vm/centos0
  * booting...

すぐにhostのシェルプロンプトに戻るので、console につなぐ。

$ sudo vm console centos0
Connected

CentOS Linux 7 (Core)
Kernel 3.10.0-862.el7.x86_64 on an x86_64

centos0 login:

で、guestのネットワークもつながっている

$ ifconfig
eth0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
        inet 10.10.10.10  netmask 255.255.255.0  broadcast 10.10.10.255
        inet6 fe80::bbbb:fcff:aaaa:44a9  prefixlen 64  scopeid 0x20<link>
        ether 58:9c:fc:06:44:a9  txqueuelen 1000  (Ethernet)
        RX packets 44  bytes 4789 (4.6 KiB)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 52  bytes 4565 (4.4 KiB)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

lo: flags=73<UP,LOOPBACK,RUNNING>  mtu 65536
        inet 127.0.0.1  netmask 255.0.0.0
        inet6 ::1  prefixlen 128  scopeid 0x10<host>
        loop  txqueuelen 1000  (Local Loopback)
        RX packets 64  bytes 5632 (5.5 KiB)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 64  bytes 5632 (5.5 KiB)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

なお、上記のvm consoleのコンソール接続は cu らしく、したがって脱出は ~. なんだけど、僕は ssh してから vm console しているので ~~. である。 やってみればわかるけど、~. だと ssh を叩き切るので悲しい。

Ubuntuの場合

Ubuntuについては @mzakiさんの「Ubuntu serverをvm-bhyveにUEFIインストール」 を参考にさせていただきました。 ありがとうございます。

残念ながら僕はUEFIでは動かせなかったので、以下は元々vm-bhyveについてきた 設定ファイル(テンプレート)を利用した。

まず、テンプレートは次の通り。

# cat ubuntu.conf
cpu=1
disk0_name="disk0.img"
disk0_type="virtio-blk"
loader="grub"
memory=512M
network0_switch="public"
network0_type="virtio-net"

これでVMを作成する。

$ sudo vm create -t ubuntu -s 50g -m 512m myUbuntu

Ubuntu 16.04 のインストールメディアから起動。 (18.04のインストールメディアでは起動できなかった。)

$ sudo vm install -f myUbuntu /path/to/ubuntu-16.04.6-server-amd64.iso

boot時のgrubメニュー書き換えやgrubx64.efiのコピーなどの調整はしていない。 でもちょっとなんか忘れてる気がする。

コンソールを取るには

$ sudo vm start myUbuntu
$ sudo vm console myUbuntu

(2019/Aug/10頃書いた)