Ubuntu Server 19.04 に ZFS を導入しRAID1を構成する

経緯

PCを自作NASに移行して半年弱、当時は予算の関係で保留にしていたが、そろそろHDD買い足してバックアップなども万全にしたい

当初はファイルシステムは無難にext4、マザーボードの機能でRAID1を組むつもりだったが、いろいろ調べた結果ZFSというファイルシステムを導入することにした。

理由としては

  • ファイルシステム自体がRAIDに対応
  • 透過圧縮、スナップショットなど便利機能多数
  • CPUやメモリを食うが、逆に考えれば自作NASのNASとしては無駄なスペックを活かせる

構成

ハード

<th style="text-align: center">
  品名
</th>
<td style="text-align: center">
  Ryzen2400G
</td>
<td style="text-align: center">
  Asus B450-i Rog strix
</td>
<td style="text-align: center">
  kingston KVR24N17S8/8
</td>
<td style="text-align: center">
  Corsair SF450 PLATINUM
</td>
<td style="text-align: center">
  WesternDigital WD40EZRZ-RT2
</td>
種類
CPU
M/B
メモリ
電源
HDD

ソフト

Ubuntu Server 19.04
smbサーバーとして稼働中

準備

外付けHDDにバックアップ

HDDの増設

手順

ZFS in Linuxのインストール

ubuntu19.04には公式のリポジトリに入っているらしく、普通にapt installでインストールできた。

$ sudo apt install --yes debootstrap gdisk zfs-initramfs

追加したHDDの確認

$ sudo fdisk -l

(中略)

Disk /dev/sda: 3.7 TiB, 4000787030016 bytes, 7814037168 sectors
Disk model: WDC WD40EZRZ-00G
Units: sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 4096 bytes
I/O size (minimum/optimal): 4096 bytes / 4096 bytes
Disklabel type: gpt
Disk identifier: CBCBA5BF-DD51-44FB-A592-E3579550A2C4

Device     Start        End    Sectors  Size Type
/dev/sda1   2048 6144002047 6144000000  2.9T Linux filesystem

Disk /dev/sdb: 3.7 TiB, 4000787030016 bytes, 7814037168 sectors
Disk model: WDC WD40EZRZ-00G
Units: sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 4096 bytes
I/O size (minimum/optimal): 4096 bytes / 4096 bytes

既存のHDDが/dev/sda、追加したHDDが/dev/sdb ということがとりあえずわかった。
ので、まず。/dev/sdbをgpt にしておく

$ sudo parted /dev/sdb
(parted) mklabel gpt

HDDのIDを確認する。
(/dev/sdaといった名前は起動の際に割り振られ、固定のものではないため)

$ ls /dev/disk/by-id/

HDD固有のIDはいくつか形式があるらしく、このコマンドの出力も一つのHDDに対し複数の名前がデてきた。
今回は以下の2つを使うことにした。

wwn-0x50014ee266279d3a  -> ../../sda
wwn-0x50014ee210f658e7 -> ../../sdb

zpoolの作成( RAIDなし)

zpoolのコマンドが使える事自体の確認も兼ねて、リストを出してみる。

$sudo zpool list 
no pools available

当然まだない

とりあえず試しにHDD1つで作ってみる

$ sudo zpool create tank  wwn-0x50014ee210f658e7

そしてリストを出力。

$ sudo zpool list
NAME   SIZE  ALLOC   FREE  EXPANDSZ   FRAG    CAP  DEDUP  HEALTH  ALTROOT
tank  3.62T   432K  3.62T         -     0%     0%  1.00x  ONLINE  -

$ sudo zpool status
  pool: tank
 state: ONLINE
  scan: none requested
config:

    NAME                      STATE     READ WRITE CKSUM
    tank                      ONLINE       0     0     0
      wwn-0x50014ee210f658e7  ONLINE       0     0     0

ついでにこの時点でパーティションどうなっているかも見てみた。

Disk /dev/sdb: 3.7 TiB, 4000787030016 bytes, 7814037168 sectors
Disk model: WDC WD40EZRZ-00G
Units: sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 4096 bytes
I/O size (minimum/optimal): 4096 bytes / 4096 bytes
Disklabel type: gpt
Disk identifier: 923EA8D0-BFE5-BE44-BFE7-C0B74BD4819E

Device          Start        End    Sectors  Size Type
/dev/sdb1        2048 7814019071 7814017024  3.7T Solaris /usr & Apple ZFS
/dev/sdb9  7814019072 7814035455      16384    8M Solaris reserved 1

HDDを指定してzpoolを作成するとパーティションは勝手に切ってくれるらしい。
8MB のパーティションがなんのためにあるのか気になるところだが、とりあえず今回はスルー

zpoolの削除

あとからミラーリング用にディスクを追加できるならそうしようかと思っていたのだが、この時点ではやり方が見つからなかったためはじめからミラーリングで作り直した。

$sudo zpool destroy tank

調べ直したら一応できるっぽい。
ストレージプール内でデバイスを接続する/切り離す

zpoolの作成(RAID1)

$ sudo zpool create tank  mirror wwn-0x50014ee266279d3a  wwn-0x50014ee210f658e7

ZFSの追加

$ sudo zfs create tank/home

設定の確認

重複排除

まず重複排除機能が無効化されていることを確認する。
面白そうな機能ではあるが今回はこれをやるにはスペックが全然足りないので。

$ zfs get dedup 
NAME              PROPERTY  VALUE          SOURCE
tank              dedup     off            default
tank/home         dedup     off            default

圧縮

スピードが要求される用途に関しては別にSSDを使う予定なので、今回は容量を重視し圧縮をする。

$ sudo zfs set compression=on tank/home

アクセスタイム

アクセスタイムについては、有効である必要もないが無効だと稀にエラーにつながるらしいので、折衷案的なrelatimeを採用。

$ sudo zfs set   atime=on tank
$ sudo zfs set relatime=on tank

デーモンの有効化

$sudo systemctl enable zfs.target
$sudo systemctl enable zfs-import-cache
$sudo systemctl enable zfs-mount
$sudo systemctl enable zfs-import.target

ちゃんと起動時にZFSがマウントされるか、再起動して確認

バックアップからファイルをコピーする

バックアップ用のHDDからZFSのディレクトリにコピーをする
(HDDは/media/hdd_backupにマウント、この中のhomeディレクトリからコピーする)

$ sudo rsync -avc /media/hdd_backup/home/ /tank/home/

コピー後、zfs listで確認したところ、ちゃんと1.26TB コピーされ、認識されている模様

$ zfs list
NAME               USED  AVAIL  REFER  MOUNTPOINT
tank              1.26T  2.25T   112K  /tank
tank/home         1.26T  2.25T  1.26T  /tank/home

結果

今の所とりあえずはちゃんと使えている。

参考

ZFS
ZFSの使い方
ZFSの基本的な使い方とZFSとEXT4のベンチマーク比較
Ubuntu 18.04 Root on ZFS