ZFSのスナップショットマネージャー Sanoidを使う

8月 6, 2018 Computer, Linux

(Last Updated On: 2018/10/19)

ZFSにはスナップショット管理機能があります。スナップショットは便利です。自前スクリプトでも管理できますが管理ツールがある方が便利です。

Sanoidの機能

  • スナップショットの作成と削除(sanoidコマンド)
  • ZFS send/recieveを利用したローカル/リモートバックアップ(syncoidコマンド)

実際にはもう一つ、findoidというコマンドもあります。使っていないのでここでは省略します。

参考:

RPMパッケージの作成

GitHubのリポジトリにはRPMのspecファイルが付いています。RPMを使っているディストリビューションだとRPMパッケージを作った方が便利です。(debパッケージ定義もあります)

specだけでも簡単にビルドできます。基本的には以下のコマンドを実行するだけです。

$ spectool -g -R /path/to/your/sanoid.spec
$ rpmbuild -ba /path/to/your/sanoid.spec

ビルドツールがインストールされていれば、この2つコマンドでRPMが作られます。(x86_64のデフォルトだと~/rpmbuild/RPMS/x86_64/) dnf/yumかrpmでインストールできます。

Sanoidの設定

sanoidコマンドは設定に応じてスナップショットを取得&削除するツールです。

sanoidコマンドの実行にはsanoid.confが必要です。RPMでインストールした場合、/etc/sanoid/sanoid.confを作成する必要があります。

 https://github.com/jimsalterjrs/sanoid

のREADME.mdにサンプルが記載されています。初めて使う場合、設定項目が何かよく分らないと思います。

[data/home] <= ZFSファイルボリューム名
    use_template = production <= 使用するテンプレート名(下で定義)

[data/images]
    use_template = production
    recursive = yes <= ZFSボリュームの中にボリュームが在る場合、再帰的にスナップショットを取得
    process_children_only = yes <= 子のボリュームのみ処理

[data/images/win7]
    hourly = 4 <= テンプレートの毎時スナップショット保持数を変更

# templates below this line
[template_production] <= "production"がテンプレート名になる
       hourly = 36 <= 毎時スナップショットを36個保持、それ以上は削除
       daily = 30 <= 日時スナップショットを30個保持、それ以上は削除
       monthly = 3 <= 月次スナップショットを3個保持、それ以上は削除
       yearly = 0 <= 年次スナップショットを0個保持、それ以上は削除
       autosnap = yes <= 自動的にスナップショットを取得(syncoidなどで他のZFSスナップショットをsend & receive した場合、スナップショットを取る必要がない)
       autoprune = yes <= スナップショット保持数設定通りに自動的にスナップショットを削除

hourly, daily、 monthly, yearly設定を0にした場合の意味は設定によって異なるようです。0にしたら全て削除される場合と1にしないと古いスナップショットが削除されない場合があります。バグっぽい(?)ので細かい動作仕様は省略します。

sanoidはcronで動作させます。GitHubのページでは毎分sanoid –cronを実行させる設定が紹介されています。毎時以上に細かいスナップショットは取れないので/etc/cron.hourlyにsanoidを実行するシェルスクリプトを登録した方が良いでしょう。

#!/usr/bin/env bash

export TZ=UTC 
/usr/sbin/sanoid --cron

日本にはサマータイムがありませんが、基本的にはUTCで管理することをお勧めします。表示された時間に+9時間するだけです。

他のオプションなどは sanoid –help で表示できます。

Syncoidの設定

syncoidはローカル/リモートのZFSスナップショットをZFSボリュームのsend / recieve機能を使ってコピーします。つまり他のZFSファイルシステムのスナップショットと同期します。

syncoidはコマンド単体で利用するよう設計されています。rsync風の形式で送信元/送信先を指定できます。以下のような感じで使います。

#!/usr/bin/env bash

export TZ=UTC <= 基本UTCをお勧めします
OPT='--no-sync-snap' <= 同期時に新しいスナップショットを作らない

# Local host
syncoid $OPT pool/vol    backup-pool/local-vol

# Remote host1
syncoid $OPT root@host1:pool/vol  backup-pool/host1-vol

# Remote host2
syncoid $OPT root@host2:pool/vol  backup-pool/host2-vol

syncoidは”自動的にバックアップ先のZFSボリュームを作成”します。既に存在する場合はエラーになります。予め作らないようにします。タイポなどのミスがあると訳けが分らないエラーになります。タイポしないように注意します。

上のスクリプトを/etc/cron.daily/syncoid などとして保存し、定期的に実行します。

古いスナップショットの自動削除はsanoidで行います。

他のオプションなどは syncoid –help で表示できます。

問題など

スナップショットをマウントするとリードオンリーでマウントされますが、マウントしたままにしているとZFSのスナップショットのsend/recieveで問題が起きるようです。recieve先のZFSボリュームをzfs destroy -R pool/volumeで削除すると同期可能になります。基本、スナップショットはマウントしたままにしない方が良いでしょう。

まとめ

バックアップ履歴の管理はディスク容量も必要ですし、真面目かつ細かく履歴を取るのも面倒です。しかし、ZFSとスナップショットを使うと簡単かつ効率的に管理できます。

スナップショットの欠点はローカル/同じファイルシステムだけに保存していても、バックアップの代わりにならない、ことです。ZFSの send / receiveを使えばこの問題も解決できます。

今まで自前の貧弱なスクリプトを使っていましたが、ディスク容量が足りなくなったことをきっかけにsanoidを使うようにしまし。前より良い感じになりました。

因みにZFS on Linuxは安定している & Fedoraのようにカーネルバージョンアップが激しいディストリビューションでも、ほぼ問題なく使えています。時々ZFSカーネルモジュールのバージョンアップがカーネルのマイナーバージョンアップに間に合わない場合があります。バージョンが上がった時には少し注意が必要です。

総合的にはZFS on Linux、お勧めです。CentOSでも安定しています。

一つだけ困っている問題はdockerをZFS上で使うと、時々コンテナ上かホスト上で起動していたコマンドがファイルシステムを握ったような状態になることです。lsofや/procの中を見ても何もないのに、dockerが使っているZFSボリュームが削除できなくなり、再起動が必要になることです。これ以外は問題らしい問題はありません。

投稿者: yohgaki