ZFSを使いたかったので、FreeBSD 10.0をインストールしてNAS構築


タイトルの通り、新しくNASを構築しようと思ったのですが、その際にZFSを使ってみたかったのでZFSのバージョンが高いものが使えるFreeBSDをインストールして、ZFSでNAS構築をしてみました。

その中で幾つか詰まったこともあったので、作業内容と共にメモ代わりに…

SSDを認識しない

最初の難所として、システムディスクに使用しようとしていたSSDをFreeBSDのインストーラが認識しない問題が発生しました。

いくつか試したこと

BIOS上でのSSD認識確認

初めに物理的にSSDが正常に刺さっていない可能性もあるため、BIOS上でSSDを認識するか試しました。

結果として、BIOS上では正常にSSDが認識されているため、少なくとも物理的には認識できる形でつながっていることは確認できました。

別OSのインストールディスクの確認

次にFreeBSDの固有問題かを調べるために別のOS、今回は手元にあったubuntu 12.04.1のインストールディスクで試した所、こちらでは普通に認識され、インストール先に指定が出来る状態でした。

インストールディスクをFreeBSD 9.2に変更

当時インストールディスクを作ったのが、FreeBSD 10.0が正式リリースされた数日後だったのでなにかバグ等でもあるかもしれないと思い、FreeBSD 9.2のディスクを新たに作り確認してみましたが、特に変化なし

BIOSでSSDのモード変更

BIOSの設定でSATAの設定をAHCIからIDEに変更しました。
変更した所、ドライブが認識され標準のインストール画面から、インストールすることが出来ました。

インストール後、モードをAHCIに戻しても、少なくとも表面上は問題ありませんでした。(インストール時にモードの確認等しているのであれば問題があると思いますが…)

CDドライブを手動でマウント

最初は上記の指定でやっていましたが、その後テストでOS再インストールした時にいろいろ試していたら、マウントポイントを手動で指定する際に、CDドライブを指定すれば特に設定を変えずにインストーラが実行されました。

私の環境だと以下の様な形です。(ドライブ指定はおそらく環境依存)

(前略)
Manual root filesystem specification:
  : [options]
      Mount  using filesystem 
      and with the specified (optional) option list.

    eg. ufs:/dev/da0s1a
        zfs:tank
        cd9660:/dev/acd0 ro
          (which is equivalent to: mount -t cd9660 -o ro /dev/acd0 /)

  ?               List valid disk boot devices
  .               Yield 1 second (for background tasks)
      Abort manual input

mountroot> cd9660:/dev/cd0

内蔵ドライブではなくUSBの外付けDVDドライブでインストールしようとしたのが原因なのか、SSDをブート時のドライバだけでは認識できなかったのかはわかりませんが、これでインストーラが正常に起動しました。

あとは思いついたけどやらなかったことといえば、ドライバ組み込みやSATAケーブル変えることを思いつきましたが、前者は敷居が高いのと後者は別OSでは認識しているのであまり意味はなさそうだったので、試しませんでした。

OS初期設定

DNSサーバ設定

インストール段階では、DNSサーバ情報が登録されておらず、名前解決が一切できないのでURL指定でのほとんどの通信ができないので、最初に設定します。

-/etc/resolv.conf

nameserver DNSサーバのIPアドレス(デフォルトゲートウェイ等)

アップデート

インストール時の最新バージョンのディスクを使っていますがセキュリティアップデート等もあるかもしれないので、アップデート情報の確認とインストール

# freebsd-update fetch
# freebsd-update install

時計合わせ

インストール時にntpの設定はしましたが、ネットワークに後から繋いだので、最初はを手動で合わせました。

# ntpdate -b -v 2.freebsd.pool.ntp.org
本当は日本のntpサーバをすべきでしたが、ntpサーバを調べるのが面倒だったので、デフォルトに設定されていたntpサーバ宛に
//adjkerntz

システムディスクのssd trim有効化

システムディスクにはssdを利用しましたが、デフォルトではtrimの設定が有効ではなかったため、手動で有効化しました。 ただし、起動中にその起動ディスク自体の設定を変えることはできないようなので、インストールディスクをLiveCDモードで利用して、以下のコマンドで有効化、その確認を行いました。

