rsnapshot

提供: ArchWiki
2023年12月9日 (土) 00:33時点におけるKgx (トーク | 投稿記録)による版 (→‎自動化: 外付けドライブを翻訳して追加)
(差分) ← 古い版 | 最新版 (差分) | 新しい版 → (差分)
ナビゲーションに移動 検索に移動

Rsnapshot は差分バックアップを行うためのオープンソースユーティリティです。

インストール

公式リポジトリから rsnapshot をインストールしてください。

設定

インストール時に、設定ファイルが作成されます。ファイルを再設定するときに備えて、設定ファイルはバックアップを作成することを推奨します。

# cp /etc/rsnapshot.conf /etc/rsnapshot.conf.default

/etc/rsnapshot.conf ファイルには豊富にコメントが付いており見ればすぐに設定することができます。様々なオプションの完全なリファレンスが見たいときは、rsnapshot の man ページを読んでください。

ルートディレクトリ

ファイルシステムのバックアップを保存したいディレクトリを選択してください。以下の例ではバックアップを /mnt/backups/ に保存しています。

/etc/rsnapshot.conf
# All snapshots will be stored under this root directory.
#
snapshot_root   /mnt/backups/
ノート: フィールドを区切るのはタブです。空白ではありません。タブで区切ることになっているので、ファイルパスに空白が入っていても簡単に指定することができるようになっています。

外部プログラムの依存関係

unix コマンド cp, du, ssh (遠隔バックアップをする場合), rsnapshot-diff などのパスを指定している行をアンコメントしてください。ファイルのこのセクションは以下のようにします:

/etc/rsnapshot.conf
# LINUX USERS:   Be sure to uncomment "cmd_cp". This gives you extra features.
# EVERYONE ELSE: Leave "cmd_cp" commented out for compatibility.
#
# See the README file or the man page for more details.
#
cmd_cp          /usr/bin/cp

# uncomment this to use the rm program instead of the built-in perl routine.
#
cmd_rm          /usr/bin/rm

# rsync must be enabled for anything to work. This is the only command that
# must be enabled.
#
cmd_rsync       /usr/bin/rsync

# Uncomment this to enable remote ssh backups over rsync.
#
cmd_ssh /usr/bin/ssh

# Comment this out to disable syslog support.
#
cmd_logger      /usr/bin/logger

# Uncomment this to specify the path to "du" for disk usage checks.
# If you have an older version of "du", you may also want to check the
# "du_args" parameter below.
#
cmd_du          /usr/bin/du

# Uncomment this to specify the path to rsnapshot-diff.
#
cmd_rsnapshot_diff      /usr/bin/rsnapshot-diff

# Specify the path to a script (and any optional arguments) to run right
# before rsnapshot syncs files
#
#cmd_preexec    /path/to/preexec/script

# Specify the path to a script (and any optional arguments) to run right
# after rsnapshot syncs files
#
#cmd_postexec   /path/to/postexec/script
ノート: cmd_preexec と cmd_postexec は rsnapshot の前後に実行されるカスタムスクリプトです。

前のバックアップの保存

Rsnapshot ではバックアップレベルに名前を付けて指定した数だけバックアップを保存することができます。

バックアップの保存を設定した場合、ファイルシステムから実際にファイルがバックアップされるのはリストの一番最初だけで、前のバックアップがローテートされます。後は前のバックアップがローテートされるだけで、リストの前のアイテムから作成された最古のバックアップから最新のバックアップが作成されます。そのため、設定ファイルのリストの順番はとても重要になります。

rsnapshot 設定ファイルのデフォルトの "BACKUP LEVELS / INTERVALS" セクションを置き換えて下さい:

