猫の手なら貸せる

いろいろ共有できたらいいなとおもってます

ラズパイのシステムバックアップをSystemdで定期実行する

無限に同じことを違う人が書いていて正直みんなやってそうですが、最近シェルをSystemdのサービスに落とし込めるようになったので、自分なりに書き起こしておきます。

筆者環境

  • RaspberryPi 4 4GBモデル
  • Raspbian buster

cat /etc/os-release

PRETTY_NAME="Raspbian GNU/Linux 10 (buster)"
NAME="Raspbian GNU/Linux"
VERSION_ID="10"
VERSION="10 (buster)"
VERSION_CODENAME=buster
ID=raspbian
ID_LIKE=debian
HOME_URL="http://www.raspbian.org/"
SUPPORT_URL="http://www.raspbian.org/RaspbianForums"
BUG_REPORT_URL="http://www.raspbian.org/RaspbianBugs"

バックアップ手順

全てシェルで書いています。実際はログの出力やエラーの処理などを書いていますが、その中からコアな部分を抜粋。

root(/)以下のバックアップ

作成するバックアップのパスを変数にセットします。dumppath="/mnt/nas/backup/root.dump"など。

拡張子などは実際は不要ですが、わかりやすくするためにつけています。

/sbin/dump -0f "$dumppath" /dev/mmcblk0p2  

-0fを指定することで毎回フルバックアップを取ります。前提としてバックアップの際は必ず、ラズパイに使っているmicroSDの1/4くらいの空き容量が必要です。

私の環境だと、dumpの生ファイルは毎回2〜3GBは使用します。

/bootディレクトリのバックアップ

bootはパーティション・フォーマットが異なり、FAT32領域なのでパーミッション等を考慮する必要がありません。なので適当にtgzなどで作成しています。

/bin/tar -zcf "$tgzpath" /boot

一度に使用する領域は対外500MB程度です。

xz圧縮

生dumpをとっておくのは厳しいので圧縮率が高く解凍の早いxzを使い固めます。

サーバーですが、バックアップは使用していない時間帯に行う前提で、最高圧縮率の-9オプションを指定しています。

/usr/bin/xz -9 "$dumppath"

毎回1時間くらいかかりますが、圧縮率は高いです。

f:id:nkhnd:20200429154933p:plain

上記のようなstepの表示や圧縮率計算のログは、シェルで計算したものをechoしているだけです。Systemdでシェルを動かした場合、echoした内容に勝手に時間が付与された形でjournalctlに出力されます。

バックアップの手順自体はこんなもんです。

Systemdによる自動化

一昔前はcrontabを使っていました。その時はこう。

0 15 * * * /src/pdump.sh /mnt/nas/backup/system/

pdumpはPeriodic Dumpの略です。命名は大事。スクリプト内でargでPATHを指定できるようになど設定しています。

Systemdを学習したのでSystemdを使っています。利点はcrontabで行うより手動でバックアップするのが簡単です。

crontabでは上のコマンドを毎回コピーして実行しますが、Systemdならsystemctl start dump.serviceで実行してくれます。

ログとかもjournalctlが勝手に上手くやってくれるのでこっちが考える必要がありません。ログローテートとか勉強していないので知りません。

pdump.serviceの作成

こんな感じで適当なディレクトリにdump.serviceを作成します。ここでは/src/pdump/ディレクトリ内に作っています。

[Unit]
Description=Periodic dump script

[Service]
Type=simple
ExecStart=/src/pdump/pdump.sh
EnvironmentFile=/src/pdump/pdump.conf
Restart=no

[Install]
WantedBy=multi-user.target

設定ファイルなどはスクリプト内を簡略化するために使用しています。

pdump.timerの作成

定期的に上記のスクリプトを動かすための設定ファイルを作成します。

[Unit]
Description=Periodic dump timer

[Timer]
OnCalendar=*-*-* 15:00:00
Persistent=true
Unit=pdump.service

[Install]
WantedBy=multi-user.target

毎日15:00にpdump.serviceを実行です。

シンボリックリンクを配置

直接設定ファイルを置く人もいますが、私は他のサービスの例にならってシンボリックリンクを使っています。

ln -s /src/pdump.service /etc/systemd/system/
ln -s /src/pdump.timer /etc/systemd/system/

Systemd有効化

pdump.timerのみをSystemdに読み込ませます。

sudo systemctl daemon-reload 
sudo systemctl enable pdump.timer

動作を確認。以下は4/20に開始して、次のバックアップが4/30 15:00に行われることまで書いてあります。

systemctl status pdump.timer
● pdump.timer - Periodic dump timer
   Loaded: loaded (/src/pdump/pdump.timer; enabled; vendor preset: enabled)
   Active: active (waiting) since Mon 2020-04-20 09:04:45 JST; 1 weeks 2 days ago
  Trigger: Thu 2020-04-30 15:00:00 JST; 22h left

 4月 20 09:04:45 nkpi systemd[1]: Started Periodic dump timer.

ログはjournalctl -u pdump.serviceで見れます。上のスクショでは写っていませんが、日付なども勝手に付与してくれます。

復元のやり方

dumpとセットのコマンドrestoreを使用します。restoreでは仕様上、使用中のファイルシステムへ適応できません。

要はラズパイでラズパイの復旧はできません。

別のラズパイを用意するかLinux仮想マシンを構築するなど行う必要があります。いつでも復元できるようにシステムを簡単に作成しておきましょう。

筆者はMacbookParallelsを導入し、ubuntu上でrestoreを行っています。

cd /media/ubuntu/rootfs #ルートをカレントディレクトリにします。
unxz /media/ubuntu/recovdisk/200428/root.dump.xz #圧縮を解きます。

#restoreコマンドを中身のあるディレクトリ上で行うと、デフォルトでは既存のファイルへ上書きを行います。消さなくても実行は可能ですが、余計なファイルが残ったままになります。
sudo rm -rf ./
 
sudo restore -rf /media/ubuntu/recovdisk/200428/root.dump #復元。

/bootディレクトリはtgzを解凍するだけです。

cd /media/ubuntu/boot
sudo rm -rf ./
sudo tar -zxvf /media/ubuntu/recovdisk/200428/boot.tgz 

サーバは安定稼働が続いていてネタがない中、iPhoneSEが届いたりしてQi充電に初めて触れました。手軽に充電できてとっても素敵。

寝る時は睡眠計測の都合で有線接続です。しょうがない。

SleepCycleが理不尽に値段が高いので一回きりで十分なSleep meisterを購入しました。

Sleep Meister - 睡眠サイクルアラーム

Sleep Meister - 睡眠サイクルアラーム

  • Naoya Araki
  • ヘルスケア/フィットネス
  • ¥250
apps.apple.com

今のところSleep Cycleと違いは殆どなく、いい感じです。

最近はDockerを勉強し始めたので、ソフトウェアRAIDをコンテナサービスで置き換えられないかなーなど考え中。