qjailでvnet(VIMAGE)を使っているとbridgeがbridge10という名前で自動的に作成されます。
同じサーバでvm-bhyveを使い始めた時、bridge10があるのでそのままbridge10を使う設定で運用することにしました。その後、jail環境のアップデートか何かでqjail stopをしたときにbridge10が削除されてしまい、bhyve側のネットワークが使えなくなってしまう問題にぶちあたりました。
その時の解決方法を書きます。
FreeBSDのバージョンは12.1、関係するパッケージのバージョンは↓です。
# pkg info | grep -e qjail -e bhyve
grub2-bhyve-0.40_7 Grub-emu loader for bhyve
qjail-5.4 Utility to quickly deploy and manage jails
vm-bhyve-1.3.0 Management system for bhyve virtual machines
問題発生までの環境構築メモ
qjailの構築メモ。詳しくはこちら参照
# pkg install -y qjail
# qjail install -h ftp3.freebsd.org
# qjail create -4 "IPアドレス" jailtest
# qjail config -w em0 -v none jailtest
# qjail start jailtest
# qjail console jailtest
vm-bhyveの構築メモ。詳しくはこちら参照
# pkg install -y vm-bhyve grub2-bhyve
# kldload vmm
# mkdir /var/vm
# vm init
# vm switch create -t manual -b bridge10 public
# cp /usr/local/share/examples/vm-bhyve/* /var/vm/.templates/
# fetch http://dl-cdn.alpinelinux.org/alpine/v3.10/releases/x86_64/alpine-virt-3.10.3-x86_64.iso
# vm iso alpine-virt-3.10.3-x86_64.iso
# vm create -t alpine -s 10G -m 512M -c 1 alpinevm
# sed -i '' -e 's/vmlinuz-vanilla/vmlinuz-virt/g' -e 's/initramfs-vanilla/initramfs-virt/g' /var/vm/alpinevm/alpinevm.conf
# vm install alpinevm alpine-virt-3.10.3-x86_64.iso
# vm console alpinevm
...インストールは省略
ここまでの状態だとjailもbhyveのネットワークは問題なく使用でき、
ifconfig bridge10のmemberのところはこんな感じになっています。
# ifconfig bridge10 | grep -A1 member
member: tap0 flags=143<LEARNING,DISCOVER,AUTOEDGE,AUTOPTP>
ifmaxaddr 0 port 5 priority 128 path cost 2000000
member: epair1a flags=143<LEARNING,DISCOVER,AUTOEDGE,AUTOPTP>
ifmaxaddr 0 port 4 priority 128 path cost 2000
member: em0 flags=143<LEARNING,DISCOVER,AUTOEDGE,AUTOPTP>
ifmaxaddr 0 port 1 priority 128 path cost 20000
ここでqjail stopしてjailを止めるとbridge10が削除されてしまい、bhyveの中のホストとネットワーク通信できなくなります。
# qjail stop
# ifconfig bridge10
ifconfig: interface bridge10 does not exist
ここでqjail startしてもbridge10は作成されますがbhyveで使用するtap0はmemberになりません。
手動でtap0を紐づければまた使えますが面倒です。
原因
/usr/local/bin/qjailはシェルスクリプトなのでqjail stopしたときの動きを見てみると、
qjail stopした時、ifconfigの出力結果にepairが無い場合はbridge10を削除する処理になっていました。
解決方法
qjailに手を入れるとかフック処理とか色々考えましたが、
epairを作っておけばbridge10は削除されないのでダミーのepairを作っておくことにしました。
# 手動設定用
# kldload if_bridge.ko if_epair.ko
# ifconfig bridge10 create up addm em0
# ifconfig epair9999 create
# ifconfig bridge10 addm epair9999a
# 再起動用設定
# sysrc cloned_interfaces="bridge10 epair9999"
# sysrc ifconfig_bridge10="up addm em0 addm epair9999a"
# 以下手動削除用
# ifconfig epair9999a destroy
# ifconfig bridge10 destroy
# kldunload if_bridge.ko if_epair.ko