/etc/rsnapshot.conf
retain  hourly  24
retain  daily   7
retain  weekly  4
retain  monthly 12
  • rsnapshot hourly が呼ばれた時、新しいバックアップがファイルシステムから作成されて、<snapshot_root>/hourly.0/ に保存されます。後のバックアップは全てコマンドが実行される度に差分で作られます。したがって、<snapshot_root>/hourly.0 だったものは <snapshot_root>/hourly.23/ になります。そしてコマンドが次に実行されると、バックアップは削除されます。
  • rsnapshot daily が呼ばれた時、<snapshot_root>/hourly.23/ バックアップから <snapshot_root>/daily.0/ が作成されます (バックアップが存在する不場合)。それ以外は、同じようにローテーションが行われます。
  • 同じく、rsnapshot weekly が呼ばれた時、<snapshot_root>/daily.6/ バックアップから <snapshot_root>/weekly.0/ が作成されます。設定された retain のレベルだけ同じことが繰り返されます。

上記の設定なら、以下のように実行します:

rsnapshot hourly 毎時

rsnapshot daily 毎日

rsnapshot weekly 毎周

rsnapshot monthly 毎月

これにより、古いスナップショットで容量が食われるのを最小限に抑えつつ12ヶ月分ものバックアップを保存することが可能です。

上記と同じ設定で、毎日のバックアップだけを行いたい場合、hourly のバックアップレベルをコメントアウトしてください。リストの最初のアイテムじゃなくなれば rsnapshot daily を呼び出しても何のファイルもバックアップされなくなります。

バックアップ

バックアップしたいファイルを rsnapshot に指定するセクションです。先に backup パラメータを記述してから、バックアップしたいディレクトリのフルパスやネットワーク上のパスを続けてください。3番目のカラムにはバックアップを保存するスナップショットのルートからの相対パスを指定します。

/etc/rsnapshot.conf
###############################
### BACKUP POINTS / SCRIPTS ###
###############################

# LOCALHOST
backup  /home/          localhost/

上記の例では、backup でバックアップ地点を指定しています。/home/ がスナップショットを取得するディレクトリのフルパスで、localhost/snapshot_root の中に保存するディレクトリです。保存先ディレクトリに localhost という単語を使っているのはただの例です。localhost の代わりにサーバーの完全修飾ドメイン名を使うこともできます。複数のマシンのスナップショットを単一のバックアップ専用サーバーに保存する場合、ファイルがどのサーバーからのものなのかわかるようにマシンのホスト名をディレクトリ名として使うと良いでしょう。

リモート環境

ローカルのファイルシステムのフルパスを指定するだけでなく、SSH による rsync を使ってリモートマシンをバックアップすることも可能です。cmd_ssh パラメータで ssh をインストール・有効化している場合、以下のようにパスを指定できます:

/etc/rsnapshot.conf
###############################
### BACKUP POINTS / SCRIPTS ###
###############################

# example.com
backup      root@example.com:/etc/     example.com/

上記の設定で同じようにバックアップが取られますが、特別に考慮するべきことがいくつか存在します:

  • example.com で ssh デーモンが動作している必要があります。
  • 指定したリモートマシンのアカウントにアクセスできる必要があります。上記の例なら example.com の root ユーザーです。
  • example.com の root ユーザー、公開鍵認証を有効にして、パスワードを入力しなくてもログインできるようにする必要があります。他のユーザーでバックアップを実行したい場合、root の代わりに他のユーザーをソースに指定してください (例: user@domain.com)。パスワードを入力しなくてもリモートログインできるようにすることは、場合によってはセキュリティ上のリスクとなり得ます。バックアップサーバーへのアクセスは注意深く守るようにしてください。セットアップ方法の詳しい情報は、ssh の man ページや、ssh の公開鍵・秘密鍵を使用するチュートリアルを読んでください。rsnapshot のためだけというだけなく、セキュリティと利便性を高めることについて大抵は公開鍵認証は良い認証方法です。クライアントマシンに uid と gid を 0 に設定した別のユーザーを作成することでバックアップサーバーからの被害を抑えることができます。scponly などの制限的なシェルも存在します。
  • ネットワークを介してバックアップが行われるので、速度は遅くなります。rsnapshot は rsync を使うので、最初のバックアップに最も時間がかかります。その後のバックアップについては、バックアップ元のデータの変更量によって、rsync はファイルの差異だけを送信するので、ずっと高速になるはずです。

