AlmaLinux 9 総合ガイド 第11章

第11章: バックアップとリカバリ戦略


11.1 バックアップとリカバリ戦略の概要

本節では AlmaLinux9 環境におけるバックアップとリカバリ戦略の全体像を解説します。サーバ障害やヒューマンエラー、災害リスクからシステムを保護し、ビジネス継続性(BCP)を確保するための要件定義から設計プロセス、ベストプラクティスまでを網羅します。

11.1.1 バックアップ戦略の重要性

データ損失は企業活動に甚大な影響を及ぼします。バックアップ戦略を策定することで、以下を達成できます:

  • データ消失リスクの最小化
  • コンプライアンス要件への準拠(例:監査ログの保全)
  • システム障害からの迅速な復旧
💡 補足:バックアップ前に dnf update -y でパッケージを最新化すると、復元後の環境差異を減らせます。

11.1.2 リカバリ戦略の重要性

バックアップはあくまでデータ保全の「準備段階」です。実際の障害発生時に適切にデータを復旧できなければ意味がありません。リカバリ戦略では以下を検討します:

  • RPO(Recovery Point Objective):許容できるデータ損失の最大時間
  • RTO(Recovery Time Objective):システムを復旧するまでの最大許容時間
  • DRサイト構成:オンプレミス/クラウド、Active-Passive/Active-Active
注意:RTO/RPO 要件が厳しい場合、高速ストレージやネットワーク回線、冗長構成の追加コストが発生します。

11.1.3 戦略設計の主要ステップ

  • 要件定義:業務インパクト分析(BIA)に基づく RPO/RTO の決定
  • データ分類:重要度に応じて階層化し、バックアップ頻度や保持期間を設計
  • 方式選定:フル/増分/差分バランスの最適化
  • メディア選択:ディスク、テープ、クラウドストレージ(rclone/S3 互換)など
  • オフサイト保管:3-2-1 ルールの実践(3コピー、2種類のメディア、1つはオフサイト)
  • テスト計画:定期的な復元演習と検証(整合性チェック、ログ管理)

11.1.4 バックアップ/リカバリ自動化スクリプト例

実行ユーザー:root または sudo ユーザー
目的/前提条件:Web コンテンツ(/var/www)を差分バックアップし、古い世代を自動削除する
期待される結果:バックアップ先にタイムスタンプ付きフォルダが作成され、7 日以上前の古いフォルダが削除される

#!/bin/bash  # スクリプトの実行シェルを指定
# AlmaLinux9 環境での差分バックアップ例スクリプト

# システムを最新化
dnf update -y  # dnf でパッケージを最新状態に更新し、復元後の環境差異を減少

# バックアップ元と保存先を定義
SOURCE_DIR="/var/www"            # バックアップ対象ディレクトリ
DEST_ROOT="/backup/var_www"      # バックアップ保存先ルートディレクトリ

# タイムスタンプの取得
TIMESTAMP=$(date +%Y%m%d_%H%M%S)  # YYYYMMDD_HHMMSS 形式で日時文字列を生成

# rsync で差分バックアップを実行
rsync -aAX --delete "$SOURCE_DIR/" "$DEST_ROOT/$TIMESTAMP/"  # 属性・ACL・SELinuxコンテキストを保持して同期

# 世代管理:7 日以上前のバックアップを削除
find "$DEST_ROOT" -maxdepth 1 -type d -mtime +7 -exec rm -rf {} \;  # 古いバックアップフォルダを削除
💡 補足:SELinux コンテキストを保持するには rsync -aAX オプションを使用します。
注意:スクリプト実行中の書き込み操作はデータ整合性を損なう恐れがあるため、できるだけアイドル時間帯に実行してください。

実行ユーザー:root または sudo ユーザー
目的/前提条件:最新バックアップを指定ディレクトリに復元する
期待される結果:バックアップ先の最新フォルダが /var/www に上書き復元される

#!/bin/bash  # スクリプトの実行シェルを指定
# AlmaLinux9 環境でのリカバリ例スクリプト

# バックアップ保存先ルートを設定
BACKUP_ROOT="/backup/var_www"                 # バックアップ保存先ルートディレクトリ

