~nabeken/diary/

Gentoo Linux(6年くらい)とFreeBSD(1年くらい)とOpenBSD(新参者)を使う日々。


IHANet BGP peering overview

FreeBSD 8.1-RELEASEでZFS on ROOT

Posted on Thu Jul 29 21:03:37 +0900 2010 by nabeken

LinuxのLVM + reiserfsで構築していたストレージサーバをZFSでリプレイスする計画の第1弾として、先日リリースされたFreeBSD 8.1-RELEASEでZFSを検証しました。 検証はスムーズに行ったので本番環境を意識してZFS on ROOTに挑戦しました。8.1からは以前よりも簡単になっています。

Booting from ZFS RAID0/5/6 in FreeBSD 8.0-RELEASEを参考にZFS on ROOTの構築を行ないました。自分で理解できなかった部分を補足していきます。

ディスクの下準備

今回使用するディスクはad4, ad6の2台です。

ad6は検証中に構築したZFSのstorage pool(pool名storage)です。これはそのまま使います。

ad4は検証時にFreeBSD 8.1-Rをインストールしたディスクです。sysinstallでデフォルトのスライス構成になっていました。 ある程度portsからインストールしたり、設定を施しているのでこの環境をそっくりZFS上へ載せることにしました。

まずは既存環境のバックアップを行ないます。バックアップ用にひとつファイルシステムを用意します。

# zfs create -o mountpoint=/tmproot storage/tmproot
# cd /
# rsync -avP bin ..... (必要なところ全部) /tmproot

バックアップが完了したら、いよいよad4を一度まっさらにします。この作業にはインストーラのFixitモードを使用します。CD/DVD/USBメモリからブートし、インストーラーを起動します。 今回はUSBでブートしました。

USBからブートして、Fixitモードにするところで、デバイスが見つからないというエラーがでます。これは既知の問題で、8.0-RELEASE-i386-memstick fixit - No USB devices found!にその解決方法 があります。一度、トップメニューのOptions→qを押して再スキャン後、再びFixitモードにすると正しくUSBメモリが選択肢に現われます。

ここからは最後の下準備です。ad4のスライス構成を一度まっさらにし、MBRからGPTへパーティション構成を変更します。

# gpart destroy ad4

ここでDevice busyのエラーが出る場合があります。その時は残っているパーティションを一度削除する必要があります(cf. Revenge of FreeBSD8 on SheevaPlug)。 どのパーティションが残っているかは以下で調べます。

# gpart show ad4

出てきたパーティション番号に対してdeleteしていきます。

# gpart delete -i X ad4

すべて消し終えたら改めてdestoryします。

# gpart destroy ad4

ここまででディスクの下準備は完了です。次からはパーティションの作成に移ります。

GPTパーティションの作成

まずはパーティションスキーマを作成します。その前にgpartのマニュアルを一通り目を通してください(On-line Manual of “gpart”)。

# gpart create -s gpt ad4

次に3つのパーティションを作成します。

  1. ブートコード、ブートストラップを含むパーティション
  2. swapパーティション
  3. zfs用

まずは/bootから作成します。

# gpart add -b 34 -s 128 -t freebsd-boot ad4

-t に指定している freebsd-boot は適当な文字列ではありません。パーティションタイプを識別するIDです(マニュアルの「パーティションタイプ」)。 -b は開始ブロックアドレス、-sはブロック数です。1ブロック512バイトです。

次はswapを作成します。

# gpart add -b 162 -s 8388608 -t freebsd-swap -l swap0 ad4

開始ブロックは前の開始ブロック+ブロック数になります。今回は8388608ブロック(= 4GB)に設定しました。

-l はラベル名です。これを付けると/dev/gpt/swap0 でアクセスできます。

最後にzfs用のパーティションを作成します。

# gpart add -b 8388770 -t freebsd-zfs -l disk0 ad4

ブロック数を指定していないので、残りすべてになります。パーティションの準備は完了しました。

ブートコードのインストール

zfsからブートするためのbootcodeをインストールします。

# gpart bootcode -b /mnt2/boot/pmbr -p /mnt2/boot/gptzfsboot -i 1 ad4

-b は保護用のMBRに、 -p はパーティションにブートストラップをそれぞれインストールします。