特殊スクリプト

backup_script 行は特別な設定です。このパラメータを使う場合、2番目のカラムには実行するバックアップスクリプトのフルパスを、3番目のカラムにはバックアップを保存するローカルパスを指定します (それは backup パラメータと同じです)。例:

/etc/rsnapshot.conf
backup_script      /usr/local/bin/backup_mysql.sh       localhost/mysql/

上記の例では、rsnapshot は一時ディレクトリをで /usr/local/bin/backup_mysql.sh スクリプトを実行して、作成されたファイルをスナップショットルートの localhost/mysql/ ディレクトリに同期します。

バックアップスクリプトからはカレントディレクトリにバックアップするものを何でもダンプするだけです。必要なだけ、いくらでもファイルやディレクトリを作成できますが、あらかじめ定義したパスにバックアップするファイルを置くことはできません。rsnapshot は一時ディレクトリを作成して、そのディレクトリに移動してからバックアップスクリプトを実行し、そして一時ディレクトリの中身を3番目のカラムで指定したローカルパスに同期させるからです。バックアップスクリプトとしてはデータベースの中身をアーカイブ化するスクリプトが典型です。スクリプトは以下のようになります:

backup_mysql.sh
#!/bin/sh

/usr/bin/mysqldump -uroot mydatabase > mydatabase.sql
/bin/chmod 644 mydatabase.sql
ノート:
  • 指定する宛先パスが一つであることを確認してください。 バックアップスクリプトは宛先パスのすべてを完全に上書きするため、同じ宛先を2回指定しようとすると、最後のスクリプトのファイルのみが残ります。 幸い、 rsnapshot は、構成ファイルを読み取るときに、これを実行できないようにします。
  • これらのバックアップスクリプトは、 rsnapshot を実行しているユーザーとして呼び出されることに注意してください。 この例では、バックアップスクリプトが root によって所有されており、他の人が書き込みできないことを確認してください。 これを怠ると、これらのバックアップスクリプトへの書き込みアクセス権を持つユーザーは誰でも、 root ユーザーとして実行されるコマンドをスクリプトに入れることができます。 それらが悪意のあるものである場合、それらはあなたのサーバーを乗っ取る可能性があります。

設定のテスト

変更が全て完了したら、設定ファイルで正しく同期が行われるか確認してください。設定ファイルをテストするには、configtest 引数を付けて rsnapshot を実行します:

# rsnapshot configtest

設定が問題なければ、Syntax OK と出力されます。問題がある場合は、何が問題なのか出力します。設定ファイルが空白ではなくタブを使っていることなどを確認してください。

最後に rsnapshot をテストモードで実行して設定をテストします。実際にバックアップを行わないで、どんなことが行われるかの詳細なリストが出力されます。テストランを実行するには、次のコマンドを使用:

# rsnapshot -t hourly

上記のコマンドで rsnapshot は "hourly" バックアップをシミュレートします。実際に rsnapshot が実行されたときに rsnapshot が使用するのと同じコマンドが出力されます。

ノート: テスト出力は実際の実行とわずかに異なる場合があることに注意してください。ただし、これは、プログラムの後半でチェックされる可能性のあることをテストが実際に実行しないためです。 たとえば、プログラムがディレクトリを作成し、後でそのディレクトリが存在するかどうかをテストする場合、テスト中に実際には作成されなかったため、テストの実行でディレクトリが2回作成されると要求される場合があります。 これは、テストの実行中に表示される唯一の違いです。

自動化

設定ファイルを設定したら、自動的に rsnapshot を実行するようにセットアップします。

まずサービスファイルを作成:

/etc/systemd/system/rsnapshot@.service
[Unit]
Description=rsnapshot (%I) backup

