LoginSignup
19
24

More than 1 year has passed since last update.

ZFS(Linux)のセットアップ手順

Last updated at Posted at 2016-05-10

セットアップ

インストール(Ubuntu 20.04)

sudo apt install -y zfsutils-linux

パーティションテーブルと必要に応じてパーティションの準備

ドライブ一覧確認

ls /dev/disk/by-id

ドライブごと(パーティションテーブルごと)zpoolに割り当てる場合

パーティションテーブルをGPTで作ります。台数分実行します。パーティションは作りません。zpoolを作成するときに自動的に作られます。

# HDD全体が論理消去されるため注意
dev=/dev/disk/by-id/xxx && # ドライブを指定
sudo sgdisk -Z -o $dev

  # -Z 既存のGPTとMBRを消去
  # -o GPT(GUIDパーティションテーブル)を作成

パーティションをzpoolに割り当てる場合

ドライブごとのとき同様にパーティションテーブルをGPTで作った後、以下のようにZFS用のパーティションを作ります。台数分実行します。

dev=/dev/disk/by-id/xxx && # ドライブを指定
sudo sgdisk -a 8 -n 1:40: -t 1:bf01 $dev

  # -a 8 4Kセクターに合わせる (4096/512=8)
  # -n 1:40: 第1パーティションを作成(40セクターから)
  # -t 1:bf01 第1パーティションのタイプを設定(通常のext4なら8300)

sudo sgdisk -p $dev && # GPTを確認
sudo sgdisk -i 1 $dev # 第1パーティションを確認

パーティションテーブルとパーティションを一気に作成する場合は次のとおりです。

# HDD全体が論理消去されるため注意
dev=/dev/disk/by-id/xxx && # ドライブを指定
sudo sgdisk -Z -o -a 8 -n 1:40: -t 1:bf01 $dev

zpoolに指定するIDの確認

PARTUUIDで指定する場合

パーティションのUUIDを使います。ドライブごとzpoolに割り当てる場合には使えません。ランダムな文字列で分かりにくいですが、ドライブの接続方法が変わっても不変のため安定性があります。

array1=() &&
for partuuid in $(find /dev/disk/by-partuuid -type l); do
    dev=$(readlink -f "${partuuid}")
    id2=""
    for id in $(find /dev/disk/by-id -type l); do
        dev2=$(readlink -f "${id}")
        if test $dev = $dev2
        then
            id2="${id2} ${id}"
        fi
    done
    array1=("${array1[@]}" "${dev} ${partuuid}${id2}")
done&&
orig_ifs=$IFS; IFS=$'\n' &&
array2=($(echo "${array1[*]}" | sort)) &&
echo "${array2[*]}" &&
IFS=$orig_ifs

丸ごとコピーアンドペーストして実行してください。

by-idで指定する場合

ドライブのシリアル番号を使います。個別のパーティションにも-part1、-part2とIDが振られるため、ドライブごとzpoolに割り当てる場合にも、パーティションをzpoolに割り当てる場合にも使えます。ドライブとの対応関係は分かりやすいですが、RAIDカードやUSB外付けボックスによって変わる可能性があります。

ls /dev/disk/by-id

zpoolを作成

/data/にマウントするが、canmount=offでそのマウントポイント自体はマウントから除外し、tankのひとつ下に作るファイルシステムから利用する設定(用途別に割り当て容量を制限する目論見)。

TANK=tankname &&
sudo mkdir -p /data &&
sudo zpool create -o ashift=12 -m /data/$TANK $TANK <raidz|mirror> /dev/disk/<id> /dev/disk/<id> &&
    # -o ashift=12でAFT対応。FreeBSDと違い自動判定してくれないため注意。
    # HDD1台のときはraidzを無指定にすること。複数台のときに無指定にするとストライピングになるため注意。
    # zpool createの直後に-fを付ける必要があるかもしれないが、慎重に付けること。
sudo zfs set compression=lz4 $TANK && # lz4による圧縮は高速なため有効化
sudo zfs set atime=off $TANK && # いちいち書き込みが必要になるわりにメリットが薄い最終アクセス時刻記録を無効化
sudo zfs set canmount=off $TANK && # 親ファイルシステムはマウントしない
sudo zfs set snapdir=visible $TANK && # スナップショットが.zfsディレクトリから見えるように