# tunefs -t enable /dev/ada0p2
# dumpfs /dev/ada0p2|grep flags
flags   soft-updates+journal trim

ZFS構築

ある程度の初期設定が終わったら、FreeBSDを利用した主目的であるZFSの設定を行います。

プール作成

初めにZFSのプールを作成します。この際、ある程度の冗長性を持たせるためにRAIDZ2を選択して、構築しました。

# zpool status
no pools available
# zpool create zpool0 raidz2 ada1 ada2 ada3 ada4 ada5 ada6 ada7
# zpool status
  pool: zpool0
 state: ONLINE
  scan: none requested
config:

        NAME        STATE     READ WRITE CKSUM
        zpool0      ONLINE       0     0     0
          raidz2-0  ONLINE       0     0     0
            ada1    ONLINE       0     0     0
            ada2    ONLINE       0     0     0
            ada3    ONLINE       0     0     0
            ada4    ONLINE       0     0     0
            ada5    ONLINE       0     0     0
            ada6    ONLINE       0     0     0
            ada7    ONLINE       0     0     0

errors: No known data errors

# zpool list
NAME     SIZE  ALLOC   FREE    CAP  DEDUP  HEALTH  ALTROOT
zpool0    19T  1.65M  19.0T     0%  1.00x  ONLINE  -

ファイルシステム作成

作成したプールから実際にシステムにマウントされるファイルシステムを作成します。

# zfs create zpool0/main
# zfs list
NAME          USED  AVAIL  REFER  MOUNTPOINT
zpool0       1.40M  12.5T   304K  /zpool0
zpool0/main   288K  12.5T   288K  /zpool0/main

圧縮機能の利用・確認

ZFSにはファイルシステム単位でファイルの圧縮を行うことができるので、その利用およびアルゴリズム毎の動作を確認しました。

# zfs create -o compression=gzip zpool0/gzip
# zfs create -o compression=gzip-9 zpool0/gzip-9
# zfs create -o compression=zle zpool0/zle 
# zfs create -o compression=lz4 zpool0/lz4
# zfs list
NAME            USED  AVAIL  REFER  MOUNTPOINT
zpool0         2.98M  12.5T   368K  /zpool0
zpool0/gzip     288K  12.5T   288K  /zpool0/gzip
zpool0/gzip-9   288K  12.5T   288K  /zpool0/gzip-9
zpool0/lz4      288K  12.5T   288K  /zpool0/lz4
zpool0/main     288K  12.5T   288K  /zpool0/main
zpool0/zle      288K  12.5T   288K  /zpool0/zle
# zfs get compression
NAME           PROPERTY     VALUE     SOURCE
zpool0         compression  off       default
zpool0/gzip    compression  gzip      local
zpool0/gzip-9  compression  gzip-9    local
zpool0/lz4     compression  lz4       local
zpool0/main    compression  off       default
zpool0/zle     compression  zle       local

その後、/dev/urandomを使って128MBのファイルを各ファイルシステムに作成しました。

# dd if=/dev/urandom of=/zpool0/main/random.dat count=131072 bs=1024
131072+0 records in
131072+0 records out
134217728 bytes transferred in 3.618413 secs (37092982 bytes/sec)
# dd if=/dev/urandom of=/zpool0/gzip/random.dat count=131072 bs=1024
131072+0 records in
131072+0 records out
134217728 bytes transferred in 3.002447 secs (44702778 bytes/sec)
# dd if=/dev/urandom of=/zpool0/gzip-9/random.dat count=131072 bs=1024
131072+0 records in
131072+0 records out
134217728 bytes transferred in 2.879405 secs (46613008 bytes/sec)
# dd if=/dev/urandom of=/zpool0/lz4/random.dat count=131072 bs=1024
131072+0 records in
131072+0 records out
134217728 bytes transferred in 2.997831 secs (44771615 bytes/sec)

# dd if=/dev/urandom of=/zpool0/zle/random.dat count=131072 bs=1024
131072+0 records in
131072+0 records out
134217728 bytes transferred in 2.965427 secs (45260841 bytes/sec)

# zfs list
NAME            USED  AVAIL  REFER  MOUNTPOINT
zpool0          644M  12.5T   368K  /zpool0
zpool0/gzip     128M  12.5T   128M  /zpool0/gzip
zpool0/gzip-9   128M  12.5T   128M  /zpool0/gzip-9
zpool0/lz4      128M  12.5T   128M  /zpool0/lz4
zpool0/main     128M  12.5T   128M  /zpool0/main
zpool0/zle      128M  12.5T   128M  /zpool0/zle