[Service]
Type=oneshot
Nice=19
IOSchedulingClass=3
ExecStart=/usr/bin/rsnapshot %I

次に、サービスを実行する間隔ごとにタイマーユニットを作成します (つまり、時間ごと、毎日、毎週、毎月):

/etc/systemd/system/rsnapshot-interval.timer
[Unit]
Description=rsnapshot hourly backup

[Timer]
OnCalendar=
Persistent=true
Unit=rsnapshot@interval.service

[Install]
WantedBy=timers.target

OnCalendar エントリが有効であることを確認し、動作を確認して下さい。(特に上記を変更した場合):

# systemd-analyze calendar "Mon *-*-* 04:30:00"
ノート: 通常、小さい間隔より少し前に実行するように大きい間隔をスケジュールすることをお勧めします。これにより、1 時間ごとのジョブが終了する前に毎日実行しようとする競合状態を防ぐことができます。これと同じ方法を拡張して、毎週のエントリが daily の前に実行されるようにする必要があります。

最後に、それらを 有効化 して 起動 し、結果の ユニットステータス が良好であること、およびタイマーが期待どおりにスケジュールされていることを確認します。

# systemctl list-timers rsnapshot*

これで、最初のタイマーがトリガーされるまで待つことができます。すぐにタイマーを開始したい場合は、マニュアル で実行できます。

外付けドライブ

ノート: このセクションは、上記の 自動化 セクションで説明されている設定がすでに完了していることを前提としています。

宛先ドライブが USB または eSATA 経由で接続された外部エンクロージャ内にある場合、起動中にマウントされていないか、rsnapshot の開始がスケジュールされている時点でアンマウントされている可能性があります。rsnapshot が常に存在するパス (例:/.snapshots) に書き込むように設定されている場合、データは、目的の外部ドライブではなく、ルートディレクトリとしてマウントされているハード ドライブにバックアップされます。

この状況を解決するには、予想されるマウントポイントにマウントされているディスクに依存するように rsnapshot を設定する必要があります。/etc/fstab/etc/systemd/system/rsnapshot@.service を変更する 2 つのアクションが必要です。

Systemd は、/etc/fstab ファイルを読み取り、その中のすべてのマウントポイントのユニットファイルを作成します。このセットアップでは、マウントポイントに 1 つ (オプションで 2 つ) の設定オプションを追加する必要があります。目的のマウントポイントのオプション列の最後に、x-systemd.automount を追加します。また、非アクティブになった後にマウントポイントをアンマウントしたい場合は、x-systemd.idle-timeout=10m 10m という値は任意の値に変更できます。使用可能なオプションの詳細については、systemd.automount(5) および systemd.mount(5) を参照してください。

ヒント: パーティションの UUID は、root で blkid を実行することで確認できます。

マウントポイントの例:

/etc/fstab
# /dev/sdd1
UUID=2848e78d-b05a-4477-a5f0-38f35411c269 /mnt/backups ext4 noauto,nofail,noexec,nouser,nosuid,rw,async,x-systemd.device-timeout=200ms,x-systemd.automount,x-systemd.idle-timeout=10m 0 2
ヒント: 使用可能なオプションの詳細については、fstab(5) および mount(8) § FILESYSTEM-INDEPENDENT MOUNT OPTIONS を参照してください。

/etc/fstab を変更した後、daemon-reload を実行して、systemd が取得した、マウントユニットと自動マウントユニットが正しく表示されていることを確認します。

# systemctl show mnt-backups.mount
Where=/.snapshots
What=/dev/sdd1
Options=rw,nosuid,noexec,relatime,x-systemd.automount
Type=ext4
TimeoutUSec=1h
...
# systemctl show mnt-backups.automount
Where=/mnt/backups
DirectoryMode=0755
...

最後に、/etc/systemd/system/rsnapshot@.service編集 して [Unit] セクションに次の行を追加します。

/etc/systemd/system/rsnapshot@.service
[Unit]
Requires=mnt-backups.mount
After=mnt-backups.mount