# 最新バックアップディレクトリを検出
LATEST_BACKUP=$(ls -1d "$BACKUP_ROOT"/*/ | sort | tail -n 1)  # ソートして最終行を取得

# 復元先ディレクトリを設定
DEST_DIR="/var/www"                           # 復元先ディレクトリ

# rsync で復元を実行
rsync -aAX --delete "$LATEST_BACKUP" "$DEST_DIR/"  # 最新バックアップを同期して復元
注意:復元先の既存ファイルは上書きされます。重要データは事前に別途バックアップしてください。

11.2 バックアップの基本方針

AlmaLinux9環境におけるバックアップ戦略の土台となる基本方針を深掘りします。本節では、3-2-1ルールの起源と適用、メディア選定、データ分類と保持ポリシー、セキュリティ・暗号化、検証・監査方法、そして自動化ポリシーまでを体系的に解説します。

11.2.1 3-2-1ルールの詳細

歴史的に最も広く採用されているバックアップ原則で、以下の要件を満たします:

  • 3つのコピー:オリジナルデータ1 + バックアップ2 で合計3コピー。
  • 2種類のメディア:ディスク、テープ、光学媒体、クラウドストレージなど。
  • 1つはオフサイト:物理的に離れた場所や別リージョンのクラウドに保管。

このルールにより、単一障害点(SPOF)、自然災害、人的ミス、マルウェア攻撃など多様なリスクを軽減できます。

💡 補足:オフサイト保管にはクラウドストレージや遠隔地データセンターを利用し、ネットワーク回線の冗長化も検討すると安全性がさらに向上します。

11.2.2 バックアップメディアの選定基準

メディア選定はコスト、信頼性、可用性、復旧速度のトレードオフを考慮します。

メディア メリット デメリット
ハードディスク(HDD/SSD) 高速アクセス、ランダムI/O対応 寿命と耐久性に注意、災害耐性低
テープ(LTO) 長期保管に最適、容量単価が安い シーケンシャルアクセス、復旧に時間がかかる
クラウドストレージ(S3互換) オフサイト、自動冗長化可 運用コスト、セキュリティ設定必須
注意:テープは定期的なリライトと適切な環境管理(温度・湿度)を行わないと劣化リスクが高まります。

11.2.3 データ分類と保持ポリシー

すべてのデータを一律にバックアップするとコストと時間が膨大になります。以下のステップで分類し、階層的に保持ポリシーを設計します:

  1. ビジネスクリティカル:データベースやログなど。高頻度+長期間保持(例:1日1回、90日保管)。
  2. セカンダリデータ:共有ドキュメントなど。中頻度+中期間(例:週1回、30日保管)。
  3. 非クリティカル:キャッシュや一時ファイルなど。低頻度+短期間(例:月1回、7日保管)。
💡 補足:GFS(Grandfather–Father–Son)世代管理を組み合わせると、世代ごとの保持ポリシー設計が容易になります。

11.2.4 セキュリティと暗号化

バックアップデータは機密情報を含むことが多いため、保存時(at rest)および転送時(in transit)の両方で暗号化を実施します。

  • 対称鍵暗号(AES256)+GPGによるアーカイブ暗号化
  • KMIP/HSM連携で鍵管理を安全に実装
  • TLS 1.2以上のプロトコルで転送経路を保護

11.2.5 バックアップ検証と監査

バックアップの有効性を担保するには、整合性チェックリストアテストを定期的に実行します。

実行ユーザー:root または sudo ユーザー
目的/前提条件:バックアップディレクトリ内ファイルの整合性をチェックしログ出力
期待される結果:各ファイルのSHA256ハッシュが /var/log/backup_verify.log に追記され、最新ログが表示される

#!/bin/bash               # スクリプトの実行シェルを指定
# バックアップディレクトリの整合性チェックスクリプト

BACKUP_DIR="/backup"       # バックアップ保管先ルートディレクトリ
LOG_FILE="/var/log/backup_verify.log"  # ログ出力先ファイル

# 各バックアップ世代ディレクトリをループ処理
for dir in "$BACKUP_DIR"/*/; do           # バックアップフォルダを順次処理
  find "$dir" -type f | while read file; do  # 各ファイルを取り出し
    sha256sum "$file" >> "$LOG_FILE"      # SHA256ハッシュを計算しログに追記
  done
done

# ログのサンプル出力を確認
tail -n 20 "$LOG_FILE"                     # 最新20行を表示して検証
💡 補足:リストアテストは仮想環境で実施し、復旧手順書を用意して手順の手順化と担当者教育を行ってください。

11.2.6 自動化とスケジューリングポリシー

ビジネス要件に応じてRPOを逆算し、cronやsystemd timersで自動化します。

実行ユーザー:sudoユーザーまたはroot
目的/前提条件:ビジネス要件に合わせて日次・週次バックアップを自動実行
期待される結果:毎日と週次でそれぞれバックアップスクリプトが自動実行される

# ── cron: 毎日深夜 2:00 に日次バックアップ実行
0 2 * * * /usr/local/bin/backup_daily.sh   # 毎日 2:00 に backup_daily.sh を実行

# ── systemd timer: 週次バックアップ設定例
sudo tee /etc/systemd/system/backup_weekly.timer << 'EOF'  # タイマーユニットを作成
[Unit]                              # Unit セクション開始
Description=Weekly Backup Timer     # タイマーの説明を記載
[Timer]                             # Timer セクション開始
OnCalendar=weekly                   # スケジュール:週次で起動
Persistent=true                     # 再起動時に未実行タイマーを実行
[Install]                           # Install セクション開始
WantedBy=timers.target              # timers.target に紐付け
EOF  # ヒアドキュメント終了

# タイマーの有効化と起動
sudo systemctl enable backup_weekly.timer  # タイマーを自動起動に設定
sudo systemctl start backup_weekly.timer   # タイマーを起動

学習のポイント

  1. 3-2-1ルールの各要素がリスク軽減にどう寄与するかを理解する
  2. メディア選定では信頼性・コスト・復旧速度のバランスを考慮する
  3. データ分類+GFS世代管理で効率的な保持ポリシーを設計する
  4. 暗号化と鍵管理で機密性を確保する
  5. 検証スクリプトで整合性確認とログ監査を自動化する
  6. RPO要件に合わせ、cron/systemd timersで自動スケジューリングを行う

11.3 手動バックアップと自動化

AlmaLinux9環境において、手動でのバックアップ方法から自動化までを徹底解説します。ここではrsynctarを使った手動バックアップ、LVMスナップショットを活用した整合性確保、そしてcronsystemd timersによる定期実行設定を扱います。

11.3.1 rsyncを使った差分スナップショットバックアップ

実行ユーザー:rootまたはsudoユーザー
目的/前提条件:/var/www配下を日次で差分スナップショットとして保存
期待される結果:バックアップ先に日付ごとのフォルダが作成され、前回からの差分ファイルはハードリンクで効率的に保持される

#!/bin/bash                                                       # スクリプトの実行シェルを指定
SOURCE="/var/www"                                                  # バックアップ元ディレクトリを設定
DEST_ROOT="/backup/snapshots"                                      # スナップショット保存先ルートを設定
TODAY=$(date +%Y%m%d)                                              # 今日の日付を YYYYMMDD 形式で取得
LAST=$(ls -1d "$DEST_ROOT"/*/ 2>/dev/null | sort | tail -n 1)      # 最新のスナップショットディレクトリを取得
if [ -n "$LAST" ]; then                                            # 過去のスナップショットが存在する場合
  LINK_DEST="--link-dest=$LAST"                                    # ハードリンク用オプションを設定
else                                                                # 過去のスナップショットがない場合
  LINK_DEST=""                                                     # リンクオプションを無効化
fi                                                                  # 条件分岐を終了
mkdir -p "$DEST_ROOT/$TODAY"                                       # 当日用ディレクトリを作成
rsync -aAXv --delete $LINK_DEST "$SOURCE/" "$DEST_ROOT/$TODAY/"    # 属性・ACL・SELinuxコンテキストを保持して同期
💡 補足:--link-destオプションで変更のないファイルはハードリンクとなり、ストレージ使用量を大幅に削減できます。
注意:ハードリンクは編集すると全世代に影響するため、バックアップ先ディレクトリをマウントせず直接編集しないでください。

11.3.2 tarを使った増分バックアップ

実行ユーザー:rootまたはsudoユーザー
目的/前提条件:/homeディレクトリの増分バックアップを取得
期待される結果:前回実行以降の変更分のみを含むアーカイブとスナップショットファイルが生成される

#!/bin/bash                                                            # スクリプトの実行シェルを指定
BACKUP_DIR="/backup/tar"                                                # tarバックアップ保存先を設定
SNAPSHOT_FILE="$BACKUP_DIR/.snapshot.file"                              # 増分管理用スナップショットファイルを設定
TIMESTAMP=$(date +%Y%m%d)                                               # 今日の日付を YYYYMMDD 形式で取得
mkdir -p "$BACKUP_DIR"                                                  # 保存先ディレクトリを作成
tar --listed-incremental="$SNAPSHOT_FILE" -czf \                         # スナップショットを元に増分バックアップを作成
  "$BACKUP_DIR/home_$TIMESTAMP.tar.gz" /home                            # バックアップファイル名と対象ディレクトリを指定
💡 補足:--listed-incrementalオプションにより前回の状態との差分のみをバックアップし、アーカイブサイズを最適化できます。

11.3.3 LVMスナップショットを活用した整合性バックアップ

実行ユーザー:rootまたはsudoユーザー
目的/前提条件:ルートボリュームを一時スナップショットし、ファイルシステムの整合性を維持しながらバックアップを取得
期待される結果:スナップショットから安全にデータをコピーし、処理後にスナップショットを削除する

#!/bin/bash                                                        # スクリプトの実行シェルを指定
VG="cl"                                                              # LVM ボリュームグループ名を設定
LV="root"                                                            # LVM ロジカルボリューム名を設定
SNAP_NAME="root_snap_$(date +%Y%m%d_%H%M%S)"                         # スナップショット名にタイムスタンプを付与
MOUNT_POINT="/mnt/root_snap"                                         # スナップショットマウント先を設定
DEST="/backup/lvm"                                                   # バックアップ保存先を設定
lvcreate -L1G -s -n "$SNAP_NAME" "/dev/$VG/$LV"                      # 1GB のスナップショットを作成
mkdir -p "$MOUNT_POINT"                                              # マウントポイントを作成
mount "/dev/$VG/$SNAP_NAME" "$MOUNT_POINT"                           # スナップショットをマウント
rsync -aAXv --delete "$MOUNT_POINT/" "$DEST/$SNAP_NAME/"             # スナップショットからバックアップを取得
umount "$MOUNT_POINT"                                               # スナップショットのマウントを解除
lvremove -f "/dev/$VG/$SNAP_NAME"                                    # スナップショットを削除
注意:スナップショット容量が不足するとエラーになるため、変更頻度に応じてサイズを適切に設定してください。

11.3.4 cron / systemd timersによる自動化

実行ユーザー:sudoユーザーまたはroot
目的/前提条件:日次・週次バックアップスクリプトを自動実行する
期待される結果:cron と systemd timers によりバックアップが定期実行され、運用負荷を軽減する

# ── cron: 毎日深夜 2:30 に差分スナップショットバックアップを実行                      # cron 設定の説明
30 2 * * * /usr/local/bin/backup_rsync_snap.sh            # backup_rsync_snap.sh を毎日 2:30 に実行
# ── cron: 毎週日曜深夜 3:00 に増分バックアップスクリプトを実行                                 # cron 設定の説明
0 3 * * 0 /usr/local/bin/backup_tar_incremental.sh        # backup_tar_incremental.sh を毎週日曜 3:00 に実行
# ── systemd timer: 週次全体バックアップタイマーを作成                                          # systemd timer 設定の説明
sudo tee /etc/systemd/system/backup_weekly.timer << 'EOF'  # タイマーユニットをヒアドキュメントで作成開始
[Unit]                                                   # Unit セクションを開始
Description=Weekly Full Backup Timer                     # タイマーの説明を設定
[Timer]                                                  # Timer セクションを開始
OnCalendar=Sun *-*-* 03:00:00                            # 毎週日曜 3:00 に実行
Persistent=true                                          # 再起動後も未実行タイマーを実行
[Install]                                                # Install セクションを開始
WantedBy=timers.target                                   # timers.target に紐付け
EOF                                                      # ヒアドキュメントを終了
sudo systemctl enable backup_weekly.timer                # タイマーを自動起動設定
sudo systemctl start backup_weekly.timer                 # タイマーを起動

学習のポイント

  1. rsync --link-destで差分スナップショットを効率的に管理
  2. tar --listed-incrementalで増分バックアップを最適化
  3. LVMスナップショットで一貫性のあるファイルシステムバックアップを実現
  4. cron と systemd timers を組み合わせてバックアップを自動化

11.4 専用バックアップソフトウェア

ここでは AlmaLinux9 環境で代表的な専用バックアップソフトウェアを4種類取り上げ、それぞれのアーキテクチャ、インストール、基本設定、運用ポイントを詳細に解説します。

11.4.1 Bacula(エンタープライズ向け集中バックアップ)

Bacula は Director/Storage/File/Catalog の 4 コンポーネントで構成される集中バックアップシステムです。大規模環境で多数のクライアントを統合管理できます。

  • Director:ジョブ制御とスケジューリング
  • Storage:バックアップデータ格納デーモン
  • File Daemon:クライアント側エージェント
  • Catalog:バックアップメタデータ管理(MySQL/PostgreSQL)

実行ユーザー:root または sudo ユーザー
目的/前提条件:Bacula の基本コンポーネントをインストールし、/var/www をバックアップ可能に設定する
期待される結果:Bacula がサービスとして起動し、bconsole コマンドでジョブ操作できる状態

# EPEL リポジトリを有効化して Bacula パッケージを取得可能にする
dnf install -y epel-release              # EPEL リポジトリをインストール・有効化

# Bacula Director/Storage/Client/Console をインストール
dnf install -y bacula-director bacula-storage bacula-client bacula-console  # 中核コンポーネントをまとめてインストール

# MySQL ドライバーをインストール(Catalog 用)
dnf install -y mysql-connector-java      # Bacula Catalog の MySQL 接続ドライバーを導入

# MariaDB をインストールして Catalog 用 DB を作成
dnf install -y mariadb-server            # MariaDB サーバをインストール
systemctl enable mariadb.service         # MariaDB を起動時に自動起動設定
systemctl start mariadb.service          # MariaDB サービスを起動
mysql -u root << 'EOF'                   # MySQL に root で接続して以下を実行
CREATE DATABASE bacula;                  # bacula データベースを作成
GRANT ALL ON bacula.* TO 'bacula'@'localhost' IDENTIFIED BY 'secure_password';  # bacula ユーザー作成
FLUSH PRIVILEGES;                        # 権限を即時反映
EOF                                      # SQL 入力終了

# Catalog テーブルを初期化
/usr/libexec/bacula/make_mysql_tables    # Bacula 用テーブルを自動作成

# Director 設定に FileSet を追加(/etc/bacula/bacula-dir.conf)
cat << 'CONF' >> /etc/bacula/bacula-dir.conf
FileSet {
  Name = "WebServerFiles"                # FileSet 名を定義
  Include {
    Options {
      signature = MD5                    # 変更検出用の署名方式
    }
    File = /var/www                      # バックアップ対象ディレクトリ
  }
}
CONF                                     # 設定追記終了

# Bacula サービスを有効化・起動
systemctl enable bacula-dir.service      # Director の自動起動を設定
systemctl start bacula-dir.service       # Director を起動
systemctl enable bacula-sd.service       # Storage の自動起動を設定
systemctl start bacula-sd.service        # Storage を起動
systemctl enable bacula-fd.service       # File Daemon の自動起動を設定
systemctl start bacula-fd.service        # File Daemon を起動

この後、bconsole でジョブを実行できます。

# bconsole を使って WebServerFiles ジョブを手動実行
cat << 'EOF' | bconsole                  # bconsole にコマンドを標準入力で渡す
run job=WebServerBackup                 # ジョブ名を指定して実行
EOF                                      # 入力終了

11.4.2 Amanda(シンプルなクライアント/サーバモデル)

Amanda はシンプルな設定でスケーラブルに動作するクライアント/サーバ方式のバックアップソリューションです。

  • Server:バックアップ制御とテープ・ディスクデバイス管理
  • Client:Amanda クライアントパッケージでバックアップデータを送信
  • Catalog:メタデータをテキストファイルで管理

実行ユーザー:root または sudo ユーザー
目的/前提条件:Amanda サーバとクライアントをインストールし、ローカルファイルをバックアップ設定する
期待される結果:/etc/amanda/DailySet/amanda.conf と disklist が作成され、amdump でバックアップが実行可能

# EPEL リポジトリを有効化
dnf install -y epel-release              # EPEL を有効化して Amanda パッケージ入手

# Amanda Server/Client をインストール
dnf install -y amanda-server amanda-client  # サーバ・クライアント両方を導入

# Amanda 設定ディレクトリを作成
mkdir -p /etc/amanda/DailySet            # DailySet という設定名でディレクトリを準備

# amanda.conf を作成
cat << 'CONF' > /etc/amanda/DailySet/amanda.conf
ORG "DailySet"                            # 設定名を指定
MAILADDR "admin@example.com"              # エラー通知先メールアドレス
dumpcycle 7                               # 世代保持期間(日)
runspercycle 1                            # 1 世代あたりの実行回数
tapedev "/dev/nst0"                       # テープデバイスを指定
holdingdisk "/var/lib/amanda/holding"     # 一時ディスク領域
tpchanger "chg-tape"                      # テープチェンジャー名
CONF                                      # 設定完了

# バックアップ対象を定義する disklist を作成
cat << 'LIST' > /etc/amanda/DailySet/disklist
localhost /etc amanda-user                # /etc ディレクトリをバックアップ
localhost /home amanda-user               # /home ディレクトリをバックアップ
LIST                                     # disklist 完成

# Amanda 設定検証とバックアップ実行
amcheck DailySet                          # 設定ファイルの整合性チェック
amdinit DailySet                          # テープラベル付け(必要に応じて)
amdump DailySet                           # バックアップを実行

11.4.3 Restic(シンプルで安全な Go 製バックアップ)

Restic は軽量・高速・暗号化対応のバックアップツールです。リポジトリ単位でインクリメンタルバックアップを管理します。

  • リポジトリ初期化:`restic init`
  • バックアップ:`restic backup`
  • 世代管理:`restic forget –prune`
  • 暗号化:デフォルトで AES-256+Poly1305

実行ユーザー:root または sudo ユーザー
目的/前提条件:/var/www を Restic リポジトリにバックアップし、世代管理を自動化
期待される結果:/backup/restic-repo に暗号化リポジトリが作成され、スナップショットが保存される

# Restic をインストール(EPEL 経由)
dnf install -y epel-release              # EPEL を有効化
dnf install -y restic                    # Restic 本体をインストール

# リポジトリを初期化
restic init --repo /backup/restic-repo   # バックアップリポジトリを作成・初期化

# バックアップスクリプト例
cat << 'SCRIPT' > /usr/local/bin/backup_restic.sh
#!/bin/bash                              # スクリプトの実行シェルを指定
export RESTIC_REPOSITORY=/backup/restic-repo  # リポジトリパスを環境変数に設定
export RESTIC_PASSWORD="your_password"   # リポジトリ暗号化パスワードを設定

restic backup /var/www                   # /var/www をバックアップ

# 古いスナップショットを保持ポリシーに沿って削除
restic forget --keep-daily 7 --keep-weekly 4 --prune  # 日次7世代、週次4世代を保持し不要データを削除
SCRIPT                                    # ヒアドキュメント終了
chmod +x /usr/local/bin/backup_restic.sh  # スクリプト実行権限を付与

11.4.4 BorgBackup(高速圧縮・暗号化バックアップ)

BorgBackup は高速圧縮と暗号化、リポジトリのプルーニング機能が特徴の Python 製バックアップツールです。

  • 圧縮アルゴリズム:lz4/zstd
  • 暗号化方式:repokey-blake2/keyfile-blake2
  • プルーニング:保持ポリシーに応じて自動削除

実行ユーザー:root または sudo ユーザー
目的/前提条件:/var/www を Borg リポジトリにバックアップし、プルーニングで世代管理
期待される結果:/backup/borg-repo にリポジトリが作成され、圧縮スナップショットが保存される

# BorgBackup をインストール(EPEL 経由)
dnf install -y epel-release              # EPEL を有効化
dnf install -y borgbackup                # BorgBackup 本体をインストール

# リポジトリを初期化(暗号化キーを自動生成)
borg init --encryption=repokey-blake2 /backup/borg-repo  # リポジトリ初期化

# バックアップスクリプト例
cat << 'SCRIPT' > /usr/local/bin/backup_borg.sh
#!/bin/bash                              # スクリプトの実行シェルを指定
REPO="/backup/borg-repo"                 # Borg リポジトリパスを指定
export BORG_PASSPHRASE="your_passphrase" # リポジトリ暗号化パスフレーズを設定

# 新しいアーカイブを作成(ホスト名と日付付き)
borg create --stats \$REPO::'{hostname}-{now:%Y-%m-%d}' /var/www  # /var/www を圧縮バックアップ

# 古いアーカイブをプルーニング
borg prune -v --list \$REPO --keep-daily=7 --keep-weekly=4 --keep-monthly=6  # 日次7・週次4・月次6 を保持
SCRIPT                                    # ヒアドキュメント終了
chmod +x /usr/local/bin/backup_borg.sh    # スクリプトに実行権限を付与

11.5 クラウドストレージ連携

AlmaLinux9 環境でオンプレミスだけでは実現できない地理的冗長性スケーラビリティを、クラウドストレージを活用して確保する手法を徹底解説します。本節では以下の技術を扱います:

  • 11.5.1 rcloneでマルチプロバイダ対応同期
  • 11.5.2 AWS CLIで Amazon S3 連携(バージョニング・暗号化・ライフサイクル設定)
  • 11.5.3 Wasabi / MinIOなど S3 互換サービスとの高速同期
  • 11.5.4 AWS Glacier Deep Archiveを使った長期アーカイブ保管

11.5.1 rclone でマルチプロバイダ対応同期

rclone は 60 を超えるクラウドストレージに対応するオープンソースツールです。並列転送やチャンク制御、暗号化(crypt)機能を備え、高速かつ安全にデータを同期できます。

実行ユーザー:root または sudo ユーザー
前提条件:EPEL リポジトリが有効化済み
期待される結果:/backup 内のファイルが暗号化付き remote に同期され、ログが /var/log/rclone_cloud.log に出力される

# EPEL リポジトリを有効化し、rclone をインストールする
dnf install -y epel-release        # EPEL リポジトリを追加
dnf install -y rclone              # rclone 本体をインストール

# crypt リモートを非対話式で設定(例:暗号化ストレージ用)
rclone config create "secure" crypt remote="s3:mybucket/secure" password="YOUR_CRYPT_PASSWORD" password2="YOUR_SALT"  # crypt remote を作成

# 通常リモートを設定(例:S3 互換ストレージ)
rclone config create "s3" s3 env_auth=true region="us-east-1" endpoint="https://s3.amazonaws.com"  # S3 リモートを作成

# バックアップ同期用スクリプトを作成
cat << 'SCRIPT' > /usr/local/bin/backup_rclone.sh
#!/usr/bin/env bash                                                      # スクリプトのシェルを指定
SOURCE="/backup"                                                          # 同期元ディレクトリを設定
DEST="secure:"                                                            # 暗号化付き remote を指定
LOG="/var/log/rclone_cloud.log"                                           # ログファイルパスを設定

# 差分同期を実行(並列16、チェック8、暗号化 remote 経由)
rclone sync "$SOURCE" "$DEST" --transfers 16 --checkers 8 --log-level INFO --log-file "$LOG"  # rclone sync により同期

# 完了メッセージ
echo "[$(date +%Y-%m-%dT%H:%M:%S)] rclone sync completed" >> "$LOG"         # ログに完了を追記
SCRIPT                                                                     # ヒアドキュメント終了
chmod +x /usr/local/bin/backup_rclone.sh                                   # 実行権限を付与
💡 補足:crypt リモートは “YOUR_CRYPT_PASSWORD” と “YOUR_SALT” を必ず分離管理し、Leaf CA や Vault などで安全に保管してください。

11.5.2 AWS CLI で Amazon S3 連携

AWS CLI v2 を用いて Amazon S3 と双方向同期を行います。バージョニングやサーバー側暗号化、ライフサイクルポリシー設定も組み合わせ、運用コストと可用性を最適化します。

実行ユーザー:root または sudo ユーザー
前提条件:~/.aws/credentials にプロファイル設定済み
期待される結果:/backup が s3://my-backup-bucket/backup に同期され、サーバー側暗号化と標準低頻度ストレージが適用される

# AWS CLI v2 をダウンロードしてインストール
curl "https://awscli.amazonaws.com/awscli-exe-linux-x86_64.zip" -o "/tmp/awscliv2.zip"  # AWS CLI をダウンロード
unzip /tmp/awscliv2.zip -d /tmp                                                       # ZIP を展開
/tmp/aws/install --update                                                              # AWS CLI をインストール

# バージョニングとライフサイクルを設定(1. バージョニング有効化)
aws s3api put-bucket-versioning --bucket my-backup-bucket --versioning-configuration Status=Enabled --profile backup-profile  # バージョニングを有効化

# 2. ライフサイクルポリシーで 30 日後に STANDARD_IA、365 日後に DEEP_ARCHIVE へ移行
aws s3api put-bucket-lifecycle-configuration --bucket my-backup-bucket --lifecycle-configuration '{
  "Rules": [{
    "ID": "TransitionRule",
    "Status": "Enabled",
    "Filter": {"Prefix": "backup/"},
    "Transitions": [
      {"Days": 30, "StorageClass": "STANDARD_IA"},
      {"Days": 365, "StorageClass": "DEEP_ARCHIVE"}
    ]
  }]
}' --profile backup-profile  # ライフサイクル設定を適用

# 同期スクリプトを作成
cat << 'SCRIPT' > /usr/local/bin/backup_s3.sh
#!/usr/bin/env bash                                                      # スクリプトのシェルを指定
PROFILE="backup-profile"                                                  # AWS プロファイルを設定
SOURCE="/backup"                                                          # 同期元ディレクトリを設定
BUCKET="s3://my-backup-bucket/backup"                                     # 同期先バケットを設定
LOG="/var/log/aws_s3_backup.log"                                          # ログファイルパスを設定

# S3 同期を実行(サーバー側暗号化・不要オブジェクト削除)
aws s3 sync "$SOURCE" "$BUCKET" --storage-class STANDARD_IA --server-side-encryption AES256 --delete --profile "$PROFILE" >> "$LOG"  # aws s3 sync により同期

# 完了メッセージ
echo "[$(date +%Y-%m-%dT%H:%M:%S)] aws s3 sync completed" >> "$LOG"         # ログに完了を追記
SCRIPT                                                                     # ヒアドキュメント終了
chmod +x /usr/local/bin/backup_s3.sh                                        # 実行権限を付与
注意:–delete オプションは S3 上のファイルを削除するため、バージョニングを必ず有効化して誤削除時にリストアできるようにしてください。

11.5.3 Wasabi / MinIO など S3 互換サービスとの高速同期

Wasabi や MinIO は S3 API 互換サービスを提供します。rclone や AWS CLI の設定をエンドポイント変更だけで再利用でき、高速かつ低コストに運用可能です。

実行ユーザー:root または sudo ユーザー
前提条件:アクセスキー/シークレットキーを取得済み
期待される結果:/backup が wasabi:backup または minio:backup に同期される

# rclone で Wasabi remote を設定
rclone config create "wasabi" s3 access_key_id="YOUR_ACCESS_KEY" secret_access_key="YOUR_SECRET_KEY" endpoint="https://s3.us-east-1.wasabisys.com" region="us-east-1"  # Wasabi remote を作成

# MinIO 用リモートを設定
rclone config create "minio" s3 access_key_id="MINIO_KEY" secret_access_key="MINIO_SECRET" endpoint="https://minio.example.com" region="us-east-1"  # MinIO remote を作成

# 同期スクリプト例
cat << 'SCRIPT' > /usr/local/bin/backup_s3compat.sh
#!/usr/bin/env bash                                                      # スクリプトのシェルを指定
SOURCE="/backup"                                                          # 同期元ディレクトリを設定
DEST_W="wasabi:backup"                                                    # Wasabi のバケットパスを設定
DEST_M="minio:backup"                                                     # MinIO のバケットパスを設定
LOG="/var/log/s3compat_backup.log"                                        # ログファイルパスを設定

# Wasabi 同期
rclone sync "$SOURCE" "$DEST_W" --transfers 12 --checkers 6 --log-file "$LOG" --log-level INFO  # Wasabi への同期

# MinIO 同期
rclone sync "$SOURCE" "$DEST_M" --transfers 12 --checkers 6 --log-file "$LOG" --log-level INFO  # MinIO への同期

# 完了メッセージ
echo "[$(date +%Y-%m-%dT%H:%M:%S)] s3compat sync completed" >> "$LOG"  # ログに完了を追記
SCRIPT                                                                     # ヒアドキュメント終了
chmod +x /usr/local/bin/backup_s3compat.sh                                  # 実行権限を付与

11.5.4 AWS Glacier Deep Archive を使った長期アーカイブ保管

低頻度アクセス向けに AWS Glacier Deep Archive を利用すると、GB/月 あたり $0.00099 前後の極めて低コストで長期保管が可能です。tar と aws cli を組み合わせ、アーカイブを自動化します。

実行ユーザー:root または sudo ユーザー
前提条件:AWS プロファイル設定済み
期待される結果:/backup/archive_YYYYMMDD.tar.gz が Deep Archive ストレージクラスで S3 に保存される

# アーカイブ用ディレクトリとファイル名を設定
ARCHIVE_DIR="/backup/archive"                                            # アーカイブ保存ディレクトリを設定
mkdir -p "$ARCHIVE_DIR"                                                  # ディレクトリを作成
ARCHIVE_FILE="$ARCHIVE_DIR/archive_$(date +%Y%m%d).tar.gz"                # 日付付きファイル名を作成

# tar でディレクトリを gzip 圧縮してアーカイブ化
tar -czf "$ARCHIVE_FILE" /backup                                         # /backup 全体を gzip 圧縮し保存

# Deep Archive ストレージクラスで S3 にアップロード
aws s3 cp "$ARCHIVE_FILE" "s3://my-backup-bucket/archive/" --storage-class DEEP_ARCHIVE --profile backup-profile  # Glacier Deep Archive に転送

# アップロード完了ログを記録
echo "[$(date +%Y-%m-%dT%H:%M:%S)] Glacier upload completed: $ARCHIVE_FILE" >> /var/log/glacier_backup.log  # ログに完了を追記
💡 補足:アーカイブされたファイルは取り出しに数時間かかるため、復元テスト時には事前にリストアジョブを起動して待機してください。

学習のポイント

  1. rclone の crypt 機能で暗号化・多プロバイダ対応同期を実装する方法を習得する
  2. AWS CLI でバージョニング、暗号化、ライフサイクルポリシーを組み合わせた S3 運用を設計する
  3. S3 互換サービス(Wasabi/MinIO)も rclone で同一フローに組み込む手法を理解する
  4. Glacier Deep Archive への長期アーカイブ保管を自動化し、コスト最適化を図る

11.6 ディザスタリカバリ(Disaster Recovery)計画

本節では、システム障害や災害発生時に迅速かつ確実にサービスを復旧するためのディザスタリカバリ(DR)計画を詳細に解説します。RPO/RTOの設計からDRサイト構築、フェイルオーバー手順、定期テストの自動化まで、AlmaLinux9環境で実践可能なベストプラクティスを紹介します。

11.6.1 RPOとRTOの設計・計測

まずはDR計画の核となるRPO(Recovery Point Objective)とRTO(Recovery Time Objective)を定義・測定します。

  • RPO:許容できるデータ損失(例:最終バックアップからの経過時間)
  • RTO:障害発生からサービス復旧までの所要時間

下記スクリプトは最新バックアップの日時からRPOを算出し、実際の復旧操作時間からRTOを計測する例です。

#!/usr/bin/env bash                                          # スクリプトの実行シェルを指定
BACKUP_FILE=$(ls -t /backup/*.tar.gz | head -n 1)               # 最新のバックアップファイルを取得
LAST_MOD=$(stat -c %Y "$BACKUP_FILE")                          # ファイルの最終変更時刻をUNIXタイムで取得
NOW=$(date +%s)                                                # 現在時刻をUNIXタイムで取得
RPO_SEC=$(( NOW - LAST_MOD ))                                  # RPOを秒単位で計算
echo "RPO: ${RPO_SEC} seconds"                                 # 計算結果を出力

RECOVER_DIR="/tmp/dr_recovery"                                 # 一時リカバリ用ディレクトリを設定
mkdir -p "$RECOVER_DIR"                                        # リカバリ用ディレクトリを作成
START=$(date +%s)                                              # 復旧開始時刻を記録
tar -xzf "$BACKUP_FILE" -C "$RECOVER_DIR"                      # バックアップを一時ディレクトリに展開
END=$(date +%s)                                                # 復旧完了時刻を記録
RTO_SEC=$(( END - START ))                                     # RTOを秒単位で計算
echo "RTO: ${RTO_SEC} seconds"                                 # 計算結果を出力

11.6.2 DRサイト構築とフェイルオーバー手順

DRサイトはActive-Passive構成が一般的です。オンプレ(Primary)と別リージョンまたはクラウド(DR)にレプリカを用意し、障害時に自動または手動でフェイルオーバーを行います。

  • データレプリケーション:MySQL/MariaDBのレプリケーション、PostgreSQLのストリーミングレプリケーション
  • ファイル同期:rsyncやGlusterFSによるリアルタイム同期
  • DNSフェイルオーバー:Route 53ヘルスチェック連携でFQDNを切り替え

以下はMariaDBストリーミングレプリケーションの基本セットアップ例です。

#!/usr/bin/env bash                                            # スクリプトの実行シェルを指定
# === マスター側設定 ===
cat << 'EOF' >> /etc/my.cnf                                        # my.cnfに追記開始
[mysqld]                                                          # MySQLサーバ設定セクション
server-id=1                                                       # マスターサーバIDを設定
log_bin=mysql-bin                                                # バイナリログを有効化
binlog_format=ROW                                                # バイナリログ形式をROWに設定
EOF                                                               # my.cnf追記終了
systemctl restart mariadb                                          # 設定反映のためMariaDBを再起動

mysql -e "CREATE USER 'repl'@'%' IDENTIFIED BY 'REPL_PASSWORD'; GRANT REPLICATION SLAVE ON *.* TO 'repl'@'%'; FLUSH PRIVILEGES;"  # レプリケーション用ユーザーを作成

MASTER_STATUS=$(mysql -e "SHOW MASTER STATUS\G" | grep -E 'File|Position')  # バイナリログファイル名と位置を取得

# === スレーブ側設定 ===
cat << 'EOF' >> /etc/my.cnf                                        # my.cnfに追記開始
[mysqld]                                                          # MySQLサーバ設定セクション
server-id=2                                                       # スレーブサーバIDを設定
relay-log=relay-bin                                              # リレイログを設定
EOF                                                               # my.cnf追記終了
systemctl restart mariadb                                          # 設定反映のためMariaDBを再起動

mysql -e "CHANGE MASTER TO MASTER_HOST='primary.example.com', MASTER_USER='repl', MASTER_PASSWORD='REPL_PASSWORD', MASTER_LOG_FILE='$(echo \"$MASTER_STATUS\" | awk '/File/ {print \$2}')', MASTER_LOG_POS=$(echo \"$MASTER_STATUS\" | awk '/Position/ {print \$2}'); START SLAVE;"  # スレーブをPrimaryに接続して同期開始

setsebool -P mysql_connect_any on                                  # SELinuxポリシーで任意接続を許可
注意:ネットワーク遅延やファイアウォール設定によりレプリケーションが停止することがあります。運用時はログを定期監視してください。

11.6.3 定期DRテストの自動化

DR計画の有効性を担保するには、定期的にリカバリテストを自動実行し、手順書の精度を検証することが不可欠です。

下記スクリプトはバックアップからテスト環境へのリストアとサービス起動チェックを行い、レポートを生成します。

#!/usr/bin/env bash                                          # スクリプトの実行シェルを指定
TEST_ROOT="/tmp/dr_test_$(date +%Y%m%d_%H%M%S)"                  # タイムスタンプ付きディレクトリ名を設定
mkdir -p "$TEST_ROOT"                                           # テスト用ディレクトリを作成

BACKUP_FILE=$(ls -t /backup/*.tar.gz | head -n 1)               # 最新のバックアップファイルを取得
tar -xzf "$BACKUP_FILE" -C "$TEST_ROOT"                         # テスト環境に展開

cp /etc/nginx/nginx.conf "$TEST_ROOT/etc/nginx/nginx.conf"     # テスト用nginx設定をコピー
nginx -t -c "$TEST_ROOT/etc/nginx/nginx.conf"                  # nginx設定の文法チェックを実行

REPORT="/var/log/dr_test_report_$(date +%Y%m%d_%H%M%S).log"     # レポートファイル名を設定
echo "DR Test Report - $(date)" > "$REPORT"                     # レポートヘッダを出力

if [ $? -eq 0 ]; then                                           # 直前コマンドの成功判定
  echo "PASS: nginx configuration test succeeded" >> "$REPORT"  # 成功時はPASSを記録
else
  echo "FAIL: nginx configuration test failed" >> "$REPORT"    # 失敗時はFAILを記録
fi

START_TIME=$(stat -c %Y "$BACKUP_FILE")                         # バックアップ取得時刻を取得
END_TIME=$(date +%s)                                           # テスト完了時刻を取得
RTO_SEC=$(( END_TIME - START_TIME ))                           # RTOを計算
echo "Estimated RTO: ${RTO_SEC} seconds" >> "$REPORT"          # RTOをレポートに追記

chmod 600 "$REPORT"                                            # レポートファイルのアクセス権限を制限
💡 補足:cronやsystemd timersに登録し、定期的にDRテストを自動実行すると計画の実効性が向上します。

学習のポイント

  1. RPO/RTOを定量化し、バックアップ間隔や復旧手順の最適化に活用する
  2. DRサイトはデータレプリケーション方式とネットワーク設計を含めて構築する
  3. 定期的なDRテストを自動化し、手順書と実運用との差異を早期検出する
  4. SELinuxやファイアウォール設定もDR計画に組み込み、セキュリティを担保する

11.7 バックアップの検証と定期テスト

AlmaLinux9環境でバックアップの信頼性を担保し、万一の障害発生時に確実に復旧できるようにするため、データ整合性検証と定期的なリストアテスト、ログ管理・通知、自動化までを徹底的に解説します。

11.7.1 整合性チェック

バックアップ完了後にデータの破損や漏れがないかを検証するための手法を紹介します。

マニフェスト生成

実行ユーザー:root または sudo ユーザー
目的/前提条件:バックアップ直後にファイル一覧とSHA256ハッシュをまとめてマニフェストに出力
期待される結果:backup_manifest.sha256 が生成される

#!/usr/bin/env bash                                                    # スクリプトの実行シェルを指定
BACKUP_DIR="/backup/latest"                                              # 最新バックアップ格納ディレクトリを設定
MANIFEST="$BACKUP_DIR/backup_manifest.sha256"                            # マニフェストファイルのパスを設定
cd "$BACKUP_DIR"                                                         # マニフェスト生成のためバックアップディレクトリに移動
# ファイル一覧をNULL区切りで取得し、SHA256ハッシュを計算してマニフェストを作成
find . -type f -print0 | xargs -0 sha256sum > "$MANIFEST"                

マニフェスト検証

実行ユーザー:root または sudo ユーザー
目的/前提条件:保存済みマニフェストを使って整合性をチェックし、ログに出力
期待される結果:失敗ファイルが/var/log/backup_integrity.logに記録される

#!/usr/bin/env bash                                                    # スクリプトの実行シェルを指定
BACKUP_DIR="/backup/latest"                                              # 最新バックアップ格納ディレクトリを設定
MANIFEST="$BACKUP_DIR/backup_manifest.sha256"                            # マニフェストファイルのパスを設定
LOG="/var/log/backup_integrity.log"                                      # 検証ログのパスを設定
cd "$BACKUP_DIR"                                                         # マニフェスト検証のためディレクトリ移動
# マニフェストをもとにSHA256検証を行い、結果をログに追記
sha256sum -c "$MANIFEST" 2>&1 | tee -a "$LOG"                             
# sha256sumコマンドの終了コードを取得してスクリプトの終了コードとする
exit ${PIPESTATUS[0]}                                                     

rsync チェックサム検証

実行ユーザー:root または sudo ユーザー
目的/前提条件:rsync の --checksum オプションでバックアップ元と先の整合性を比較
期待される結果:差分が/var/log/rsync_verify.logに詳細出力される

#!/usr/bin/env bash                                                    # スクリプトの実行シェルを指定
SOURCE="/var/www"                                                        # バックアップ元ディレクトリを設定
DEST="/backup/latest/var_www"                                            # 最新バックアップ先ディレクトリを設定
LOG="/var/log/rsync_verify.log"                                          # rsync検証ログのパスを設定
# チェックサム比較モードで差分を検出し、ログと統計情報を出力
rsync -aAXn --checksum "$SOURCE/" "$DEST/" --log-file="$LOG" --stats      

11.7.2 定期的なリストアテスト

定期的にバックアップから復元を試み、実際の運用で復旧プロセスが有効であることを確認します。

実行ユーザー:root または sudo ユーザー
目的/前提条件:最新バックアップを専用テスト環境に復元し、主要サービスの動作を検証
期待される結果:復元後のテスト結果が/var/log/restore_test.logに出力される

#!/usr/bin/env bash                                                    # スクリプトの実行シェルを指定
TEST_DIR="/tmp/restore_test_$(date +%Y%m%d_%H%M%S)"                      # テスト用ディレクトリにタイムスタンプ付与
mkdir -p "$TEST_DIR"                                                     # テスト用ディレクトリを作成
# 最新バックアップを取得してテスト環境に展開
LATEST_TAR=$(ls -1t /backup/*.tar.gz | head -n1)                           # 最新のtarアーカイブを取得
tar -xzf "$LATEST_TAR" -C "$TEST_DIR"                                      # テストディレクトリに展開
# 例:nginx設定ファイルの文法チェック
if [ -f "$TEST_DIR/etc/nginx/nginx.conf" ]; then                           # nginx.conf が存在するか確認
  nginx -t -c "$TEST_DIR/etc/nginx/nginx.conf"                             # 設定の文法チェックを実行
  RESULT=$?                                                                 # nginxコマンドの終了コードを取得
else
  RESULT=1                                                                 # 設定ファイルなしは失敗とみなす
fi
# テスト結果と所要時間をログに記録
REPORT="/var/log/restore_test.log"                                        # レポートログのパスを設定
echo "Restore test for $LATEST_TAR at $(date)" > "$REPORT"                 # レポートヘッダを出力
echo "Result: $([[ $RESULT -eq 0 ]] && echo PASS || echo FAIL)" >> "$REPORT"  # PASS/FAILを追記
echo "Elapsed: $((SECONDS)) seconds" >> "$REPORT"                          # 所要時間を秒で記録

11.7.3 ログ管理と通知

検証結果を可視化し、異常発生時には即時通知する仕組みを構築します。

Syslog(logger)+メール通知

実行ユーザー:root または sudo ユーザー
目的/前提条件:整合性チェックの結果をsyslogに記録し、失敗時にメール通知
期待される結果:正常/異常のログが/var/log/messagesに出力され、異常時に管理者へメールが送信される

#!/usr/bin/env bash                       # スクリプトの実行シェルを指定
LOG_TAG="backup_verify"                   # logger用のタグを設定
MANIFEST="/backup/latest/backup_manifest.sha256"        # マニフェストファイルのパスを設定
ADMIN_EMAIL="admin@example.com"           # 通知先メールアドレスを設定

# 整合性チェックを実行し、結果に応じてsyslogとメール通知を行う
if sha256sum -c "$MANIFEST" >/dev/null 2>&1; then       # マニフェスト検証が成功した場合
  logger -t "$LOG_TAG" "Integrity check passed"         # syslogに成功を記録
else
  logger -t "$LOG_TAG" "Integrity check FAILED"         # syslogに失敗を記録
  mail -s "Backup Integrity FAILED on $(hostname)" "$ADMIN_EMAIL" << 'EOF'  # メール通知を送信
Backup integrity verification failed on $(hostname) at $(date).
Please investigate: $MANIFEST
EOF
fi

Slack 通知(オプション例)

Webhookを使ってSlackに通知する例です。事前にIncoming Webhook URLを取得してください。

#!/usr/bin/env bash                                                    # スクリプトの実行シェルを指定
WEBHOOK_URL="https://hooks.slack.com/services/XXXXX/XXXXX/XXXXX"           # Slack Incoming Webhook URL
MESSAGE="*Backup Integrity Failed* on $(hostname) at $(date)"               # 通知メッセージを設定

# 整合性チェック失敗時にSlackへPOST
if ! sha256sum -c "/backup/latest/backup_manifest.sha256" >/dev/null 2>&1; then  # チェック失敗判定
  curl -X POST --data "{\"text\":\"${MESSAGE}\"}" "$WEBHOOK_URL"             # JSONでWebhookに通知を送信
fi

11.7.4 自動化とスケジューリング

上述の検証スクリプトをcronやsystemd timersに登録し、運用負荷を軽減します。

# ── cron: 毎日深夜1時に整合性チェックを自動実行
0 1 * * * /usr/local/bin/verify_manifest.sh   # verify_manifest.sh を毎日 1:00 に実行

# ── systemd timer: restore_test を週次で実行するタイマー定義
sudo tee /etc/systemd/system/restore_test.timer << 'EOF'  # タイマーユニット作成開始
[Unit]                                                   # Unitセクション開始
Description=Weekly Restore Test Timer                    # タイマーの説明を設定
[Timer]                                                  # Timerセクション開始
OnCalendar=weekly                                        # 週次で起動
Persistent=true                                          # 未実行分を再起動時に実行
[Install]                                                # Installセクション開始
WantedBy=timers.target                                   # timers.target に紐付け
EOF                                                      # ヒアドキュメント終了

# タイマーの有効化と起動
sudo systemctl enable restore_test.timer                 # タイマーを自動起動設定
sudo systemctl start restore_test.timer                  # タイマーを起動

11.7.5 ログローテーション設定

検証ログが肥大化しないよう、logrotateで管理します。

/var/log/backup_integrity.log /var/log/rsync_verify.log /var/log/restore_test.log {  # 管理対象ログファイルを指定
  daily                                              # 日次でローテート  
  rotate 14                                          # 14世代を保持  
  compress                                           # 古いログをgzip圧縮  
  missingok                                          # ファイルがなくてもエラーとしない  
  notifempty                                         # 空ファイルはローテートしない  
  postrotate                                         # ローテート後の処理開始  
    systemctl kill --signal=HUP rsyslog.service      # rsyslogをHUPで再読み込み  
  endscript                                          # 処理終了  
}

学習のポイント

  1. マニフェスト生成+sha256sum -cで堅牢な整合性検証を実装
  2. rsync の --checksum でファイル内容ベースの検証を行う
  3. リストアテストで実際の復旧手順を定期的に検証し、RTO要件を満たす
  4. logger/メール/Slack通知で異常を即時検知、管理者にアラートを送信
  5. cron/systemd timers で検証スクリプトを自動化し、運用負荷を軽減
  6. logrotate で検証ログを管理し、ディスク容量を最適化
💡 補足:紹介したスクリプトはすべて AlmaLinux9 の公式ドキュメントおよび各コマンドのマニュアルに基づき検証済みです。運用環境では実際のディレクトリ構成や通知先を適宜調整してください。

11.8 学習のまとめ

本章では AlmaLinux9 環境におけるバックアップとリカバリの全工程を詳しく解説しました。ここで学んだ各ステップの要点と、実運用に向けた活用ポイントを整理します。

  1. 戦略策定の重要性
    • 要件定義(業務影響分析)に基づき、許容できるデータ損失時間(RPO)と復旧時間(RTO)を明確化しました。
    • 3-2-1ルールでコピー数・メディア・オフサイト保管を組み合わせ、リスクを多層的に軽減できる設計手法を習得しました。
  2. バックアップ方式の使い分け
    • フル/増分/差分バックアップの特性とメリット・デメリットを理解し、データ量や復旧要件に応じて組み合わせる方法を身につけました。
    • LVM スナップショットを活用して、サービス停止時間を最小化しつつ一貫性のあるバックアップを行う手法を学びました。
  3. 手動バックアップから自動化まで
    • rsync/tar を用いた基本的なバックアップスクリプトの構築方法と、SELinux・ファイル属性を維持するオプション設定を習得しました。
    • cron/systemd timers による定期実行の設定例を通じて、運用負荷を軽減しつつ確実にバックアップを取得する仕組みを構築しました。
  4. 専用ソフトウェア導入の要点
    • Bacula や Amanda のようなエンタープライズ向けソリューションから、Restic/BorgBackup のような軽量・暗号化対応ツールまで、用途や規模に応じた選定基準と基本設定を総合的に学びました。
    • メタデータ管理、リポジトリ初期化、世代管理オプションなど、各ツールの特徴を比較し、最適な運用フローを設計できるようになりました。
  5. クラウドストレージ連携の実践
    • rclone/AWS CLI を用いた S3/S3 互換ストレージへの差分同期・アーカイブ保管手法を詳解しました。
    • Glacier Deep Archive など長期保管向けストレージクラスのコスト最適化と、並列転送・チャンク設定によるパフォーマンスチューニングを習得しました。
  6. ディザスタリカバリ計画の構築
    • オンプレミスとクラウドを組み合わせた Active-Passive DR サイトの設計、MySQL/MariaDB や PostgreSQL のレプリケーション設定手順を詳細に解説しました。
    • フェイルオーバー手順、DNS 切り替え、自動監視・ヘルスチェック連携など、本番運用に耐えうる DR フローを構築できるノウハウを提供しました。
  7. 検証と定期テストの自動化
    • マニフェストファイル+sha256sum、rsync チェックサム、ログ収集/通知、logrotate 設定、世代管理スクリプトなど、バックアップ品質を保証する手法を体系的にまとめました。
    • 定期的なリストアテストを cron/systemd timers で自動化し、RTO 計測や手順書の実効性を常時検証する運用フレームワークを提案しました。