ZFSパッケージ登録記念:Ubuntu 15.10にZFS on Linux

目次
  • ZFS on Linux のパッケージが Ubuntu 15.10 の universe に登録された。
  • Ubunut 15.10 に ZFS on Linux をインストールしてみた。

この春、Debian で ZFS on Linux(ZoL)(注 1)が近々サポートされるというニュースが流れました(注 2)。しかし結局サポートされるようになったのかどうか、全く話を聞かなくになってしまいました。

そして秋には Ubuntu で ZFS が使えるようになるというニュースが流れました(注 3)。この時は 2016 年春にリリース予定の Ubuntu 16.04 での話でした。そのため Ubuntu で使えるようになったとしてもまだ先の話かと思っていました。

ところが先日 ZFS on Linux メーリングリストに「Ubuntu のパッケジレポジトリに ZoL がある」(注 4)があるという話が投稿されました。それを読んで Ubuntu のパッケージを検索するとこの秋にリリースされた Ubuntu 15.10 用の ZoL パッケージが見つかりました(注 5)。これまでも ZoL を PPA から Ubuntu にインストール出来ました(注 6)が、公式のパッケージとして ZoL が登録されたことは大進歩です。これで OS をアップグレードするときに ZFS のカーネルモジュールがインストールされているか心配しなくて良くなります。

これまで PPA のパッケージを使って ZoL をインストールしていましたが、せっかくなので新しく登録された ZFS on Linux のパッケージを Ubuntu 15.10 にインストールしてみました。

ZFS on Linux を使えるマシンの条件

ZFS on Linux を使用するには、次のような必要条件が有ります。

64-bit Ubuntu システムであること。
32-bit 用のパッケージは提供されていません。 最近 Ubuntu をインストールしたマシンは、サーバ用とデスクトップ用共に標準で 64-bit になっているのでこの条件は問題ありません。ただしアップグレードを繰り返してきたマシンは 32-bit のシステムかもしれません。

64-bit か 32-bit かは、uname -iコマンドで確認できます。コマンドの出力がx86_64となっていれば 64-bit システムです。

# 64-bit
uname -i
x86_64

# 32-bit  uname -i
i686
メモリが 8GB 以上あること。
もっと少ないメモリ容量でも重複排除を使用しなければ動くことは動くらしいです。逆に重複排除を使用するならば、8GB では少なすぎます。またメモリは読み出しキャッシュともなるので、実用上はさらにほしい所です。 また普通のメモリでも ZFS を使用できますが、データを絶対失いたくない用途では ECC 付きのメモリが強く推奨されています(注 7)。

ZFS で ECC 付きメモリがどの程度必須かは、ヒートアップ間違い無しの話題です。ECC が付いていない普通のメモリを使っていると、 知らないうちにファイルが壊れる、最悪ファイルシステム全体が壊れることがある という恐ろしい意見を良く見かけます。ただ一方で ECC 付きメモリでなくて安全性に違いはない という意見も有ります(注 8)。

ECC 付きのメモリを使っておけば、ファイルが壊れた時に本当は別に原因があったとしても ECC 付きのメモリにしておかなかったからかもと後悔をしなくてすみます。ちなみに私は、ホーム・ファイル・サーバに ECC の付いていない普通のメモリを使用しています。

ZFS on Linux をインストール

今回は KVM 上で動いている Ubuntu 15.10 マシンに ZFS on Linux をインストールしてみました。

OS
Ubuntu 15.10 64-bit
メモリ
8GB(8192MB)
ドライブ
5GB + ZFS 用に 5GBx2 ZFS に使用するドライブには、Virttual Disk の Advanced options で Serial number を書いておきます。今回は、virtio-drive1virtio-drive2としました。こうすることで、後でドライブが識別しやすくなります。 KVMのVirtual DiskにSerial numberを設定する。
$ ls /dev/disk/by-id/
ata-QEMU_DVD-ROM_QM00001  virtio-ubuntu-drive0-part1  virtio-virtio-drive3
virtio-ubuntu-drive0      virtio-virtio-drive2

ドライバ名が頭に付くことを忘れていた。

仮想環境でない本物のドライブでは、次のようにモデル名とシリアル番号から自動的に設定されています。また同じドライブに対して、WWN(注 9)からも名前が付けられます。 モデル名とS/N、WWNからデバイス名が作成される。

$ ls /dev/disk/by-id/
usb-ST310005_9VPC_246802468024-0:0
usb-ST310005_9VPC_246802468024-0:0-part1
usb-ST310005_9VPC_246802468024-0:0-part2
# 省略