sudo zfs set acltype=posixacl $TANK && # ACLを有効化
sudo zfs set xattr=sa $TANK && # ACLに必要?

# 一括版
sudo mkdir -p /data &&
sudo zpool create -o ashift=12 -O compression=lz4 -O atime=off -O snapdir=visible -O canmount=off -O acltype=posixacl -O xattr=sa <tankname> <raidz|mirror> /dev/disk/<id> /dev/disk/<id>
sudo zfs set mountpoint=/data/<tankname> <tankname>

zfsを作成

tankのひとつ下にファイルシステムを作る。

sudo zfs create <tankname>/<fsname>
sudo zfs set quota=1T <tankname>/<fsname> #割り当て容量を制限できる

状況確認

zpool status #zpoolの確認
zfs list #zfsの確認
zfs list -t filesystem,snapshot,volume #同上(スナップショットを含む)

zpool get all #zpoolプロパティーの確認
zpool get all <tankname> #同上(特定のzpool)
zfs get all #zfsプロパティーの確認
zfs get all <tankname>/<fsname> #同上(特定のzfs)

zfs get compressratio #圧縮率の確認
zfs list -t snapshot -o name,creation #スナップショットの作成日時を確認

削除(やり直したいとき)

sudo zfs destroy <tankname>/<fsname>
sudo zpool destroy <tankname>

ファイル周り

所有者とパーミッションを変更

path='/data/<tankname>/<fsname>'
sudo find $path -type d -name .zfs -prune -exec chown user:group {} + &&
sudo find $path -type d -name .zfs -prune -or -type d -exec chmod 770 {} + &&
sudo find $path -type d -name .zfs -prune -or -type f -exec chmod 660 {} +

スナップショットは読み取り専用で変更できないため、触りにいかないよう除外しています。

ファイルをコピー後ハッシュをチェック

ZFS固有のものではありませんが、ついでに書いておきます。

ハッシュを取得

#Windows上のMobaXterm
cd /drives/c/Users/suzuki/Documents &&
find . -type f -exec md5sum {} \; > ./Documents.md5sum

#Linux
cd /data/tank/suzuki/Documents &&
find . -type f -exec md5sum {} \; > ./Documents.md5sum

テキストを整形してdiffを取る

正規表現置き換えでs/^([^ ]+) (.+)$/\2 \1/としてハッシュとファイル名をひっくり返します(ファイル名が先になるように)。その後、行をソートして、diffを取ります。

チューニング・障害対応

ARC(メモリキャッシュ)の設定

FreeNASではZFSを扱うとき8GBのメモリーを搭載していることを条件にしているようです。そのためここでは8GBからシステム用に1GB引いた7GBに設定しています。

状況確認

cat /proc/spl/kstat/zfs/arcstats #pがARCの使用量、c_maxが上限

上限設定

echo 7516192768 > /sys/module/zfs/parameters/zfs_arc_max #ARCの上限を7GBに設定

上限設定(永続化)

再起動しても上限設定が続くようにするには/etc/modprobe.d/zfs.confに下記の行を書き込みます。

echo 'options zfs zfs_arc_max=7516192768' > /etc/modprobe.d/zfs.conf

自動トリムをオンにする(デフォルトはオフ)

SSDでは基本的にオンにすべきです。Western DigitalのDM-SMRドライブはHDDながらトリムがサポートされていますが、データ損失の問題を軽減するために自動トリムはオフにすることが推奨されています。 Update: WD Red SMR Drive Compatibility with ZFS | TrueNAS Community

sudo zpool set autotrim=on <tankname>

ドライブによるトリムのサポート有無やトリムの実行状況を確認する

zpool status -t

zpool statusで一部のHDDがUNAVAILになったとき

ドライブ自体が/devから確認できるなら、下記で復旧できる場合があります。

sudo zpool online <tankname> /dev/disk/by-partuuid/<id>

cronで異常を通知

/etc/cron.hourly/zpool_statusに下記の内容でファイルを作成します。異常の際、標準出力に現状を出力します。標準出力があればメールが飛ぶようにcronを設定しておいてください。

#!/bin/bash
status=$(zpool status -x 2>&1)
if [ 'all pools are healthy' != "$status" -a 'no pools available' != "$status" ]; then
    echo $status
fi

ファイルを作成したら実行属性を付けます。

chmod u=rwx,g=rx,o=rx /etc/cron.hourly/zpool_status
19
24
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
19
24