Btrfs環境でSnapperを使う方法:更新エラー時にLinuxを自動スナップショット&ロールバック

Linux tutorial - IT technology blog
Linux tutorial - IT technology blog

1回のapt upgradeで本番サーバーが停止した話

エンジニアになりたての頃、私はWebサーバークラスターの復旧作業で午後丸々を費やした苦い経験があります。原因は単純で、事前検証を怠り安易にapt upgradeを実行してしまったことでした。新しいカーネルがネットワークドライバーと競合を起こしてIPアドレスを見失い、SSH接続すら不能に。冷や汗をかきながらKVMを接続し、救出作業に4時間も追われました。

この障害から学んだ教訓は、「本番環境でのあらゆる変更には必ずロールバック手段を用意すべき」ということでした。サーバーでBtrfsファイルシステムを採用しているなら、Snapperはまさに最高の救世主となります。このツールを使えば、パッケージのインストール前後にシステムの状態を自動保存し、問題が発生してもコマンド1つで過去の状態へと巻き戻すことができます。

Btrfsサブボリュームとスナップショットの仕組みをサクッと理解

Snapperを効果的に運用するために、まずは以下の2つの基本概念を押さえておきましょう。

1. BtrfsサブボリュームとCopy-on-Write(CoW)

Btrfsはディスクを独立したサブボリュームに分割しつつ、全体のストレージ容量を共有します。Copy-on-Write(CoW)の仕組みのおかげで、作成した直後のスナップショットの実容量は0 MBです。新しいデータが書き込まれたり上書きされたりして初めて追加のディスク容量を消費するため、スナップショットを50個作成してもディスクが即座に逼迫する心配はありません。

2. Snapperにおける3種類のスナップショット

Snapperでは、用途に応じてスナップショットが明確に分類されています。

  • Single: 特定の時点における単一のスナップショット。日次の定期バックアップなどに適しています。
  • Pre: ソフトウェアのインストールや更新コマンドを実行する直前に自動作成されます。
  • Post: インストール完了直後に作成されます。SnapperはPreとPostをペアとして管理するため、変更された各ファイルを正確に比較できます。

実践:インストール、設定、ロールバックの検証

ステップ1:Snapperと関連ツールのインストール

Debian/Ubuntuの場合(ルートパーティションがBtrfsの@レイアウトで動作している必要があります):

sudo apt update
sudo apt install snapper inotify-tools grub-btrfs

Fedora、CentOS Stream、またはRHEL系ディストリビューション(DNF使用)の場合:

sudo dnf install snapper python3-dnf-plugin-snapper

このDNFプラグインは非常に便利で、dnf updateを実行するたびにPre/Postスナップショットのペアを自動生成してくれます。

ステップ2:ルートパーティション向けの設定ファイル作成

ルートディレクトリ/用のSnapper設定を初期化します:

sudo snapper -c root create-config /

デフォルトでSnapperは/.snapshotsディレクトリを作成します。古いスナップショットが溜まってディスク容量を圧迫しないよう、クリーンアップポリシーを調整しましょう:

sudo nano /etc/snapper/configs/root

一般的なサーバー向けに適切な世代保持数を設定します:

# クリーンアップ前にスナップショットを保持する最小時間(秒単位)
TIMELINE_MIN_AGE="1800"

# 時間周期ごとのスナップショット保持数制限
TIMELINE_LIMIT_HOURLY="6"
TIMELINE_LIMIT_DAILY="7"
TIMELINE_LIMIT_WEEKLY="2"
TIMELINE_LIMIT_MONTHLY="0"
TIMELINE_LIMIT_YEARLY="0"

# ディスク使用率に応じた自動クリーンアップ
EMPTY_PRE_POST_CLEANUP="yes"
NUMBER_CLEANUP="yes"

systemdのタイマーを有効化して、自動クリーンアップを開始します:

sudo systemctl enable --now snapper-timeline.timer snapper-cleanup.timer

ステップ3:手動スナップショット作成と差分比較

Nginxやデータベースの重要な設定ファイルを変更する前に、手動で復元ポイントを作成しておきます:

sudo snapper -c root create --description "Nginx設定変更前"

作成済みのスナップショット一覧を確認します:

sudo snapper -c root list

ターミナルに出力される結果例:

 # | Type   | Pre # | Date                     | User | Cleanup  | Description
---+--------+-------+--------------------------+------+----------+-----------------------------
 0 | single |       |                          | root |          | current
 1 | single |       | Thu 02 Oct 2026 09:00:00 | root | timeline | timeline
 2 | single |       | Thu 02 Oct 2026 10:15:30 | root |          | Nginx設定変更前

設定ファイルを編集したものの、サービスが起動しなくなったと仮定します。スナップショット#2と現在の状態(#0)の間で変更されたファイルを確認してみましょう:

sudo snapper -c root status 2..0

行頭記号の意味:

  • +: 新規作成されたファイル
  • -: 削除されたファイル
  • c: 内容が変更されたファイル

設定ファイル内の行単位の差分(diff)を確認します:

sudo snapper -c root diff 2..0 /etc/nginx/nginx.conf

ステップ4:ロールバックによるシステム復元

問題が/etc配下の特定の設定ファイルだけであれば、以下のコマンドで素早く変更を取り消せます:

sudo snapper -c root undochange 2..0

Snapperによって、すべての対象ファイルがスナップショット#2の状態へと即座に復元されます。

アップデート後にカーネルパニックやglibcの破損など深刻な障害が発生した場合は、サブボリューム全体のロールバックを実行します:

sudo snapper rollback 2
sudo reboot

ロールバック処理は30秒もかからずに完了します。再起動後は、何事もなかったかのようにスナップショット#2の安定した状態でシステムが立ち上がります。

まとめ

BtrfsとSnapperは、Linux運用において欠かせない強力な組み合わせです。リスクの伴うメンテナンス作業を、安全で制御可能なプロセスへと変えてくれます。適切なクリーンアップ設定を行っておくだけで、リソースを無駄遣いすることなく軽量な自己復旧システムを手軽に構築できます。

Share: