Qiita Teams that are logged in
You are not logged in to any team

Log in to Qiita Team
Community
OrganizationAdvent CalendarQiitadon (β)
Service
Qiita JobsQiita ZineQiita Blog
21
Help us understand the problem. What is going on with this article?
@juze9

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

セットアップ

インストール(Ubuntu 20.04)

sudo apt install -y zfsutils-linux

HDD一覧確認

ls /dev/disk/by-id

/dev/disk/by-idで作成

パーティションテーブルを作成

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

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

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

idの一覧を取得

ls /dev/disk/by-id

/dev/disk/by-partuuidで作成

パーティションを作成

/dev/disk/by-idのとき同様にパーティションテーブルを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

partuuidの一覧を取得

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

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

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> #割り当て容量を制限できる

状況確認

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

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

sudo zfs get compressratio #圧縮率の確認
sudo 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

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

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

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
21
Help us understand the problem. What is going on with this article?
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
juze9

Comments

No comments
Sign up for free and join this conversation.
Sign Up
If you already have a Qiita account Login
21
Help us understand the problem. What is going on with this article?