しかし、圧縮するシステムの方が圧縮しないよりも書き込みが速い自体になってしましました。更に書き込み自体も特別圧縮された様子が無く、完全なランダムデータのため圧縮できなかったのではと思い、用意したbmpファイルで再チェックしました。

# ls -la sample.bmp
-rw-r--r--  1 user  user  16174134 Jan 28 19:39 sample.bmp
# dd if=sample.bmp of=/zpool0/main/sample.bmp bs=1024
15795+1 records in
15795+1 records out
16174134 bytes transferred in 0.623115 secs (25956908 bytes/sec)
# dd if=sample.bmp of=/zpool0/gzip/sample.bmp bs=1024
15795+1 records in
15795+1 records out
16174134 bytes transferred in 0.437439 secs (36974587 bytes/sec)
# dd if=sample.bmp of=/zpool0/gzip-9/sample.bmp bs=1024
15795+1 records in
15795+1 records out
16174134 bytes transferred in 0.214765 secs (75310905 bytes/sec)
# dd if=sample.bmp of=/zpool0/lz4/sample.bmp bs=1024
15795+1 records in
15795+1 records out
16174134 bytes transferred in 0.420913 secs (38426313 bytes/sec)
# dd if=sample.bmp of=/zpool0/zle/sample.bmp bs=1024
15795+1 records in
15795+1 records out
16174134 bytes transferred in 0.165674 secs (97626283 bytes/sec)

# zfs list
NAME            USED  AVAIL  REFER  MOUNTPOINT
zpool0         47.0M  12.5T   368K  /zpool0
zpool0/gzip    4.78M  12.5T  4.78M  /zpool0/gzip
zpool0/gzip-9  4.75M  12.5T  4.75M  /zpool0/gzip-9
zpool0/lz4     6.12M  12.5T  6.12M  /zpool0/lz4
zpool0/main    15.8M  12.5T  15.8M  /zpool0/main
zpool0/zle     13.9M  12.5T  13.9M  /zpool0/zle

# zfs get compressratio
NAME           PROPERTY       VALUE  SOURCE
zpool0         compressratio  1.79x  -
zpool0/gzip    compressratio  3.70x  -
zpool0/gzip-9  compressratio  3.72x  -
zpool0/lz4     compressratio  2.71x  -
zpool0/main    compressratio  1.00x  -
zpool0/zle     compressratio  1.14x  -

今回は圧縮アルゴリズム毎に使用されている容量にかなり差が生まれ、圧縮機能が動いていることが確認できました。しかし、書き込みはやはり圧縮しないよりも圧縮した方が早く、これがただの誤差レベルなのか、圧縮して書きこむ方が最終的な書き込み量が減るため、こちらの体感として早くなっているのかはわかりませんでした。

ZFS破壊テスト

わざわざ冗長性を持たせていても、実際に障害時に復旧できなかったら意味が無いため、わざと障害を起こし、そこから復旧できるかを以下の3点、テストしました。

  • SATAケーブルを稼働中に引き抜く(HDDの故障テスト)
  • SATAケーブルを稼働中に抜き、別のHDDを差す(HDDの故障→交換テスト)
  • ZFS領域はそのまま、OSを再インストールしてデータを読み出せるか確認する(システムディスクの故障→復旧テスト)

SATAケーブルを稼働中に引き抜く

文字通り、SATAケーブルを稼働中にいきなり引き抜きアクセス出来ない状態にします。
今回、raidz2なので理論上2台の障害までは問題なく動くはずなので、2台引き抜きます。
するとzpool statusで以下のように表示されます。

# zpool status -x
  pool: zpool0
 state: DEGRADED
status: One or more devices could not be used because the label is missing or
        invalid.  Sufficient replicas exist for the pool to continue
        functioning in a degraded state.
action: Replace the device using 'zpool replace'.
   see: http://illumos.org/msg/ZFS-8000-4J
  scan: scrub repaired 0 in 0h0m with 0 errors on Tue Jan 28 21:37:51 2014
