この連休は天気が悪かったこともあり、先日購入した Core i5 9400 を使って、ほぼサーバーのリプレース作業に費やしました。結構どっぷりハマったので、完全に自分のためのメモです。
FreeBSD jail の管理をラクにやりたい
せっかくサーバーの再セットアップするということで、いろいろゴチャゴチャしているところをキレイにしたい。その中の1つに jail がありました。
jail の管理方法はいくつかあります(管理人は ezjail を使っていました)が、どうも自分の性に合わないのか、いつも管理が取っ散らかってしまう傾向にありました。自分でもよくわからないのですが・・・なんだろう、freebsd-update の時に uname を変更しないといけないとか、あの辺がシックリこないのかもしれません。
というわけでいろいろ調べていると、iocage というのが良さそうです。これは FreeNAS でも使用されているしくみだそうです。しかも FreeBSD 12.0-RELEASE から VIMAGE でネットワークインターフェースも分離できるということです(今さら)。
ただし、これを使うためには ZFS が必要です。というわけで今回は、ZFS+iocage で jail をラクラク管理するための環境を構築するためについてのまとめです。
細かいことはいいからとにかく iocage を使うためのセットアップ方法
以下の通りやればできます。環境はタイトルの通り、FreeBSD 12.1-RELEASE です。
インストーラー
- 「Partitioning」で「Auto (ZFS) Guided Root-on-ZFS」を選択
- 「ZFS Configurations」で「stripe」を選択
- あとはお好みで設定
インストール後の設定
インストールが完了したら、インターネットに接続可能な状態にしておき、root でログインしたら以下をコピペで実行します。
pkg install -y py37-iocage
iocage activate zroot
sysrc iocage_enable="YES"
mount -t fdescfs null /dev/fd
echo "fdescfs /dev/fd fdescfs rw 0 0" >> /etc/fstab
続けて以下を実行します。JAILNAME の環境変数や IP アドレスの部分は適宜変更してください。初回実行時はアップデートをダウンロードするためそれなりに時間がかかります。
setenv JAILNAME xxx
iocage create -n $JAILNAME -r 12.1-RELEASE
iocage set ip4_addr=192.168.1.100/24 defaultrouter=192.168.1.1 $JAILNAME
iocage set allow_raw_sockets=1 boot=on vnet=on $JAILNAME
これで完成です。jail 内で dhcp server を動かすような場合は bpf=on
も入れておきます。
iocage set bpf=on $JAILNAME
iocage の簡単な使い方
jail 起動・停止・再起動
iocage start $JAILNAME
iocage stop $JAILNAME
iocage restart $JAILNAME
起動中の jail の中に入る
iocage console $JAILNAME
jail の設定情報(プロパティ名・値)を全部見る
iocage get -a $JAILNAME
-a
ではなくプロパティ名を指定すると、そのプロパティの値だけを見ることもできます。
jail の設定情報(プロパティ値)を更新する
iocage set KEY=VALUE $JAILNAME
KEY=VALUE
のセットは、一度に複数同時に記述することもできます。
ZFS 設定をカスタマイズしてインストールする
ここからはちょっとだけ詳細です。
なんとなく、「インストーラーデフォルト設定のパーティション構成をそのまま使う」のが気に食わなかったので、カスタマイズする方法をいろいろ調べました。
インストーラーの「Partitioning」で「Shell」を選んで設定していくわけですが・・・個人的な感想としては、苦労の割にはあまり報われません。「気に食わない」程度のレベルであれば、素直に Auto 設定にしておいた方が絶対に幸せになれます。
また、インストール後でも大抵設定変更できることも多いので、いったん Auto でインストールしておいて、インストール後に設定変更することをお勧めします。
とはいえせっかく調べたので、Shell 上のコマンドだけ貼っておきます。
今回は Intel の M.2 SSD 660P を使っており、デバイス名は nvd0 となっています。
kldload zfs
sysctl vfs.zfs.min_auto_ashift=12
gpart create -s gpt nvd0
gpart add -a 4k -t efi -s 512m nvd0
gpart add -a 4k -t freebsd-boot -s 512k nvd0
gpart add -a 4k -t freebsd-swap -s 4g nvd0
gpart add -a 4k -t freebsd-zfs nvd0
zpool labelclear -f nvd0p4
zpool create -o altroot=/mnt -o cachefile=/tmp/zpool.cache -O mountpoint=none -O compression=lz4 -O atime=off zroot nvd0p4
zfs create -o mountpoint=/ -o canmount=noauto -p zroot/ROOT/default
zfs mount zroot/ROOT/default
zfs create -o mountpoint=/tmp -o exec=on -o setuid=off zroot/tmp
zfs create -o mountpoint=/usr -o canmount=off zroot/usr
zfs create -o mountpoint=/usr/ports -o compression=gzip-9 -o setuid=off zroot/usr/ports
zfs create -o mountpoint=/usr/src -o compression=gzip-9 zroot/usr/src
zfs create -o mountpoint=/var zroot/var
zfs create -o mountpoint=/var/log -o exec=off -o setuid=off zroot/var/log
zfs create -o mountpoint=/home zroot/home
zpool set bootfs=zroot/ROOT/default zroot
gpart bootcode -b /boot/pmbr -p /boot/gptzfsboot -i 2 nvd0
あと、インストーラの最後で再び shell に入り、/etc/rc.conf
に zfs_enable=YES
を入れておきます。これを入れておかないとインストール後の初回起動時に全くマウントされないという悲しいことになります。
iocage のセットアップ
セットアップ方法自体は上に書いた通りです。
# pkg install -y py37-iocage
# iocage activate zroot
# sysrc iocage_enable="YES"
# mount -t fdescfs null /dev/fd
# echo "fdescfs /dev/fd fdescfs rw 0 0" >> /etc/fstab
# setenv JAILNAME xxx
# iocage create -n $JAILNAME -r 12.1-RELEASE
Fetching: 12.1-RELEASE
Downloading: MANIFEST [####################] 100%
Downloading: base.txz [####################] 100%
Downloading: lib32.txz [####################] 100%
Downloading: src.txz [####################] 100%
Extracting: base.txz...
Extracting: lib32.txz...
Extracting: src.txz...
* Updating 12.1-RELEASE to the latest patch level...
Looking up update.FreeBSD.org mirrors... 3 mirrors found.
Fetching public key from update2.freebsd.org... done.
Fetching metadata signature for 12.1-RELEASE from update2.freebsd.org... done.
Fetching metadata index... done.
Fetching 2 metadata files... done.
Inspecting system... done.
Preparing to download files... done.
Fetching 516 patches.....10....20....30....40........500....510... done.
Applying patches... done.
Fetching 23 files... ....10....20. done.
The following files will be removed as part of updating to
12.1-RELEASE-p7:
/usr/share/zoneinfo/America/Godthab
/usr/src/contrib/unbound/config.h
The following files will be added as part of updating to
12.1-RELEASE-p7:
/usr/share/zoneinfo/America/Nuuk
/usr/src/contrib/ntp/include/ntp_calgps.h
/usr/src/contrib/ntp/include/ntp_psl.h
(snip)
/usr/src/usr.sbin/unbound/checkconf/Makefile
/usr/src/usr.sbin/unbound/control/Makefile
/usr/src/usr.sbin/unbound/daemon/Makefile
Installing updates... done.
Missing default rc.conf, creating it
$JAILNAME successfully created!
初回実行時はアップデータのダウンロードが実行されることがあるため、ある程度時間がかかります。
実行後、ZFS の状態を見ると、iocage 用の領域が作られていることがわかります。
# zfs set mountpoint=/jail zroot/iocage
# zfs list | grep jail
zroot/iocage 1.74G 453G 104K /jail
zroot/iocage/download 371M 453G 88K /jail/download
zroot/iocage/download/12.1-RELEASE 371M 453G 371M /jail/download/12.1-RELEASE
zroot/iocage/images 88K 453G 88K /jail/images
zroot/iocage/jails 404K 453G 88K /jail/jails
zroot/iocage/jails/$JAILNAME 316K 453G 92K /jail/jails/$JAILNAME
zroot/iocage/jails/$JAILNAME/root 224K 453G 1.38G /jail/jails/$JAILNAME/root
zroot/iocage/log 88K 453G 88K /jail/log
zroot/iocage/releases 1.38G 453G 88K /jail/releases
ネットワークの設定を行います。ここで vnet=on
を設定することで、VIMAGE でネットワークインターフェースの分離が行われます。
# iocage set ip4_addr=192.168.1.100/24 defaultrouter=192.168.1.1 $JAILNAME
ip4_addr: none -> 192.168.1.100/24
defaultrouter: auto -> 192.168.1.1
# iocage set allow_raw_sockets=1 boot=on vnet=on bpf=on $JAILNAME
allow_raw_sockets: 0 -> 1
boot: 0 -> 1
vnet: 0 -> 1
# iocage start $JAILNAME
No default gateway found for ipv6.
* Starting $JAILNAME
+ Started OK
+ Using devfs_ruleset: 1000 (iocage generated default)
+ Configuring VNET OK
+ Using IP options: vnet
+ Starting services OK
+ Executing poststart OK
VIMAGE については以下の SlideShare をご覧ください。ハッキリ言って超わかりやすいです(P.4-P.11)。
実際に確認してみると、vnet0.1
という名前で epair が作られていることがわかります。
# ifconfig
(snip)
bridge0: flags=8843<UP,BROADCAST,RUNNING,SIMPLEX,MULTICAST> metric 0 mtu 1500
ether 02:c2:67:df:ee:00
id 00:00:00:00:00:00 priority 32768 hellotime 2 fwddelay 15
maxage 20 holdcnt 6 proto rstp maxaddr 2000 timeout 1200
root id 00:00:00:00:00:00 priority 32768 ifcost 0 port 0
member: vnet0.1 flags=143<LEARNING,DISCOVER,AUTOEDGE,AUTOPTP>
ifmaxaddr 0 port 5 priority 128 path cost 2000
member: igb0 flags=143<LEARNING,DISCOVER,AUTOEDGE,AUTOPTP>
ifmaxaddr 0 port 1 priority 128 path cost 20000
groups: bridge
nd6 options=9<PERFORMNUD,IFDISABLED>
vnet0.1: flags=8943<UP,BROADCAST,RUNNING,PROMISC,SIMPLEX,MULTICAST> metric 0 mtu 1500
description: associated with jail: $JAILNAME as nic: epair0b
options=8<VLAN_MTU>
ether XX:XX:XX:XX:XX:XX
hwaddr XX:XX:XX:XX:XX:XX
inet6 fe80::aaa1:59ff:fe6a:86aa%vnet0.1 prefixlen 64 scopeid 0x5
groups: epair
media: Ethernet 10Gbase-T (10Gbase-T <full-duplex>)
status: active
nd6 options=21<PERFORMNUD,AUTO_LINKLOCAL>
# iocage console $JAILNAME
# 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 0xff000000
groups: lo
nd6 options=21<PERFORMNUD,AUTO_LINKLOCAL>
epair0b: flags=8843<UP,BROADCAST,RUNNING,SIMPLEX,MULTICAST> metric 0 mtu 1500
options=8<VLAN_MTU>
ether XX:XX:XX:XX:XX:XX
hwaddr XX:XX:XX:XX:XX:XX
inet 192.168.1.100 netmask 0xffffff00 broadcast 192.168.1.255
inet6 fe80::aaa1:59ff:fe6a:86ab%epair0b prefixlen 64 scopeid 0x2
groups: epair
media: Ethernet 10Gbase-T (10Gbase-T <full-duplex>)
status: active
nd6 options=21<PERFORMNUD,AUTO_LINKLOCAL>
iocage を使った感想
今のところ、コマンド体系が直感的で非常に使いやすいです。ZFS を使える環境にあるのであればオススメできます。
バージョンアップ時の使い勝手が気になるところですが、まだセットアップしたてで試せていないので、また別の機会にまとめたいと思います。
コメント