FreeBSD サーバ上に仮想マシン(jail)を立てる
はじめに
この記事では、FreeBSD に jail
を導入して、FreeBSD 上に仮想マシンを立てる手順を解説します。今回の実験環境は以下のようになっています。mac 上の VirtualBox で FreeBSD を動かしており、さらにその中で仮想マシンを立てる・・・というイメージです。
VirtualBox: 7.0
HostOS: macOS BigSur
GuestOS: FreeBSD 13.1-RELEASE
jail
とは
jail
は OS レベル仮想化機構実装の一つです。自分はざっくりと、FreeBSD 版 Docker と思っています。ただし、Docker は様々な OS 環境のコンテナを立てることができますが、jail
は作成したコンテナが利用できる OS は FreeBSD のみになります。つまり、jail
は、動かせるアプリケーションに制限があります。
Docker と jail
の違いについては、参考資料を参照してください[1]。
今回は、ezjail
というパッケージを使って jail
環境を構築していきます。
ezjail のインストール
ezjail
インストール
pkg install ezjail
rc.conf
に追記
echo 'ezjail_enable="YES"' >> /etc/rc.conf
設定ファイルを修正(option)
# /usr/local/etc/ezjail.conf 編集
# ezjail のディレクトリを指定できます。
# デフォルトでは、/usr/jails になっています。
# お好みでディレクトリを変更してください。
# 私はいつも /jails にしています。
ezjail_jaildir=/jails
jail
ディレクトリを作成(上で指定したもの)
mkdir /jails
basejail を作成。basejail は ezjail
で管理するすべての jail
の元になる jail
です。
ezjail-admin install
# jail ディレクトリを確認
ls /jails/
basejail flavours newjail
jail
の作成と起動
ezjail
のスコープ内に新しい jail
を作成します。作成する jail
名は test とします。
[root@vitothon /jails]# cd /jails
[root@vitothon /jails]# ezjail-admin create test 0.0.0.0
[root@vitothon /jails]# ls
basejail flavours newjail test <- 新しく作成されました
続いて jail
コマンドを使用して jail
を作成します。
# jail 名を test としています
[root@vitothon /jails]# /usr/sbin/jail -c vnet host.hostname=test name=test path=/jails/test persist
-c jail の作成(create)
vnet 独自のネットワークインタフェース、アドレス、ルーティングテーブルなどを持つ、独自の仮想ネットワークスタックを供えた jail を作成
persist このパラメタを設定すると、jail が任意のプロセスなしで存在することが可能
# ここで jls コマンドを使用すると、test が作成されていることが確認できます。
[root@vitothon /jails]# jls
JID IP Address Hostname Path
1 test /jails/test
ファイルシステムのマウントをします。
devfs
は、カーネルが管理するデバイス関係の情報をファイルシステムに見せかけて扱うことができるものです。
# mount -t タイプ デバイス マウント先ディレクトリ
[root@vitothon /jails]# mount -t devfs devfs /jails/test/dev
[root@vitothon /jails]# mount
devfs on /jails/test/dev (devfs) <- これが新しく追加されている
# devfs が /jails/test/dev にマウントされていることがわかります。
[root@vitothon /jails]# mount_nullfs /jails/basejail /jails/test/basejail
[root@vitothon /jails]# mount
/jails/basejail on /jails/test/basejail (nullfs, local, noatime, nfsv4acls) <- これが新しく追加されている
jexec
コマンドで作成した jail
に入ります。
[root@vitothon /jails]# jexec test /bin/csh
# この段階では、IP アドレスを割り当てていません
root@test:/ # ifconfig
lo0: flags=8008<LOOPBACK,MULTICAST> metric 0 mtu 16384
options=680003<RXCSUM,TXCSUM,LINKSTATE,RXCSUM_IPV6,TXCSUM_IPV6>
groups: lo
nd6 options=21<PERFORMNUD,AUTO_LINKLOCAL>
# ホストマシンに対しての ping も通りません
root@test:/ # ping 192.168.56.103
PING 192.168.56.103 (192.168.56.103): 56 data bytes
ping: sendto: Network is unreachable
jail
とホストマシンの疎通
lo0
インターフェースにループバックアドレスを設定する。
[root@vitothon /jails]# jexec test ifconfig lo0 127.0.0.1/24 up
[root@vitothon /jails]# jexec test ifconfig
lo0: flags=8049<UP,LOOPBACK,RUNNING,MULTICAST> metric 0 mtu 16384
options=680003<RXCSUM,TXCSUM,LINKSTATE,RXCSUM_IPV6,TXCSUM_IPV6>
inet6 ::1 prefixlen 128
inet6 fe80::1%lo0 prefixlen 64 scopeid 0x1
inet 127.0.0.1 netmask 0xffffff00 <- 設定されている
groups: lo
nd6 options=21<PERFORMNUD,AUTO_LINKLOCAL>
ホストマシンと jail
を繋ぐための仮想インターフェースを作成
[root@vitothon /jails]# ifconfig epair create
epair0a
[root@vitothon /jails]# ifconfig
# epair0a, epair0b が作成されたことを確認
epair0a: flags=8862<BROADCAST,RUNNING,SIMPLEX,MULTICAST> metric 0 mtu 1500
options=8<VLAN_MTU>
ether 02:66:0b:7c:50:0a
groups: epair
media: Ethernet 10Gbase-T (10Gbase-T <full-duplex>)
status: active
nd6 options=29<PERFORMNUD,IFDISABLED,AUTO_LINKLOCAL>
epair0b: flags=8862<BROADCAST,RUNNING,SIMPLEX,MULTICAST> metric 0 mtu 1500
options=8<VLAN_MTU>
ether 02:66:0b:7c:50:0b
groups: epair
media: Ethernet 10Gbase-T (10Gbase-T <full-duplex>)
status: active
nd6 options=29<PERFORMNUD,IFDISABLED,AUTO_LINKLOCAL>
# MAC アドレス設定
[root@vitothon /jails]# ifconfig epair0a link 02:c0:e4:00:00:0a
[root@vitothon /jails]# ifconfig epair0b link 02:c0:e4:00:00:0b
[root@vitothon /jails]# ifconfig
epair0a: flags=8862<BROADCAST,RUNNING,SIMPLEX,MULTICAST> metric 0 mtu 1500
options=8<VLAN_MTU>
ether 02:c0:e4:00:00:0a <- 設定
hwaddr 02:66:0b:7c:50:0a
groups: epair
media: Ethernet 10Gbase-T (10Gbase-T <full-duplex>)
status: active
nd6 options=29<PERFORMNUD,IFDISABLED,AUTO_LINKLOCAL>
epair0b: flags=8862<BROADCAST,RUNNING,SIMPLEX,MULTICAST> metric 0 mtu 1500
options=8<VLAN_MTU>
ether 02:c0:e4:00:00:0b <- 設定
hwaddr 02:66:0b:7c:50:0b
groups: epair
media: Ethernet 10Gbase-T (10Gbase-T <full-duplex>)
status: active
nd6 options=29<PERFORMNUD,IFDISABLED,AUTO_LINKLOCAL>
epair0a
にアドレスを割り当てて up する(IP アドレスは 192.168.100.254
)
[root@vitothon /jails]# ifconfig epair0a 192.168.100.254 netmask 255.255.255.0
[root@vitothon /jails]# ifconfig epair0a up
[root@vitothon /jails]# ifconfig epair0a
epair0a: flags=8863<UP,BROADCAST,RUNNING,SIMPLEX,MULTICAST> metric 0 mtu 1500
options=8<VLAN_MTU>
ether 02:c0:e4:00:00:0a
hwaddr 02:66:0b:7c:50:0a
inet 192.168.100.254 netmask 0xffffff00 broadcast 192.168.100.255
groups: epair
media: Ethernet 10Gbase-T (10Gbase-T <full-duplex>)
status: active
nd6 options=29<PERFORMNUD,IFDISABLED,AUTO_LINKLOCAL>
epair0b
は jail
(test)に接続。IP アドレスを割り当てて、up する(IP アドレスは 192.168.100.1
)。また、デフォルトルートを設定する。
[root@vitothon /jails]# ifconfig epair0b vnet test
[root@vitothon /jails]# jexec test ifconfig epair0b inet 192.168.100.1 netmask 255.255.255.0
[root@vitothon /jails]# jexec test ifconfig epair0b up
[root@vitothon /jails]# jexec test ifconfig epair0b
epair0b: flags=8863<UP,BROADCAST,RUNNING,SIMPLEX,MULTICAST> metric 0 mtu 1500
options=8<VLAN_MTU>
ether 02:c0:e4:00:00:0b
hwaddr 02:66:0b:7c:50:0b
inet 192.168.100.1 netmask 0xffffff00 broadcast 192.168.100.255
groups: epair
media: Ethernet 10Gbase-T (10Gbase-T <full-duplex>)
status: active
nd6 options=29<PERFORMNUD,IFDISABLED,AUTO_LINKLOCAL>
[root@vitothon /jails]# jexec test route add default 192.168.100.254
使用したコマンドのまとめ
ezjail-admin create test 0.0.0.0
/usr/sbin/jail -c vnet host.hostname=test name=test path=/jails/test persist
mount -t devfs devfs /jails/test/dev
mount_nullfs /jails/basejail /jails/test/basejail
jexec test ifconfig lo0 127.0.0.1/24 up
ifconfig epair create
ifconfig epair0a link 02:c0:e4:00:00:0a
ifconfig epair0b link 02:c0:e4:00:00:0b
ifconfig epair0a 192.168.100.254 netmask 255.255.255.0
ifconfig epair0a up
ifconfig epair0b vnet test
jexec test ifconfig epair0b inet 192.168.100.1 netmask 255.255.255.0
jexec test ifconfig epair0b up
jexec test route add default 192.168.100.254
jail
からホストマシンへの ping
[root@vitothon /jails]# jexec test sh
--- ここから jail ---
# ping 192.168.100.1
PING 192.168.100.1 (192.168.100.1): 56 data bytes
64 bytes from 192.168.100.1: icmp_seq=0 ttl=64 time=0.036 ms
64 bytes from 192.168.100.1: icmp_seq=1 ttl=64 time=0.039 ms
64 bytes from 192.168.100.1: icmp_seq=2 ttl=64 time=0.039 ms
OK
jail
の停止
ezjail-admin
コマンドを使用して稼働している jail
を止めます。ただし、jail
に接続していた epair0b はホストマシンに再び接続されます。
[root@vitothon /jails]# ezjail-admin stop test
Stopping jails: test.
[root@vitothon /jails]# jls
JID IP Address Hostname Path
[root@vitothon /jails]# ifconfig
epair0a: flags=8863<UP,BROADCAST,RUNNING,SIMPLEX,MULTICAST> metric 0 mtu 1500
options=8<VLAN_MTU>
ether 02:c0:e4:00:00:0a
hwaddr 02:66:0b:7c:50:0a
inet 192.168.100.254 netmask 0xffffff00 broadcast 192.168.100.255
groups: epair
media: Ethernet 10Gbase-T (10Gbase-T <full-duplex>)
status: active
nd6 options=29<PERFORMNUD,IFDISABLED,AUTO_LINKLOCAL>
epair0b: flags=8862<BROADCAST,RUNNING,SIMPLEX,MULTICAST> metric 0 mtu 1500
options=8<VLAN_MTU>
ether 02:c0:e4:00:00:0b
hwaddr 02:66:0b:7c:50:0b
media: Ethernet 10Gbase-T (10Gbase-T <full-duplex>)
status: active
nd6 options=29<PERFORMNUD,IFDISABLED,AUTO_LINKLOCAL>
# epair を削除する場合は以下のコマンドを実行(片方を指定すれば、もう片方も自動的に消えます)
# 再起動した場合は、epair は消えます
ifconfig epair0a destroy
Discussion