config:

        NAME                     STATE     READ WRITE CKSUM
        zpool0                   DEGRADED     0     0     0
          raidz2-0               DEGRADED     0     0     0
            ada1                 ONLINE       0     0     0
            ada2                 ONLINE       0     0     0
            ada3                 ONLINE       0     0     0
            ada4                 ONLINE       0     0     0
            ada5                 ONLINE       0     0     0
            6310881793467957936  FAULTED      0     0     0  was /dev/ada6
            2508579990451255890  FAULTED      0     0     0  was /dev/ada7

errors: No known data errors

一旦、エラーの出ている箇所をオフラインにして、再度SATAケーブルを挿し直した後にオンラインに戻します。

# zpool offline zpool0 ada6 ada7
# zpool status -x
  pool: zpool0
 state: DEGRADED
status: One or more devices has been taken offline by the administrator.
        Sufficient replicas exist for the pool to continue functioning in a
        degraded state.
action: Online the device using 'zpool online' or replace the device with
        'zpool replace'.
  scan: scrub repaired 0 in 0h0m with 0 errors on Tue Jan 28 21:39:08 2014
config:

        NAME                     STATE     READ WRITE CKSUM
        zpool0                   DEGRADED     0     0     0
          raidz2-0               DEGRADED     0     0     0
            ada1                 ONLINE       0     0     0
            ada2                 ONLINE       0     0     0
            ada3                 ONLINE       0     0     0
            ada4                 ONLINE       0     0     0
            ada5                 ONLINE       0     0     0
            6310881793467957936  OFFLINE      0     0     0  was /dev/ada6
            2508579990451255890  OFFLINE      0     0     0  was /dev/ada7

errors: No known data errors

//sataケーブル挿し直し
# zpool online zpool0 ada6 ada7
# zpool status -x
all pools are healthy

すると、何も問題なく表示されるようになりました。

HDDをぶっこ抜き→入れ替え

HDDを稼働中に抜いた後に、差し込む端子を変更してみました。

# zpool status -x
  pool: zpool0
 state: DEGRADED
status: One or more devices has been removed by the administrator.
        Sufficient replicas exist for the pool to continue functioning in a
        degraded state.
action: Online the device using 'zpool online' or replace the device with
        'zpool replace'.
  scan: resilvered 8K in 0h0m with 0 errors on Tue Jan 28 21:10:57 2014
config:

        NAME                     STATE     READ WRITE CKSUM
        zpool0                   DEGRADED     0     0     0
          raidz2-0               DEGRADED     0     0     0
            ada1                 ONLINE       0     0     0
            ada2                 ONLINE       0     0     0
            ada3                 ONLINE       0     0     0
            ada4                 ONLINE       0     0     0
            ada5                 ONLINE       0     0     0
            6310881793467957936  REMOVED      0     0     0  was /dev/ada6
            2508579990451255890  REMOVED      0     0     0  was /dev/ada7

ここで入れ替えた後、再構成、復旧確認まで行いました。

 # zpool offline zpool0 ada6
# zpool offline zpool0 ada7
# zpool status -x
  pool: zpool0
 state: DEGRADED
status: One or more devices has been taken offline by the administrator.
        Sufficient replicas exist for the pool to continue functioning in a
        degraded state.
action: Online the device using 'zpool online' or replace the device with
        'zpool replace'.
  scan: resilvered 132K in 0h0m with 0 errors on Tue Jan 28 21:19:26 2014
config:

        NAME                     STATE     READ WRITE CKSUM
        zpool0                   DEGRADED     0     0     0
          raidz2-0               DEGRADED     0     0     0
            ada1                 ONLINE       0     0     0
            ada2                 ONLINE       0     0     0
            ada3                 ONLINE       0     0     0
            ada4                 ONLINE       0     0     0
            ada5                 ONLINE       0     0     0
            6310881793467957936  OFFLINE      0     0     0  was /dev/ada6
            2508579990451255890  OFFLINE      0     0     0  was /dev/ada7

OS再インストール

システムディスクが壊れた際にZFSのデータが取りだせるかを検証するために、上記の状態からシステムをインストールしているSSDをフォーマット、OSの再インストールを行い、ZFSのデータが取り出せるかを確認しました。

システムディスクのフォーマット後、同じ設定でOSを再インストールした後、以下のコマンドで状態を確認。
を実行しました。