USB 接続だからか WWN での名前がこの時は作られませんでした。SATA で接続するとwwn-0x5000c50017ffe14fのような wnn で始まる WWN に由来する名前も作成されます。

ZoL は複数ののパッケージに分割されていますが、zfsutils-linuxをインストールすると必要なパッケージが全てインストールされます。ただし現時点ではパッケージの依存関係にバグがあるのか ZFS on Linux のカーネルモジュールをインストールする時に必要なbuild-essentialパッケージがインストールされません(注 10)。そこでこれも同時にインストールします。

$ sudo apt-get update
$ sudo apt-get install build-essential zfsutils-linux

普通のパッケージはファイルをコピーするだけですが、ZoL はカーネルモジュールをコンパイルしてインストールする必要があります。そのためインストールが完了するまで多少時間がかかります。

インストールが完了したら、ZFS が使えるようになっているか確認します。

$ cat /proc/filesystems |grep zfs
nodev	zfs

$ dmesg | grep -E 'SPL:|ZFS:'
[  848.530602] SPL: Loaded module v0.6.4.2-0ubuntu1
[  848.566350] ZFS: Loaded module v0.6.4.2-0ubuntu1.2, ZFS pool version 5000, ZFS filesystem version 5

ZFS を使ってみた

ZFS が使えることが確認できたら、ミラーリング(mirror, RAID1)で冗長化した ZFS を作って/homeに使用してみます(注 11)。

ZFS を使うには、まず複数のドライブをまとめて冗長性を持った一つの記憶システム pool を作成し、次に pool を分割してユーザが使用できるファイルシステムを作ります。

pool の作成

まずドライブと対応するデバイス名を確認します。

$ ls -l /dev/disk/by-id
lrwxrwxrwx 1 root root  9 12月 29 08:12 ata-QEMU_DVD-ROM_QM00001 -> ../../sr0
lrwxrwxrwx 1 root root  9 12月 29 08:12 virtio-ubuntu-drive0 -> ../../vda
lrwxrwxrwx 1 root root 10 12月 29 08:12 virtio-ubuntu-drive0-part1 -> ../../vda1
lrwxrwxrwx 1 root root  9 12月 29 08:12 virtio-virtio-drive2 -> ../../vdb
lrwxrwxrwx 1 root root  9 12月 29 08:12 virtio-virtio-drive3 -> ../../vdc

今回 ZFS に使用するドライブが vdb と vdc に接続していることがわかりました。このデバイス名は初期化するときにだけ必要で、以後は分かりやすい by-id で示された名前が使用できるようになります。(本当は最初から by-id の名前を使えるはずですが…。)

pool の作成には、zpoolコマンドを使用します。

$ sudo zpool create -o ashift=12 tank mirror vdb vdc
$ sudo zpool status
  pool: tank
 state: ONLINE
  scan: none requested
config:

	NAME        STATE     READ WRITE CKSUM
	tank        ONLINE       0     0     0
	  mirror-0  ONLINE       0     0     0
	    vdb1    ONLINE       0     0     0
	    vdc1    ONLINE       0     0     0

errors: No known data errors

$ sudo zpool list
NAME   SIZE  ALLOC   FREE  EXPANDSZ   FRAG    CAP  DEDUP  HEALTH  ALTROOT
tank  4.97G   360K  4.97G         -     0%     0%  1.00x  ONLINE  -

ドライブがまっさらでパーティションテーブル自体がないときにはエラーになるので、pool を作成するときに-fオプションを追加します。

-o ashift=12オプションは、4KB セクタのドライブに対応するためで、2^12(4096)バイトを単位としてデータを配置させます。

pool の名前を tank としましたが、この名前は/(root)ディレクトリに無い名前であれば自由に決めることができます。

pool を構成するストレージには、ドライブ丸ごとではなく特定のパーティションを指定することも可能です。ただしドライブ丸ごとのほうが効率が良いということです。

これで pool の準備は完了です。しかしこれでは障害が発生した時にどのドライブを交換したらよいか分かりにくく、間違ったドライブを交換してしまいそうです。

そこでdisk/by-idで示された分かりやすい名前を使えるようにします。

$ sudo zpool export tank
$ sudo zpool import -d /dev/disk/by-id tank
$ sudo zpool status
  pool: tank
 state: ONLINE
  scan: none requested
config:

	NAME                      STATE     READ WRITE CKSUM
	tank                      ONLINE       0     0     0
	  mirror-0                ONLINE       0     0     0
	    virtio-virtio-drive2  ONLINE       0     0     0
	    virtio-virtio-drive3  ONLINE       0     0     0

errors: No known data errors

これで将来障害が発生したとしても、交換が必要なドライブを間違える心配が減ります。

