Date: 2018.02.20
Home / NAS. / おうちで自作NAS - スナップショットを利用した外部バックアップ。
書こう書こうと思ってすっかり忘れていました。

おうちで自作NAS - 電源ユニット異常から始まり、ZFS mirrorからRAID-Zに再構築。」でデータ移行にも利用したバックアップの仕組みです。
ちょっと最近ネタもないし、突貫で書き起こしました。
(実際には次にやりたい事のネタは仕込み中ですが色々あってなかなか進んでないだけなんですが。)




FreeNASで外部バックアップと言えば、Web UIから操作できて公式的に実装されている仕組みとして「リプリケーション」と「rsync」があります。
ただ、これらはあくまでリモートの別ホストにバックアップを想定したものだし、かゆいところに手が届かない事も。

「リプリケーション」は細かい設定ができるようですが、定期的なスナップショットタスクを実施し、それをリモートホストに同期させておく機能で相手側もFreeNASである必要があります。
まあ、今回やろうとしている事のリモート版です。

「rsync」はまあ同一ホスト内でもできるけど、リモートホストへの送信だとrsyncを受けれる(sshが使える)ホストが必要。
差分転送や削除されたファイルをリモートからも削除する等、オプションで細かい事は対応可能だけど、rsync実行中に元のファイル変更ができてしまい、バックアップとしては如何なものかとなります。
また、コマンドを間違うと事故が起こる可能性が・・・

というわけで本題。
今回はFreeNAS単体で、安定して、差分バックアップができる。方法になります。

まず、これを実装するにはバックアップ先もFreeNAS上にデータセットとして登録する必要があります。
今回はUSB HDDをバックアップ先として使用していますが、もちろんSATA接続とかでも大丈夫です。

うちでは「Logitec HDDケース ガチャベイ LHR-2BRHU3」を手配して、交換で余ったディスク2本を再利用しました(笑)
Logitec HDDケース ガチャベイ LHR-2BRHU3
外箱のイラストは謎です。

このHDDケース、ハード側でもRAID機能(JBOD、RAID0、RAID1)が実装されてはいますが信頼性が???だし、HDDの障害検知がLEDのみになるしでシングルモード運用です。
そしてシングルモードにするとFreeNAS上ではHDDが2本見えるので、こっちでZFS Mirrorを組みました。
バックアップ用途なんで容量重視でストライピングもありかなとは思ったけど、HDDがいつ吹っ飛ぶかも分からないぐらい使いまわしてるのでとりあえずです。

で、データセット登録できたら準備完了。
ここからはssh接続し、コマンドラインで作業します。

まずはrootへ昇格。
% sudo su -

バックアップ元のスナップショットを取得します。
ここはWeb UIで ストレージ > ボリューム > ボリュームを表示 から対象のデータセットを選択して「スナップショットの作成」からも可能ですが、結局この後コマンド操作するのでコピペの関係からもこっちでやった方が楽です。
# zfs snapshot (バックアップ元ボリューム名)/(バックアップ元データセット名)@(スナップショット名)

例えば、ボリューム「NAS」上のデータセット「share」のスナップショットをスナップショット名「snap1」で取る場合は、
# zfs snapshot NAS/share@snap1
となります。

で、バックアップ先へのスナップショットからの初回バックアップ(リストアでもある)。
# zfs send (バックアップ元ボリューム名)/(バックアップ元データセット名)@(スナップショット名) | zfs receive (バックアップ先ボリューム名)/(バックアップ先データセット名)

先程のスナップショットを、ボリューム「USBHDD」上のデータセット「backup」にバックアップを行う場合は、
# zfs send NAS/share@snap1 | zfs receive USBHDD/backup
となります。

こんなエラーが出た場合は「zfs receive」に「-F」オプションを付ける必要があります。
cannot receive new filesystem stream: destination 'USBHDD/backup' exists
must specify -F to overwrite it
warning: cannot send 'NAS/share@snap1': signal received

# zfs send NAS/share@snap1 | zfs receive -F USBHDD/backup

これでゴリゴリとバックアップ先に書き込みが始まります。
初回なのでフルバックアップとなる為、データ容量によりますが結構時間がかかりますが、取得したスナップショットから送り込んでいるのでファイル操作も問題ないです。
ちなみに、この方法で行うとバックアップ先側にもスナップショットが登録されています。

で、次回以降のバックアップ。
スナップショット名を変えて取得しておきます。

そして以下の書式で実施します。
「zfs send」に「-I」で前回と最新のスナップショットを指定する事で、スナップショット間の差分バックアップができます。
# zfs send -I (バックアップ元ボリューム名)/(バックアップ元データセット名)@(前回のスナップショット名) (バックアップ元ボリューム名)/(バックアップ元データセット名)@(最新のスナップショット名) | zfs receive -F (バックアップ先ボリューム名)/(バックアップ先データセット名)

お決まりのふぉーえぐざんぷる。新たに取得したスナップショット名が「snap2」とした場合、
# zfs send -I NAS/share@snap1 NAS/share@snap2 | zfs receive -F USBHDD/backup
となります。

ここで注意点ですが、古い方のスナップショットがバックアップ先にも残っている必要があるので2世代は常にどちらにも残しておく事をオススメします。
バックアップ先のスナップショットから削除してしまったファイルの復元といった事も可能ですし。
スナップショットの特性上、溜めていったら溜めていったで変更点の記録分が増えてディスク消費が上がりますので、リソースと信頼性を考えながら運用するのがいいと思います。

後はこの仕組をスクリプト書いてCronで回すもよし、更にスナップショット部分は定期的なスナップショットタスクと組み合わせて実施するもよしです。
我が家では常時NAS上のファイルの変更が発生するような使い方していないし、無駄にディスクアクセスを発生させたりスナップショットが大量に溜まるのも避けたいので今はファイルの保管した時とかに手動で流してます。
まあ、スナップショットが溜まるについてはリストをコマンドで取得可能なので自動削除もスクリプトに組み込んでしまえばいいんですが。

あと、リストアしたい時はバックアップ時のコマンドを逆に流せばOKです。
もしくはバックアップ先ボリュームを共有かければ直接ファイル取り出しも可能です。
その他、CLIで辿っていけば削除されたファイルで過去スナップショットには残っているものもファイル操作可能です。
通常では隠しディレクトリ扱いになっていて全く見えませんが、「/mnt/(ボリューム名)/(データセット名)/.zfs/snapshot/」以下にスナップショット毎のディレクトがあります。

おまけ
FreeNASでUSB HDDを使用する際の注意点です。
実際にはボリュームが、ですが。
稼働中にボリュームのデタッチせずにUSB HDDが取り外されたり電源が落ちると、FreeNASの管理機能が死にます。
ネットワーク的には生きてて、共有領域も見えているのにWeb UIやsshでのアクセスができなくなります。
結果、リセットするしかなくなりますのでご注意を。
できれば電源ボタンでシャットダウンが走るようにしておいた方がいいですね。

【関連記事】
おうちで自作NAS - FreeNAS 関連記事一覧。


Secret

TrackBackURL
→https://000dandelion000.blog.fc2.com/tb.php/276-8ef6ecb1