# zfs list
no dataset
no pools available
# zpool status
no pools available
# zpool status -x
no pools available
# zfs mount -a
# ls /zpool0/
ls: /zpool0/: No such file or directory

上記の通り、OS再インストール直後は以前の状態を取得できていません。
その後、復旧のためにzpool importでプール名を確認の後、強制インポートで復旧しました。

 # zpool import
   pool: zpool0
     id: 4383566041817703211
  state: ONLINE
 action: The pool can be imported using its name or numeric identifier.
 config:

        zpool0      ONLINE
          raidz2-0  ONLINE
            ada1    ONLINE
            ada2    ONLINE
            ada3    ONLINE
            ada4    ONLINE
            ada5    ONLINE
            ada6    ONLINE
            ada7    ONLINE
# zpool import -f zpool0
# zfs list
NAME            USED  AVAIL  REFER  MOUNTPOINT
zpool0         47.3M  12.5T   368K  /zpool0
zpool0/gzip    4.78M  12.5T  4.78M  /zpool0/gzip
zpool0/gzip-9  4.76M  12.5T  4.76M  /zpool0/gzip-9
zpool0/lz4     6.13M  12.5T  6.13M  /zpool0/lz4
zpool0/main    15.8M  12.5T  15.8M  /zpool0/main
zpool0/zle     13.9M  12.5T  13.9M  /zpool0/zle
# zpool list
NAME     SIZE  ALLOC   FREE    CAP  DEDUP  HEALTH  ALTROOT
zpool0    19T  71.8M  19.0T     0%  1.00x  ONLINE  -
# zpool status
  pool: zpool0
 state: ONLINE
  scan: resilvered 9.70M in 0h0m with 0 errors on Wed Jan 29 15:25:26 2014
config:

        NAME        STATE     READ WRITE CKSUM
        zpool0      ONLINE       0     0     0
          raidz2-0  ONLINE       0     0     0
            ada1    ONLINE       0     0     0
            ada2    ONLINE       0     0     0
            ada3    ONLINE       0     0     0
            ada4    ONLINE       0     0     0
            ada5    ONLINE       0     0     0
            ada6    ONLINE       0     0     0
            ada7    ONLINE       0     0     0

errors: No known data errors

# zpool status -x
all pools are healthy
# ls -la /zpool0/
total 103
drwxr-xr-x   7 root  wheel     7 Jan 28 19:50 .
drwxr-xr-x  19 root  wheel  1024 Jan 29 18:00 ..
drwxr-xr-x   2 root  wheel     4 Jan 28 21:06 gzip
drwxr-xr-x   2 root  wheel     4 Jan 28 21:07 gzip-9
drwxr-xr-x   2 root  wheel     4 Jan 28 21:06 lz4
drwxr-xr-x   2 root  wheel     4 Jan 28 21:06 main
drwxr-xr-x   2 root  wheel     3 Jan 28 19:53 zle

上記のようにimportでOS再インストール前のデータも正常に取得できました。

サービス設定

ZFSの自動起動

自動起動の設定を/etc/rc.confに追記

echo 'zfs_enable="YES"'>>/etc/rc.conf

sambaインストール

windowsからも利用することを想定しているので、ports経由でsambaをインストールしました。

#cd /usr/ports/net/samba36
#make configure
#make
#make install

自動起動の設定を/etc/rc.confに追記

# echo 'samba_enable="YES"'>>/etc/rc.conf

そしてsambaの共有ディレクトリ設定を /usr/local/etc/smb.confに記載
元々defaultの設定にコメントアウトされていたzpoolの設定を流用

[zpool0]
    path = /zpool0/
    unix extensions = no
    vfs objects = zfsacl
    nfs4:mode = special
    nfs4:acedup = merge
    nfs4:chown = yes
    writable = yes

そして既存ユーザを以下のコマンドでsamba用のユーザとしても登録

# smbpasswd -b username

そしてsambaを実行。

# service samba start

zshインストール

個人的にzshを使いたかったので、同じくports経由でインストール

# cd /usr/ports/shells/zsh
# make 
# make install
# chsh -s /usr/local/bin/zsh
$ chsh -s /usr/local/bin/zsh

UTF-8化

