(2015.11 新規作成。)
FreeBSD 10.2-RELEASE で, 2台の間で, Continuous ZFS Replication をおこなう方法について。リアルタイムに連続してレプリケーションをおこなうのは、なかなか難しい。
ZFS は, copy-on-write の仕組みを持っていて, ファイルシステムの snapshot を一瞬で作ることができる。
snapshot を作っただけではディスク容量も消費しない。snapshot 作成後にファイルシステムの変更があると, そこでデータが複製される。
スナップショットの作成は zfs snapshot コマンド。
# zfs snapshot datatank/share@now # zfs list -t snapshot NAME USED AVAIL REFER MOUNTPOINT datatank/share@now 0 - 19.5K -
スナップショットは, 明示的にマウントしなくても,「マウントポイント/.zfs/snapshot/スナップショット名」でアクセスできる。
スナップショットを作った後, ファイル fuga
を作ってみる。その後, ls すると...
% ls -l /usr/home/share/u/ total 2 -rw-r--r-- 1 hori hori 5 11月 22 20:53 fuga -rw-r--r-- 1 hori hori 5 11月 22 20:51 hoge % ls -l /usr/home/share/.zfs/snapshot/now/u/ total 1 -rw-r--r-- 1 hori hori 5 11月 22 20:51 hoge
スナップショットのほうは、古い状態が表示される。
スナップショットの破壊は zfs destroy. 確認メッセージも何も表示されない。危ない。
# zfs snapshot datatank/share@s2 # zfs list -t snapshot NAME USED AVAIL REFER MOUNTPOINT datatank/share@now 9K - 19.5K - datatank/share@s2 0 - 21K -
# zfs destroy datatank/share@now # zfs list -t snapshot NAME USED AVAIL REFER MOUNTPOINT datatank/share@s2 0 - 21K -
単に zfs list ではスナップショットは表示されない。-t snapshot か -t all を付ける.
一つのファイルシステムのバックアップ。
リモート (バックアップ先) のほうで, sudo をインストール。
# pkg install sudo
ユーザが sudoers
になければならない。/usr/local/etc/sudoers
ファイルで設定。設定方法はこちら; FreeBSD 10.2: Linuxとの違いの気づき
ZFS は, スナップショットをストリームに出力できる。HEAD をいきなり送信することはできない。2 steps.
zfs send コマンドでスナップショットをストリーム送信し, zfs recv コマンドで受信する。
次の例は, スナップショット datatank/share@s2
を別ホスト 192.168.241.52 に送信し、そこでファイルシステムを再構築する。
# zfs send -p datatank/share@s2 | ssh zfsrecv@192.168.241.52 sudo zfs recv -u datatank/share
受信側には datatank
zpool が存在しなければならず, 逆に datatank/share ZFS が存在すると失敗する。成功すると, datatank/share
ZFS とスナップショット datatank/share@s2
が作られる。
受信側の引数が, スナップショット名ではなく ZFS 名になっているのが, 紛らわしい。
zfs send の -p オプションでプロパティがコピーされることになっているが、atime はコピーされない。全部がコピーされるわけではないようだ。
zfs recv の -u オプションで, 自動マウントされない。基本的にいつでもこのオプションを指定する。--ならデフォルトにしてほしい。
ZFSのファイルシステムは, zroot/usr
, zroot/usr/home
, ... のように, 名前上, 親子関係を持てる。
ファイルシステムの中身のデータ(ファイル)が共有されるわけではなく、プロパティが親から継承される。
zfs snapshot -r オプションで, 子孫も含めたデータセットのスナップショットを作る。mountpoint ではなく, ZFS名で子孫の方向にまとめて, という点に注意。
# zfs snapshot -r myzpool/fs@snap1
子孫もまとめてストリーム送信するには, zfs send -R とする。
# zfs send -R myzpool/fs@snap1
send -R の場合は, 受信側では recv -d とする.
2回目以降は, 差分だけを送信するようにする。zfs send のオプションに -I と -i があって, ややこしい。
バックアップ用途では, 大文字の -I を使うこと。
recv のほうは, -d -F を付けて,
# zfs recv -d -F pool/fs
レプリケーションを自動化するには, 車輪の再発明はせずに, 支援ツールを使うのがいい。
pkg search zfs ぐらいで表示すると, いろいろある;
zfs-periodic-1.0.20130213 | Simple way of maintaining zfs snapshots using the periodic system. -- Webサイトが消失していて, メンテされていないか? |
zfs-replicate-0.7_1 | ZFS Snapshot Replication Script |
zfs-snapshot-clean-0.2.0 | Tool to sieve ZFS snapshots as per given spec a la 'pdumpfs-clean'. -- pdumpfs は Plan9 の dumpfs モドキ? |
zfs-snapshot-mgmt-20090201_2 | Automatic ZFS snapshot management tool |
zfsnap-1.11.1 | Simple sh script to make zfs rolling snaphosts with cron. -- Webサイト: zfsnap/zfsnap ・ GitHub |
zfstools-0.3.6 | OpenSolaris-compatible auto snapshotting for ZFS -- Webサイト: bdrewery/zfstools ・ GitHub; Rubyで作られている. => レプリケーションはscope 外か? |
どれがいいのかなぁ.
ほかにもいくつかある;
(2016.11) Rudd-O氏のリポジトリのほうが開発が進んでいる。バグfixもされている。
pkgパッケージのはどれも違うようだ。zfs-tools (ハイフンが入っているほう) か zrep が良さそうに見える。
以下では, パックアップ元を master, バックアップ先を backup 機という。
zfs-tools は ZFS on Linux を重視しているみたい。
master 側に bash
と sudo
コマンドが必要。'bash
' package, 'sudo
' package をインストールしておく.
master機, backup機の両方で, 上の github から git clone する。
バグがあるので, 少し修正. (2016.11) Rudd-O氏のリポジトリでは修正ずみ。
root になって, python setup.py install.
zfs-tools の zreplicate コマンドは pull 型. master機のほうに専用のユーザを作る.
README.md の手順は FreeBSDではない。標準コマンドのオプションが違う。Linux のようだ。
/etc/shells
ファイルに /usr/local/bin/zfs-shell
を追加する。
ユーザを追加。su はしないので, wheel
グループには参加させない.
# adduser Username: zfssend Full name: ZFS replication sender Uid (Leave empty for default): Login group [zfssend]: Login group is zfssend. Invite zfssend into other groups? []: Login class [default]: Shell (sh csh tcsh git-shell zfs-shell nologin) [sh]: zfs-shell Home directory [/home/zfssend]: /var/lib/zfssend Home directory permissions (Leave empty for default): Use password-based authentication? [yes]: no Lock out the account after creation? [no]: Username : zfssend Password : <disabled> Full Name : ZFS replication sender Uid : 1002 Class : Groups : zfssend Home : /var/lib/zfssend Home Mode : Shell : /usr/local/bin/zfs-shell Locked : no OK? (yes/no): yes adduser: INFO: Successfully added (zfssend) to the user database.
/usr/local/etc/sudoers
ファイルを編集し, パスワードなしで sudo して /sbin/zfs
'だけ'が実行できるようにする。
zfssend ALL= NOPASSWD: /sbin/zfs
root から su zfssend list して, 動くか確認。
README.md は, 単に SSHのための公開鍵認証, で済ましている。backup機からmaster機にログインするので, backup機で鍵ペアを作って, うち公開鍵を master に保存する。
# ssh-keygen -t rsa
パスワードは空 (no passphrase) にする。
scp コマンドで, 公開鍵をmaster機へ. /var/lib/zfssend/.ssh/authorized_keys
ファイルとして保存。
backup機からmaster機に, パスワードなしで zfssend としてログインできるか, 確認
1) master機でスナップショットを取る.
# zsnap datatank/share
スナップショットができているか。
# zfs list -t all NAME USED AVAIL REFER MOUNTPOINT datatank 146K 9.63G 19K none datatank/share 21.5K 9.63G 21.5K /usr/home/share datatank/share@autosnapshot-2015-11-26-220419 0 - 21.5K - zroot 5.03G 12.3G 96K none 以下略
うまくいったか分かりやすいように, /usr/home/share 以下に, 何かファイルを作っておく.
2) backup機では, 'datatank/share' ZFS を作っておく. destination dataset がないと, zreplicate が失敗する。
atime は off にしておく。
backup機のほうで zreplicate を実行。192.168.241.51 は master のIPアドレス.
# zreplicate -v zfssend@192.168.241.51:datatank/share datatank/share Replicating dataset zfssend@192.168.241.51:datatank/share into localhost:datatank/share... Assessing that the source dataset exists... Assessing that the destination dataset exists... ================================= Replicating (full_recursive) datatank/share to datatank/share Base snapshot available in destination: None Target snapshot available in source: <Snapshot: datatank/share@autosnapshot-2015-11-26-221849> send from @ to datatank/share@autosnapshot-2015-11-26-221849 estimated size is 11.5K total estimated size is 11.5K TIME SENT SNAPSHOT receiving full stream of datatank/share@autosnapshot-2015-11-26-221849 into datatank/share@autosnapshot-2015-11-26-221849 received 46.8KB stream in 2 seconds (23.4KB/sec) ================================= Replication complete.
できたか確認。
# zfs list -t all NAME USED AVAIL REFER MOUNTPOINT datatank 156K 9.63G 19K none datatank/share 21.5K 9.63G 21.5K /usr/home/share datatank/share@autosnapshot-2015-11-26-221849 0 - 21.5K - zroot 5.02G 12.3G 96K none 以下略
受け側の /usr/home/share には, master機の HEAD のファイルがない。つまり, スナップショットの状態と一致しているはず。
3) もう一度 master でスナップショットを作る。
# zsnap datatank/share
4) backup機で zreplicate.
# zreplicate -v zfssend@192.168.241.51:datatank/share datatank/share Replicating dataset zfssend@192.168.241.51:datatank/share into localhost:datatank/share... Assessing that the source dataset exists... Assessing that the destination dataset exists... ================================= Replicating (incremental_recursive) datatank/share to datatank/share Base snapshot available in destination: <Snapshot: datatank/share@autosnapshot-2015-11-26-221849> Target snapshot available in source: <Snapshot: datatank/share@autosnapshot-2015-11-26-222430> send from @autosnapshot-2015-11-26-221849 to datatank/share@autosnapshot-2015-11-26-222430 estimated size is 5.50K total estimated size is 5.50K TIME SENT SNAPSHOT receiving incremental stream of datatank/share@autosnapshot-2015-11-26-222430 into datatank/share@autosnapshot-2015-11-26-222430 received 11.0KB stream in 1 seconds (11.0KB/sec) ================================= Replication complete.
できた!!!