ここまででディスクの設定は完了しました。

/(root)をZFSで構成する

ZFSはディレクトリを作成するかのようにファイルシステムを作ることができます。 ZFSの管理ドキュメントではユーザそれぞれのホームディレクトリをZFSで管理する例もあるくらいです。

今回は以下のようなファイルシステムを構成します。

  • /tmp (compression=on, exec=on, setuid=off)
  • /usr
  • /usr/home
  • /usr/ports (compression=lzjb, setuid=off)
  • /usr/ports/distfiles (compression=off, exec=off, setuid=off)
  • /usr/ports/packages (compression=off, exec=off, setuid=off)
  • /var
  • /var/log (compression=lzjb, exec=off, setuid=off)
  • /var/empty (readonly, exec=off, setuid=off)
  • /var/tmp (compression=lzjb, exec=on, setuid=off)

ZFSにはファイルシステムを透過的に圧縮する機能(compression)があります。 例えば/var/logなどのテキストファイル中心のものは圧縮による効果が期待できます。 そのため、少し細かくファイルシステムを作成しています。

あとはsetuidの許可、不許可や実行(exec)の許可、不許可もファイルシステム単位で設定できます(これは従来のものでも同じです)。

Booting from ZFS RAID0/5/6 in FreeBSD 8.0-RELEASEではさらに細かくわけていますが、今回はこれで十分と判断しました。

上記のポリシーを元に実際にファイルシステムを作成していきます。 まず、モジュールを読み込みます。

# kldload /mnt2/boot/kernel/opensolaris.ko
# kldload /mnt2/boot/kernel/zfs.ko

まずstorage poolを作成します。

# zpool create zroot /dev/gpt/disk0
# zpool set bootfs=zroot zroot

チェックサムのアルゴリズムをデフォルトより強力なものにします。

# zfs set checksum=fletcher4 zroot

以後はファイルシステムを作成していきます。

# zfs create -o compression=on -o exec=on -o setuid=off zroot/tmp
# zfs create zroot/usr
# zfs create zroot/usr/home
# zfs create -o compression=lzjb -o setuid=off zroot/usr/ports
# zfs create -o compression=off -o exec=off -o setuid=off zroot/usr/ports/distfiles
# zfs create -o compression=off -o exec=off -o setuid=off zroot/usr/ports/packages
# zfs create zpool/var
# zfs create -o compression=lzjb -o exec=off -o setuid=off zroot/var/log
# zfs create -o exec=off -o setuid=off zroot/var/empty
# zfs set readonly=on zroot/var/empty
# zfs create -o compression=lzjb -o exec=on -o setuid=off zroot/var/tmp

パーミッションを設定します。

# chmod 1777 /zroot/tmp
# chmod 1777 /zroot/var/tmp

最後に/homeを/usr/homeにリンクを張ります。

# cd /zroot
# ln -s /usr/home home

以後はFreeBSDのインストール作業になります。私の場合はバックアップから書き戻します。 storgeプールをimportします。

# zpool import -f storage
# LD_LIBRARY_PATH=/tmproot/usr/local/lib /usr/local/bin/rsync -avP /tmproot/ /zroot/

書き戻しが終われば、loaderの設定を行ないます。

loader.conf, rc.conf

# cat /zroot/boot/loader.conf
vm.kmem_size="512M"
vm.kmem_size_max="4990M"
vfs.zfs.arc_min="128M"
vfs.zfs.arc_max="256M"
vfs.zfs.vdev.cache.size="5M"
vfs.zfs.prefetch_disable=1
vfs.root.mountfrom="zfs:zroot"
zfs_load="YES"

mountfromとzfs_loadが肝です。rc.confにも設定が必要です。

# cat /zroot/etc/rc.conf
zfs_enable="YES"

参考文献Booting from ZFS RAID0/5/6 in FreeBSD 8.0-RELEASEではloaderを再構築していますが、8.1-RELEASEではその作業は必要ありません。

以後は

  • /bootと/zroot/bootの設定
  • fstabの設定
  • mountpointの設定

が必要です。これは上述の参考文献と同じためそちらを参照してください。

参考文献

更新履歴

  • 初稿 (Thu, 29 Jul 2010 21:03:37 +0900)