最近はUTF-8設定のマシンが多いので、文字コードで悩まないためにデフォルトの設定をUFT-8化しました。
– /etc/login.conf

default:\
        ...
        :charset=UTF-8:\
        :lang=en_US.UTF-8:
  • ~/.login_conf
me:\
       :charset=UTF-8:\
       :lang=ja_JP.UTF-8:

sSMTP,root宛メールの転送設定

sendmailを設定しようと思いましたが、root宛のメールを転送したいだけだったので、送信だけのsSMTPを試してみました。

sendmailの停止設定

まだ特にsendmailの設定はしていないので起動することはないと思いますが、sSMTPはsendmailの代行として動く点も多いので、競合しないよう念のため止めて起きます。

echo 'sendmail_enable="NO"'>>/etc/rc.conf
echo 'sendmail_submit_enable="NO"'>>/etc/rc.conf
echo 'sendmail_outbound_enable="NO"'>>/etc/rc.conf
echo 'sendmail_msp_queue_enable="NO"'>>/etc/rc.conf

ssmtpをインストール

# cd /usr/ports/mail/ssmtp
# make install clean
# make replace

最後のmake replaceで/etc/mail/mailer.confを修正して、sendmailからssmtpに置き換えを行ってくれるようです。

ssmtpの設定

ssmtp自体の設定とroot当てのメールをgmailに転送する設定を行います。
– /usr/local/etc/ssmtp/ssmtp.conf

[email protected]
mailhub=smtp.gmail.com:587
[email protected]
AuthPass=yourpassword
UseSTARTTLS=YES

このとき、googleの二段階認証を使っている場合、AuthPassにはログインパスワードではなく、googleアカウントのセキュリティページで発行できる「アプリケーション固有のパスワード」を設定する必要があります。

mail送信のテスト

以下のコマンドで適当なメールを送って正しく送信できるかを確認します。

$ mail -v root
Subject: <件名>
適当な本文
適当な本文
(Ctrl+Dで終了を入力)

rootに設定したアドレスで受信できていることを確認します。

ZFSのエラー通知

ZFSには標準でチェック用のperiodic scriptが含まれており、それを有効にするだけで毎日チェック→通知をしてくれるそうです。
スクリプト本体の場所は、/etc/periodic/daily/404.status-zfs です。
試しに実行すると下のような形で表示してくれます。

# /etc/periodic/daily/404.status-zfs                

Checking status of zfs pools:
NAME     SIZE  ALLOC   FREE    CAP  DEDUP  HEALTH  ALTROOT
zpool0    19T   635G  18.4T     3%  1.00x  ONLINE  -

all pools are healthy

そして毎日実行を有効にするために以下のコマンドで設定ファイルに記載します。

echo 'daily_status_zfs_enable="YES"'>> /etc/periodic.conf

Windowsからの速度計測

Windowsからも利用することを想定しているので、Windowsからの速度計測も行ってみました。

一応これも圧縮形式ごとに測定しました。

圧縮なし

main

zle

zle

 

lz4

lz4

 

gzip

gzip

gzip-9

gzip9

 

速度自体はNASとしては、それなりに高速なので、いい感じですが、やはりddで確認した時と同様に圧縮と速度の関係がわかりにくいことに…

マシンスペックもそれなりのを用意しているので、実質的に圧縮で速度低下を気にしないレベルまで圧縮速度が出ているのでしょうか。

まとめ

作り初めてまだ1~2週間程度ですが、特に問題も無い形なのでメインで使い始めました。

本来データの安全を確保するには、データを分散すべきですが、管理が大変なので大きくそれなりの安定性のところに集約しようと思い、今回のNAS制作を行いました。これで壊れたらしかたないですが、出来るだけ壊れないように冗長性や故障時の復元準備等もしているので、後は出来るだけ壊れないことを祈りつつ維持して行く形でしょうか。

参考サイト

  • http://www.freebsd.org/doc/ja/books/handbook/updating-upgrading-freebsdupdate.html
  • http://d.hatena.ne.jp/mteramoto/20130104/1357305221
  • http://d.hatena.ne.jp/flageo/20120305/p2
  • http://d.hatena.ne.jp/flageo/20120310/p1

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です

このサイトはスパムを低減するために Akismet を使っています。コメントデータの処理方法の詳細はこちらをご覧ください