異なるサイズのドライブの組み合わせ

サイズが異なるドライブ(またはパーティション)を組み合わせた場合は、もっとも容量の小さいドライブに合わせて pool が作成されます(注 12)。

また将来ドライブが壊れた時には、壊れたドライブと同じかより大容量のものと交換する必要が有ります。ドライブを交換して最も容量の小さかったドライブが置き換わると、自動的に pool のサイズが拡張されます。

例えば、500GB + 500GB(500GB)のミラーリングされた pool のドライブ一台を 1TB のドライブと交換したとします。すると 500GB + 1TB という構成になりますが、この時の pool 容量は 500GB のままです。さらに 500GB のドライブを 1TB のと交換すると 1TB + 1TB となり、pool の容量は自動的に 1TB となります。

ただし容量に空きがあっても小さいサイズのドライブに交換することはできません(注 13)。

ファイルシステムの作成

pool を作成したらファイルシステムを作成して使用できるようにします。

と言っても実は pool を作成しただけでファイルシステムが作られて/(root)にマウントされています。そのため pool の名前に「/(root)ディレクトリに無い名前」という制限があったのです。

$ df -h
Filesystem      Size  Used Avail Use% Mounted on
# 省略
tank            4.9G  128K  4.9G   1% /tank

dfコマンドで使用量がわかるのが ZFS の便利なところです。

/home を ZFS にする

このままどんぶり勘定的に使用することも可能ですが、一般的にはこの領域をzfsコマンドで分割して使用します。

ここでは/home を ZFS 上に作成して、ドライブが一台壊れてもデータを守れるようにしてみます。

$ sudo zfs create -o atime=on -o relatime=on -o compression=lz4 tank/home
$ sudo zfs list
NAME        USED  AVAIL  REFER  MOUNTPOINT
tank        396K  4.89G    96K  /tank
tank/home    96K  4.89G    96K  /tank/home

これで新しい/home となるファイルシステムが出来ました。

zfsコマンドの-o atime=on -o relatime=onオプションは、ファイルアクセス時刻の記録方法を ext4 のデフォルトと同じにするためです。また-o compression=lz4オプションは、データを lz4 で圧縮して記録することを指示しています。

新しいファイルシステムができたので、これまでの/home を移動させて/home を切り替えます。

$ sudo rsync -a /home/ /tank/home
# /home/とソースはスラッシュ(/)で終わっている必要がある。
$ ls /tank/home/
# 全てのユーザディレクトリが表示されるはず。

$ cd /
$ /homeを外部メディアにバックアップ
$ sudo rm -r /home/*
$ sudo zfs set mountpoint=/home tank/home
$ sudo zfs list
NAME        USED  AVAIL  REFER  MOUNTPOINT
tank        448K  4.89G    96K  /tank
tank/home   124K  4.89G   124K  /home

$ ls /home/
# 以前と同じく全てのユーザディレクトリが表示されるはず。

$ df -h
Filesystem      Size  Used Avail Use% Mounted on
# 省略
tank            4.9G  128K  4.9G   1% /tank
tank/home       4.9G  128K  4.9G   1% /home

再起動して問題なければ、バックアップを削除します。

$ sudo rm /tank/home.tgz

参照と脚注

  1. ZFS on Linux これまでも ZFS は、FUSE ではサポートされていました。
  2. ZFS & Libdvdcss Should Soon Be In Debian – phoronix Debian Is Still Working To Tackle ZFS On Linux Support – phoronix
  3. 2015 年 10 月 9 日号  ZFS と Ubuntu・UWN#436 – Ubuntu Weekly Topics
  4. [zfs-discuss] ZoL available on the Ubuntu repositories
  5. Ubuntu パッケージ検索結果
  6. ZFS Stable Releases for Ubuntu
  7. Do I have to use ECC memory for ZFS? – ZFS ON LINUX FAQ
  8. 第 7 回  ZFS ベストプラクティス-FreeBSD Journal March/April 2015 – BSD 界隈四方山話
  9. WWN は、World Wide Name の略。World Wide Name – ウィキペディア
  10. 本来必要なパッケージは全てインストールされるはずですが、 zfs-dkms is missing dependency on build-essential – Ubuntu zfs-linux package bugs
  11. ZFS では、ミラーリングの他に raidz1(RAID5 相当)と raidz2(RAID6 相当)を冗長化に使用できます。
  12. ドライブ 2 台のミラーリングでは差が現れませんが、Btrfs は容量が異なるドライブを組み合わせても、できるだけ無駄のない pool を作成してくれます。btrfs disk usage calculator
  13. Btrfs は、使っている容量が収まれば小さい容量のドライブに置き換えることができるそうです。