FreeBSD 12.1-RELEASE で zfs と iocage を使って VIMAGE で jail を設定する

freebsd

この連休は天気が悪かったこともあり、先日購入した 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 設定をカスタマイズしてインストールする

ここからはちょっとだけ詳細です。

なんとなく、「インストーラーデフォルト設定のパーティション構成をそのまま使う」のが気に食わなかったので、カスタマイズする方法をいろいろ調べました。

FreeBSD 11.1-RELEASEを自由なZFSパーティション構成でインストールする
FreeBSD 11.1-RELEASEを自由なZFSパーティション構成でインストールする bsdinstallの登場により、FreeBSD 10あたりからRoot on ZFSでのインストールが簡単に出来るようになった。 一方で、昔ながらの手動でRoot on ZFSを作っていたユーザーは、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
Amazon.co.jp: ソリダイム(Solidigm) 3D NAND技術を搭載 インテル®SSD660Pシリーズ SSDPEKNW512G8XT : パソコン・周辺機器
Amazon.co.jp: ソリダイム(Solidigm) 3D NAND技術を搭載 インテル®SSD660Pシリーズ SSDPEKNW512G8XT : パソコン・周辺機器

あと、インストーラの最後で再び shell に入り、/etc/rc.confzfs_enable=YES を入れておきます。これを入れておかないとインストール後の初回起動時に全くマウントされないという悲しいことになります。

ZFS pool does not automount
Hi! I read more info and docs but have problem. I have two HDD, first (my boot drive ada2) prepared on time install and create ZFS pool tank0: # gpart show ada...

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 を使える環境にあるのであればオススメできます。

バージョンアップ時の使い勝手が気になるところですが、まだセットアップしたてで試せていないので、また別の機会にまとめたいと思います。

コメント

タイトルとURLをコピーしました