現在自宅では主にNASの為に構築したFreeBSD stable/9環境のマシンが常時起動しているが、オールインワンなホストにせず各機能毎にjailを作成し構築したので、jail構築の記録。
jailゲスト上でSambaを動かしたかったので、ネットワークはVIMAGEを利用している。
なお、この記録は個人的なものであり、本記録を真似・参考にされるなどした際に問題が起きても当方はいかなる責任も負わない。
環境
- FreeBSD 9.1-STABLE amd64
- 各jailゲストは /vps/(jail) に設置する。jail名であって、ホスト名ではない。(スクリプトを少し変更すれば、ディレクトリパスをホスト名にすることも可能。
- カーネルでVIMAGEを有効にする。
- jailの設定はrc.conf(5)ではなく、jail.conf(5)で行う。
- 起動スクリプトは sysutils/jail2 を利用する。
- VIMAGE対応の部分に絞って記載する方向、カーネル再構築方法や基本的なjailゲストの作成は記載しない。
昔話をすると、最初に構築した頃は9-CURRENTを使っていた。当時はVIMAGE(vnet)用のepairデバイスをifconfigでdestroyするとOSが固まることが良くあったが、いつの間にか安定していた。
VIMAGE対応(ホスト)
カーネルコンフィギュレーションファイルにてVIMAGEを有効にし、再構築する。
(追加項目) options VIMAGE
ident等も適宜変更の事。当方は安直にVIMAGEとしている。
ネットワーク設定(ホスト)
ブリッジデバイス(bridge0)を作成し、物理NIC(今回はem0)をブリッジのメンバーに追加する設定。IPアドレスはbridge0に振る(今回は10.0.0.33/24)。
cloned_interfaces="bridge0" ifconfig_bridge0="inet 10.0.0.3 netmask 255.255.255.0 addm em0" ifconfig_em0="up"
ネットワーク設定(ゲスト)
基本的なjailだとホスト名はホスト側のrc.confで指定するが、今回はゲスト側のrc.confで指定する。また、ホスト側とネットワークが独立しているので、デフォルトゲートウェイ設定(今回は10.0.0.1)もrc.confで行う。
hostname="guest" defaultrouter="10.0.0.1"
devfs設定(ホスト側)
netstatで/dev/memや/dev/kmemが存在しないとエラーが表示されるので、jailゲストのデフォルトルールセット(4番)にmem, kmemを追加した5番を作成した。
# vi /etc/devfs.rules --- [devfsrules_jail2=5] add include $devfsrules_hide_all add include $devfsrules_unhide_basic add include $devfsrules_unhide_login add path zfs unhide add path mem unhide add path kmem unhide ---
デフォルト設定は /etc/defaults/devfs.rules に存在する。今時点のルールセット4番の内容:
# Devices usually found in a jail. # [devfsrules_jail=4] add include $devfsrules_hide_all add include $devfsrules_unhide_basic add include $devfsrules_unhide_login add path zfs unhide
jail.conf作成(ホスト側)
詳細は jail.conf(5) や jail(8) のmanを参照。要するにjail -c するときのオプション等をjail.confにずらずら並べているが、変数的な概念があるので便利に使える。
# vi /etc/jail.conf --- exec.prestart = "ifconfig epair${if} create up >/dev/null"; exec.prestart += "ifconfig bridge0 addm epair${if}a"; exec.start = "ifconfig lo0 up 127.0.0.1"; exec.start += "ifconfig epair${if}b up $ipaddr"; exec.start += "sh /etc/rc"; exec.stop = "sh /etc/rc.shutdown"; exec.poststop = "ifconfig epair${if}a destroy"; mount.devfs; devfs_ruleset = 5; vnet; vnet.interface = "epair${if}b"; path = "/vps/${name}"; persist; j0 { $if = 0; $ipaddr = 10.0.0.34; } j1 { $if = 1; $ipaddr = 10.0.0.35; } j2 { $if = 2; $ipaddr = 10.0.0.36; } j3 { $if = 3; $ipaddr = 10.0.0.37; } ---
exec.prestart〜persistまでが共通の処理、j0〜j3の各セクションでゲスト毎の設定を行う。
- exec.prestart
- ゲスト起動前にホスト上で実行するコマンド。ゲスト毎にepairデバイス(番号は各ゲストの$ifで指定)をcreateし、bridge0に追加する。
- exec.start
- ゲスト起動時にゲスト上で実行するコマンド。ループバックデバイスとepairデバイスを起動してIPアドレス割り当てし、/etc/rcを実行する。
- exec.stop
- ゲスト終了時にゲスト上で実行するコマンド。/etc/rc.shutdownを実行する。
- exec.poststop
- ゲスト終了後にホスト上で実行するコマンド。epairデバイスをdestroyする。
- mount.devfs
- devfsのマウント設定
- devfs_ruleset
- devfsがマウントするルールセット指定。ここでは上記の5番(devfsrules_jail2)を指定。
- vnet
- ゲストのネットワークに VIMAGE を使用する。
- vnet.interface
- ゲストに割り当てるvnet用デバイス名。epairNbを指定している。
- path
- ゲストのルートディレクトリ。$name = j0, j1, j2, j3 等なので、/vps/j0 等がルートディレクトリになる。
- persist
- ゲストを永続させて起動する。(指定しないとすぐ終了してしまう)
- $if
- ここではepairデバイスの番号として利用している。$if = 0; なら、exec.prestartやexec.start、exec.poststop のepairデバイスが epair0 等として置き換わる。
- $ipaddr
- ここではゲストのIPアドレスを指定している。(exec.start の2行目で使われている)
jail.confを作成したら、jail -c j0 等として起動を確認する。
(j0を起動/終了する) # jail -c j0 (起動) # jail -r j0 (終了)
起動スクリプトの準備と自動起動設定
portsより、sysutils/jail2 をインストールする。(/usr/local/etc/rc.d/jail2 という、起動スクリプトのみの小さなports)
インストールできたら、自動起動設定を行う。
# vi /etc/rc.conf --- jail2_enable="YES" jail2_list="j0 j1 j2 j3" ---
jail2_listで指定した、j0, j1, j2, j3が自動起動の対象になる。
起動・終了
# service jail2 start (起動) # service jail2 stop (終了)
startやstopの後にjail名(j0等)を指定し、個別に起動・終了も可能。
※追記(2013/10/30)
CURRENTの/etc/rc.d/jailに、2013/10/10(UTC)付でjail.conf対応の修正が入った。
参考:Log of /stable/10/etc/rc.d/jail
上記の通りstable/10にも引き継がれたため、今度リリースされる FreeBSD 10.0-RELEASE からは、sysutils/jail2 を利用する事なく、jail.conf の設定を利用したjailの自動起動ができるようになると思われる。sysutils/jail2は、jailのバックグラウンド起動(rc.confでのjail_parallel_start=”YES”指定に相当)の機能がないため、当方の様に複数を立ち上げると順番に処理するため非常に時間がかかっていたが、/etc/rc.d/jailはjail_parallel_startの指定にも対応するため、高速化が望めるのではないかと想像する。
FreeBSD 10.0-RELEASEがリリースされ次第、10.0-STABLE環境にて試す予定。