すべてが正しく設定されていることを確認するには、rsnapshot サービスユニットにマウントポイントが必要になっていることを確認します。

# systemctl show rsnapshot@daily.service | grep 'Requires='
Requires=sysinit.target system-rsnapshot.slice mnt-backups.mount
ヒント: root として journalctl -u mnt-backups.mount を実行して、自動マウントとアンマウントが期待どおりに行われていることを確認します。

仕組み

スナップショットルートの下に全てのバックアップが保存されます。以下の例ではスナップショットルートは /mnt/backups/ ディレクトリです。このディレクトリの中に、先に定義した様々なインターバルのディレクトリが作成されます。初めは空ですが、rsnapshot を一週間実行し続けると、以下のようになります:

[root@localhost]# ls -l /mnt/backups/
drwxr-xr-x    7 root     root         4096 Dec 28 00:00 daily.0
drwxr-xr-x    7 root     root         4096 Dec 27 00:00 daily.1
drwxr-xr-x    7 root     root         4096 Dec 26 00:00 daily.2
drwxr-xr-x    7 root     root         4096 Dec 25 00:00 daily.3
drwxr-xr-x    7 root     root         4096 Dec 24 00:00 daily.4
drwxr-xr-x    7 root     root         4096 Dec 23 00:00 daily.5
drwxr-xr-x    7 root     root         4096 Dec 22 00:00 daily.6
drwxr-xr-x    7 root     root         4096 Dec 29 00:00 hourly.0
drwxr-xr-x    7 root     root         4096 Dec 28 20:00 hourly.1
drwxr-xr-x    7 root     root         4096 Dec 28 16:00 hourly.2
drwxr-xr-x    7 root     root         4096 Dec 28 12:00 hourly.3
drwxr-xr-x    7 root     root         4096 Dec 28 08:00 hourly.4
drwxr-xr-x    7 root     root         4096 Dec 28 04:00 hourly.5

各ディレクトリの中にはその時点での完全なバックアップが存在します。上記のディレクトリの下には backupbackup_script パラメータで指定したバックアップ先ディレクトリのパスが直接スタックします。例:

backup          /etc/           localhost/

/etc/ ディレクトリはまず最初に /mnt/backups/hourly.0/localhost/etc/ にバックアップされます。その後 hourly コマンドで rsnapshot が実行されると、hourly.X ディレクトリがローテートして、hourly.0 ディレクトリの中身は (ハードリンクを使って) hourly.1 にコピーされます。

rsnapshot daily が実行されると、全ての daily.X ディレクトリがローテートして、hourly.5 の中身は daily.0 にコピーされます。

hourly.0 にはいつでも最新のスナップショットが保存され、daily.6 にはいつでも一週間前のスナップショットが保存されます。スナップショット間でファイルの変更が行わなかった場合、フルバックアップは同一のファイルのハードリンクとなります。従って、/etc/passwd ファイルを一週間変更しなかったとき、hourly.0/localhost/etc/passwddaily.6/localhost/etc/passwd は文字通り全く同じファイルになります。これによって rsnapshot は容量を節約することを可能にしています。ある時点でファイルが変更されると、次のバックアップでは hourly.0 のハードリンクが削除され、全く新しいファイルに置き換わります。こうなるとディスクの容量を二重に消費することになりますが、ファイルのコピーを13回にわたってそれぞれ別個に作成するよりかはずっと効率的です。

上記の例とは異なるインターバルを使う場合、ファイルシステムから直接更新が取得されるのはリストの最初のインターバルであることを覚えておいてください。後に記述した全てのインターバルは前のインターバルからバックアップを引き継ぎます。例えば、毎週・毎月・毎年のインターバルを (この順番で) 定義した場合、毎週のバックアップは直接ファイルシステムから取得され、毎月のバックアップは毎週のバックアップから更新され、毎年のバックアップは毎月のバックアップから更新されます。