インフラエンジニアの羅針盤

インフラエンジニア1〜3年目のための技術ガイド

AlmaLinux 10 総合ガイド 第9章: バックアップと運用の基礎

公開更新

AlmaLinux 10 総合ガイド
第9章: バックアップと運用の基礎

【この章で学ぶこと】 データ保護、バックアップ戦略、日常運用
【なぜ重要か】 データ損失は業務停止に直結する
【前提知識】 第8章完了、ファイルシステムの理解
【所要時間】 約2.5時間

サーバー運用において、最も恐れるべき事態は何でしょうか。サービス停止?それも困りますが、再起動すれば復旧できることが多いです。本当に恐ろしいのはデータの消失です。

ハードディスクは必ず壊れます。これは「もし壊れたら」ではなく「いつ壊れるか」の問題です。人間はミスをします。rm -rfコマンドを誤った場所で実行してしまうことは、ベテランエンジニアでも起こり得ます。ランサムウェアに感染すれば、データは暗号化されてしまいます。

こうした事態に備える唯一の方法がバックアップです。この章では、tarとrsyncを使ったバックアップの実践、リストアテストの重要性、そしてバックアップを含む日常運用の基礎を学びます。

目次
  1. 9.1 バックアップの重要性
    1. 9.1.1 なぜバックアップが必要なのか
    2. 9.1.2 3-2-1ルール(バックアップの基本原則)
    3. 9.1.3 RPOとRTO(目標復旧時点・目標復旧時間)
  2. 9.2 バックアップ戦略
    1. 9.2.1 フルバックアップ
    2. 9.2.2 増分バックアップ
    3. 9.2.3 差分バックアップ
    4. 9.2.4 バックアップ対象の選定
    5. 9.2.5 バックアップスケジュールの設計
  3. 9.3 tarによるアーカイブ作成
    1. 9.3.1 tarの復習(第2章の応用)
    2. 9.3.2 バックアップ用のtar作成
    3. 9.3.3 除外オプション(–exclude)
    4. 9.3.4 バックアップの検証(-t オプション)
    5. 9.3.5 実践例: /etc ディレクトリのバックアップ
  4. 9.4 rsyncによる同期バックアップ
    1. 9.4.1 rsyncとは何か
    2. 9.4.2 rsyncの基本構文
    3. 9.4.3 ローカル同期の実践
    4. 9.4.4 主要なオプション
    5. 9.4.5 リモートサーバーへの同期(SSH経由)
    6. 9.4.6 実践例: Webコンテンツの定期同期
  5. 9.5 リストア手順とテスト
    1. 9.5.1 なぜリストアテストが必要か
    2. 9.5.2 tarアーカイブからのリストア
    3. 9.5.3 rsync同期からのリストア
    4. 9.5.4 部分リストア(特定ファイルのみ)
    5. 9.5.5 リストアテストの定期実施
    6. 9.5.6 リストア手順書の作成
  6. 9.6 バックアップの自動化
    1. 9.6.1 バックアップスクリプトの作成
    2. 9.6.2 cronでの定期実行設定
    3. 9.6.3 バックアップ成功/失敗の通知
    4. 9.6.4 実践例: 毎日深夜のフルバックアップ
  7. 9.7 ログローテーションの設定
    1. 9.7.1 ログローテーションとは
    2. 9.7.2 logrotateの仕組み
    3. 9.7.3 /etc/logrotate.confの構造
    4. 9.7.4 アプリケーション個別の設定(/etc/logrotate.d/)
    5. 9.7.5 ローテーション設定の例
    6. 9.7.6 手動でのローテーション実行とテスト
  8. 9.8 システムメンテナンスの基礎
    1. 9.8.1 定期メンテナンスの重要性
    2. 9.8.2 システムアップデートのタイミング
    3. 9.8.3 不要ファイルのクリーンアップ
    4. 9.8.4 ディスク容量監視
    5. 9.8.5 サービス稼働確認
    6. 9.8.6 メンテナンスウィンドウの設定
  9. 9.9 ドキュメンテーション
    1. 9.9.1 なぜドキュメントが必要か
    2. 9.9.2 システム構成図の作成
    3. 9.9.3 運用手順書の作成
    4. 9.9.4 変更履歴の記録
    5. 9.9.5 ナレッジベースの構築
    6. 【コラム8】バックアップがなくて全データ消失した話(架空)
  10. 章末まとめ
    1. 学んだこと
    2. 重要なコマンド
  11. 練習問題
  12. 次章への橋渡し

9.1 バックアップの重要性

まず、なぜバックアップがこれほど重要なのかを理解しましょう。

9.1.1 なぜバックアップが必要なのか

データ損失が発生する主な原因を見てみましょう。

ハードウェア障害

ハードディスクやSSDには寿命があります。MTBF(平均故障間隔)は100万時間以上と言われますが、これは統計的な数値であり、購入直後に壊れることもあります。RAIDを組んでいても、複数のディスクが同時期に故障する「RAID崩壊」は珍しくありません。

人為的ミス

最も多いデータ損失の原因は人間のミスです。

  • 誤って重要なファイルを削除してしまった
  • 設定ファイルを間違えて上書きした
  • rm -rf /のような致命的なコマンドを実行してしまった
  • 本番環境とテスト環境を間違えた

セキュリティ侵害

ランサムウェアに感染すると、データが暗号化され、身代金を要求されます。不正アクセスによりデータが改ざん・削除されることもあります。

災害

火災、水害、地震などの自然災害により、サーバールーム全体が使用不能になる可能性があります。

🚨 重要: 「うちのサーバーは大丈夫」という考えは危険です。バックアップがなければ、上記のどの事態が発生しても、データは永久に失われます。

9.1.2 3-2-1ルール(バックアップの基本原則)

バックアップの世界で広く知られている原則が3-2-1ルールです。

ルール 意味 理由
3つのコピー オリジナル + 2つのバックアップ 1つのバックアップが壊れても別のバックアップがある
2種類のメディア 異なる種類の記録媒体に保存 同じ障害で両方が壊れることを防ぐ
1つはオフサイト 物理的に離れた場所に保管 災害時に全滅することを防ぐ

実践例:

  • オリジナル: 本番サーバーのデータ
  • バックアップ1: 同じデータセンター内の別サーバー(HDDからSSDへ)
  • バックアップ2: クラウドストレージ(AWS S3、Azure Blob等)

初学者の段階では、まず「定期的なバックアップを取る習慣」を身につけることが重要です。3-2-1ルールの完全な実装は、段階的に目指していきましょう。

9.1.3 RPOとRTO(目標復旧時点・目標復旧時間)

バックアップ戦略を立てる際に重要な2つの指標があります。

RPO(Recovery Point Objective)- 目標復旧時点

「どの時点までのデータを復旧できればよいか」を示します。例えば、RPOが24時間なら、最悪の場合でも24時間前のデータまでは復旧できる必要があります。これは、少なくとも24時間ごとにバックアップを取る必要があることを意味します。

RTO(Recovery Time Objective)- 目標復旧時間

「障害発生からどれくらいの時間で復旧できればよいか」を示します。RTOが4時間なら、障害発生から4時間以内にサービスを復旧させる必要があります。

システム種別 RPOの目安 RTOの目安
社内Webサーバー(開発用) 24時間 8時間(翌営業日)
ECサイト 1時間 1時間
金融システム 数分 数分

本ガイドでは、「日次バックアップ(RPO 24時間)」を基本として解説します。

9.2 バックアップ戦略

バックアップにはいくつかの方式があり、それぞれにメリットとデメリットがあります。

9.2.1 フルバックアップ

対象となるすべてのデータを毎回バックアップする方式です。

メリット:

  • リストアが簡単(最新のバックアップファイルだけで復旧可能)
  • 管理がシンプル

デメリット:

  • 時間がかかる
  • ストレージ容量を大量に消費する

9.2.2 増分バックアップ

前回のバックアップ(フルまたは増分)以降に変更されたファイルのみをバックアップする方式です。

メリット:

  • バックアップ時間が短い
  • ストレージ効率が良い

デメリット:

  • リストアに時間がかかる(フル + すべての増分が必要)
  • 途中の増分が壊れると、それ以降のデータは復旧できない

9.2.3 差分バックアップ

最後のフルバックアップ以降に変更されたファイルをすべてバックアップする方式です。

メリット:

  • リストアが比較的簡単(フル + 最新の差分だけで復旧可能)
  • 増分より復旧が確実

デメリット:

  • 日が経つにつれてバックアップサイズが大きくなる
方式 バックアップ時間 ストレージ使用量 リストアの容易さ
フルバックアップ 長い ◎ 簡単
増分バックアップ 短い △ 複雑
差分バックアップ 中程度 ○ 比較的簡単

💡 初学者へのおすすめ: まずはシンプルな「週次フルバックアップ + 日次差分バックアップ」から始めましょう。複雑な戦略は、運用経験を積んでから検討してください。

9.2.4 バックアップ対象の選定

すべてをバックアップするのは非効率です。重要度に応じて優先順位を付けましょう。

最優先(必ずバックアップ):

  • /etc – システム設定ファイル
  • /home – ユーザーデータ
  • /var/www – Webコンテンツ
  • データベースのダンプファイル
  • アプリケーション固有のデータディレクトリ

優先度中:

  • /var/log – ログファイル(監査上必要な場合)
  • /opt – 追加アプリケーション

優先度低(通常はバックアップ不要):

  • /usr, /bin, /sbin – パッケージから再インストール可能
  • /tmp, /var/tmp – 一時ファイル
  • /var/cache – キャッシュファイル

9.2.5 バックアップスケジュールの設計

以下は、中小規模のサーバーでよく使われるスケジュール例です。

頻度 バックアップ種別 保存期間 実行時間
毎日 設定ファイル(/etc)のフルバックアップ 7日分 深夜3:00
毎週日曜 データ全体のフルバックアップ 4週間分 深夜2:00
毎月1日 月次フルバックアップ 12ヶ月分 深夜1:00

9.3 tarによるアーカイブ作成

第2章でtarの基本を学びました。この節では、バックアップ用途に特化した使い方を習得します。

9.3.1 tarの復習(第2章の応用)

tarコマンドの基本構文を振り返りましょう。

# 基本構文
tar [オプション] -f アーカイブファイル名 対象ファイル/ディレクトリ

主要なオプション:

オプション 意味
-c アーカイブを作成(create)
-x アーカイブを展開(extract)
-t アーカイブの内容を一覧表示
-v 詳細表示(verbose)
-f ファイル名を指定
-p パーミッションを保持
-z gzip圧縮
-J xz圧縮
–zstd zstd圧縮

9.3.2 バックアップ用のtar作成

バックアップでは、いつ作成したかがわかるようにタイムスタンプ付きのファイル名を使用します。

タイムスタンプ付きファイル名

dateコマンドと組み合わせて、自動的に日付入りのファイル名を生成します。

[実行ユーザー: 一般ユーザー(sudo使用)]

# 日付フォーマットの確認
$ date +%Y%m%d
20260115

# 日時まで含める場合
$ date +%Y%m%d_%H%M%S
20260115_030000

# タイムスタンプ付きバックアップの作成
$ sudo tar -czvf /backup/etc-$(date +%Y%m%d).tar.gz /etc
tar: Removing leading `/' from member names
/etc/
/etc/passwd
/etc/shadow
...

上記のコマンドを実行すると、/backup/etc-20260115.tar.gzというファイルが作成されます。

💡 メッセージについて: 「Removing leading `/’ from member names」というメッセージは、アーカイブ内のパスから先頭の/を削除したことを示しています。これは安全のための仕様であり、展開時に誤って/直下に上書きすることを防ぎます。

圧縮オプションの選択

用途に応じて圧縮形式を選択しましょう。

圧縮形式 オプション 拡張子 圧縮率 速度 用途
gzip -z .tar.gz 速い 日常的なバックアップ
xz -J .tar.xz 遅い 長期保存、転送用
zstd –zstd .tar.zst 速い 高速かつ高圧縮が必要な場合

[実行ユーザー: 一般ユーザー(sudo使用)]

# gzip圧縮(標準的な選択)
$ sudo tar -czvf /backup/etc-$(date +%Y%m%d).tar.gz /etc

# xz圧縮(高圧縮率、長期保存向け)
$ sudo tar -cJvf /backup/etc-$(date +%Y%m%d).tar.xz /etc

# zstd圧縮(高速かつ高圧縮)
$ sudo tar --zstd -cvf /backup/etc-$(date +%Y%m%d).tar.zst /etc

9.3.3 除外オプション(–exclude)

バックアップ不要なファイルやディレクトリを除外することで、バックアップサイズと時間を削減できます。

[実行ユーザー: 一般ユーザー(sudo使用)]

# 特定のディレクトリを除外
$ sudo tar -czvf /backup/home-$(date +%Y%m%d).tar.gz \
    --exclude='/home/*/.cache' \
    --exclude='/home/*/tmp' \
    --exclude='/home/*/.local/share/Trash' \
    /home

# ファイルパターンで除外
$ sudo tar -czvf /backup/var-www-$(date +%Y%m%d).tar.gz \
    --exclude='*.log' \
    --exclude='*.tmp' \
    --exclude='node_modules' \
    /var/www

よく除外する対象:

  • キャッシュディレクトリ(.cachenode_modules
  • ログファイル(*.log
  • 一時ファイル(*.tmp/tmp
  • ゴミ箱(.local/share/Trash

9.3.4 バックアップの検証(-t オプション)

バックアップを作成したら、必ず内容を確認しましょう。壊れたバックアップは意味がありません。

[実行ユーザー: 一般ユーザー]

# アーカイブの内容を一覧表示
$ tar -tzvf /backup/etc-20260115.tar.gz | head -20
drwxr-xr-x root/root         0 2026-01-15 03:00 etc/
-rw-r--r-- root/root      2345 2026-01-10 12:00 etc/passwd
-rw------- root/root      1234 2026-01-10 12:00 etc/shadow
-rw-r--r-- root/root       567 2026-01-05 08:00 etc/group
...

# アーカイブの整合性を確認
$ tar -tzf /backup/etc-20260115.tar.gz > /dev/null && echo "OK" || echo "FAILED"
OK

9.3.5 実践例: /etc ディレクトリのバックアップ

実際に/etcディレクトリのバックアップを作成してみましょう。

[実行ユーザー: 一般ユーザー(sudo使用)]

# バックアップディレクトリの作成
$ sudo mkdir -p /backup

# バックアップの作成
$ sudo tar -czvf /backup/etc-$(date +%Y%m%d).tar.gz /etc
tar: Removing leading `/' from member names
etc/
etc/passwd
etc/shadow
etc/group
etc/hosts
... (多数のファイル)

# 作成されたファイルの確認
$ ls -lh /backup/
total 2.5M
-rw-r--r--. 1 root root 2.5M Jan 15 03:00 etc-20260115.tar.gz

# バックアップの検証
$ tar -tzf /backup/etc-20260115.tar.gz | wc -l
1523

9.4 rsyncによる同期バックアップ

rsyncは、ファイルを効率的に同期するためのツールです。tarと異なり、変更されたファイルのみを転送するため、定期的なバックアップに最適です。

9.4.1 rsyncとは何か

rsync(Remote Sync)は、ファイルやディレクトリを同期するツールです。主な特徴は以下のとおりです。

  • 差分転送: 変更された部分のみを転送するため、効率的
  • 属性保持: パーミッション、所有者、タイムスタンプを保持
  • リモート対応: SSH経由でリモートサーバーとの同期が可能
  • 中断再開: 転送が中断しても、途中から再開可能

9.4.2 rsyncの基本構文

# 基本構文
rsync [オプション] 送信元 送信先

# ローカル同期
rsync -av /source/ /destination/

# リモート同期(送信)
rsync -av /local/dir/ user@remote:/remote/dir/

# リモート同期(受信)
rsync -av user@remote:/remote/dir/ /local/dir/

🚨 パスの末尾の「/」に注意:

  • /source/(末尾に/あり): sourceディレクトリの中身を同期
  • /source(末尾に/なし): sourceディレクトリ自体を同期

この違いを間違えると、意図しないディレクトリ構造になります。

9.4.3 ローカル同期の実践

まずはローカルでのディレクトリ同期を試してみましょう。

[実行ユーザー: 一般ユーザー]

# テスト用ディレクトリの作成
$ mkdir -p ~/test-source ~/test-backup
$ echo "Hello World" > ~/test-source/file1.txt
$ echo "Test Data" > ~/test-source/file2.txt

# 同期の実行
$ rsync -av ~/test-source/ ~/test-backup/
sending incremental file list
./
file1.txt
file2.txt

sent 234 bytes  received 57 bytes  582.00 bytes/sec
total size is 23  speedup is 0.08

# 結果の確認
$ ls -la ~/test-backup/
total 16
drwxr-xr-x. 2 developer developer 4096 Jan 15 10:00 .
drwx------. 5 developer developer 4096 Jan 15 10:00 ..
-rw-r--r--. 1 developer developer   12 Jan 15 10:00 file1.txt
-rw-r--r--. 1 developer developer   10 Jan 15 10:00 file2.txt

2回目以降の同期では、変更されたファイルのみが転送されます。

[実行ユーザー: 一般ユーザー]

# ファイルを追加
$ echo "New File" > ~/test-source/file3.txt

# 再度同期(変更分のみ転送される)
$ rsync -av ~/test-source/ ~/test-backup/
sending incremental file list
file3.txt

sent 145 bytes  received 35 bytes  360.00 bytes/sec
total size is 32  speedup is 0.18

9.4.4 主要なオプション

実務でよく使うオプションを紹介します。

オプション 意味 説明
-a アーカイブモード -rlptgoDの組み合わせ。パーミッション、タイムスタンプ等を保持
-v 詳細表示 処理中のファイル名を表示
-z 圧縮転送 転送中にデータを圧縮(リモート転送時に有効)
–delete 削除の同期 送信元で削除されたファイルを送信先でも削除
-n, –dry-run ドライラン 実際には転送せず、何が行われるかを表示
-e リモートシェル指定 SSH接続に使用(例: -e ssh)
–progress 進捗表示 転送の進捗状況を表示

–deleteオプションの注意点

--deleteは送信元と送信先を完全に同期させるオプションです。送信元で削除されたファイルは、送信先でも削除されます。

🚨 –deleteオプションは慎重に: 誤った送信元を指定すると、バックアップ先のファイルが全て削除される可能性があります。必ず--dry-runで確認してから実行してください。

[実行ユーザー: 一般ユーザー]

# --dry-run で事前確認(実際には何も変更されない)
$ rsync -av --delete --dry-run ~/test-source/ ~/test-backup/
sending incremental file list
deleting file2.txt

sent 78 bytes  received 19 bytes  194.00 bytes/sec
total size is 21  speedup is 0.22 (DRY RUN)

# 問題なければ実際に実行
$ rsync -av --delete ~/test-source/ ~/test-backup/

9.4.5 リモートサーバーへの同期(SSH経由)

rsyncはSSH経由でリモートサーバーとファイルを同期できます。

[実行ユーザー: 一般ユーザー]

# ローカル → リモートへの同期
$ rsync -avz -e ssh /var/www/html/ user@backup-server:/backup/www/

# リモート → ローカルへの同期
$ rsync -avz -e ssh user@backup-server:/backup/www/ /var/www/html/

# SSHポートを指定する場合
$ rsync -avz -e "ssh -p 2222" /var/www/html/ user@backup-server:/backup/www/

SSHキー認証の設定

自動バックアップを行うには、パスワードなしでSSH接続できるよう、公開鍵認証を設定しておく必要があります(第7章参照)。

9.4.6 実践例: Webコンテンツの定期同期

Webサーバーのコンテンツをバックアップサーバーに同期する例です。

[実行ユーザー: 一般ユーザー(sudo使用)]

# ローカルバックアップ(同一サーバー内)
$ sudo rsync -av --delete /var/www/html/ /backup/www/
sending incremental file list
./
index.html
styles.css
images/
images/logo.png

sent 12,345 bytes  received 234 bytes  25,158.00 bytes/sec
total size is 50,234  speedup is 3.99

# 圧縮転送でリモートサーバーへバックアップ
$ sudo rsync -avz --delete -e ssh /var/www/html/ backup@192.168.1.100:/backup/www/

9.5 リストア手順とテスト

バックアップは取って終わりではありません。リストア(復元)できなければ意味がないのです。

9.5.1 なぜリストアテストが必要か

「バックアップはあるが、リストアできない」という悲劇は実際に起こります。

よくある失敗:

  • バックアップファイルが破損していた
  • 必要なファイルがバックアップに含まれていなかった
  • リストア手順が分からない(ドキュメントがない)
  • リストアに必要なツールやパスワードが不明
  • リストアに時間がかかりすぎてRTOを満たせない

定期的なリストアテストは、これらの問題を事前に発見するために不可欠です。

9.5.2 tarアーカイブからのリストア

tarアーカイブからファイルを復元する方法を学びましょう。

全体リストア

[実行ユーザー: 一般ユーザー(sudo使用)]

# 展開先ディレクトリを作成
$ sudo mkdir -p /restore/test

# アーカイブを展開
$ sudo tar -xzvf /backup/etc-20260115.tar.gz -C /restore/test/
etc/
etc/passwd
etc/shadow
...

# 展開結果の確認
$ ls -la /restore/test/etc/
total 1024
drwxr-xr-x. 78 root root 4096 Jan 15 03:00 .
drwxr-xr-x.  3 root root 4096 Jan 15 10:00 ..
-rw-r--r--.  1 root root 2345 Jan 10 12:00 passwd
...

9.5.3 rsync同期からのリストア

rsyncバックアップからの復元は、逆方向に同期するだけです。

[実行ユーザー: 一般ユーザー(sudo使用)]

# バックアップから本番へ復元
$ sudo rsync -av /backup/www/ /var/www/html/
sending incremental file list
./
index.html
styles.css
...

sent 12,345 bytes  received 234 bytes  25,158.00 bytes/sec
total size is 50,234  speedup is 3.99

9.5.4 部分リストア(特定ファイルのみ)

アーカイブ全体ではなく、特定のファイルだけを復元することもできます。

[実行ユーザー: 一般ユーザー(sudo使用)]

# アーカイブ内の特定ファイルを確認
$ tar -tzvf /backup/etc-20260115.tar.gz | grep passwd
-rw-r--r-- root/root      2345 2026-01-10 12:00 etc/passwd

# 特定ファイルのみを展開
$ sudo tar -xzvf /backup/etc-20260115.tar.gz -C /restore/test/ etc/passwd
etc/passwd

# 現在のファイルと比較
$ diff /etc/passwd /restore/test/etc/passwd

9.5.5 リストアテストの定期実施

リストアテストは定期的に実施すべきです。以下のスケジュールを推奨します。

テスト種別 頻度 内容
バックアップ整合性確認 毎日(自動) tarの-tオプションでアーカイブの読み取り確認
部分リストアテスト 週次 ランダムなファイルを数個復元して確認
フルリストアテスト 月次または四半期 テスト環境で完全復元を実施

9.5.6 リストア手順書の作成

障害発生時にパニックにならないよう、リストア手順書を事前に作成しておきましょう。

リストア手順書のテンプレート:

## リストア手順書

### 1. 前提条件
- バックアップファイルの場所: /backup/
- 必要な権限: root権限
- 所要時間目安: 約30分

### 2. 事前確認
- バックアップファイルが存在するか確認
- ディスク空き容量の確認

### 3. リストア手順

#### 3.1 設定ファイルのリストア
```bash
$ sudo tar -xzvf /backup/etc-YYYYMMDD.tar.gz -C /
```

#### 3.2 Webコンテンツのリストア
```bash
$ sudo rsync -av /backup/www/ /var/www/html/
```

### 4. 復旧後の確認
- サービスの起動確認
- 動作テスト

### 5. 連絡先
- 担当者: xxx
- 電話: xxx-xxxx-xxxx

9.6 バックアップの自動化

手動バックアップは忘れがちです。cronを使って自動化しましょう。

9.6.1 バックアップスクリプトの作成

実用的なバックアップスクリプトを作成します。

[実行ユーザー: 一般ユーザー(sudo使用)]

# スクリプト保存用ディレクトリの作成
$ sudo mkdir -p /usr/local/sbin

# バックアップスクリプトの作成
$ sudo vim /usr/local/sbin/daily-backup.sh
#!/bin/bash
#
# daily-backup.sh - 日次バックアップスクリプト
# 使用方法: sudo /usr/local/sbin/daily-backup.sh
#

set -e  # エラー発生時に停止

# ====================
# 設定
# ====================
BACKUP_DIR="/backup"
DATE=$(date +%Y%m%d)
LOG_FILE="/var/log/backup.log"
RETENTION_DAYS=7

# ====================
# 関数定義
# ====================
log() {
    echo "$(date '+%Y-%m-%d %H:%M:%S') - $1" | tee -a "$LOG_FILE"
}

error_exit() {
    log "ERROR: $1"
    exit 1
}

# ====================
# メイン処理
# ====================
log "========== バックアップ開始 =========="

# バックアップディレクトリの確認
if [ ! -d "$BACKUP_DIR" ]; then
    mkdir -p "$BACKUP_DIR" || error_exit "バックアップディレクトリの作成に失敗"
fi

# /etc のバックアップ
log "/etc バックアップ開始"
tar -czf "${BACKUP_DIR}/etc-${DATE}.tar.gz" /etc 2>/dev/null || error_exit "/etc バックアップ失敗"
log "/etc バックアップ完了: etc-${DATE}.tar.gz"

# バックアップの検証
log "バックアップファイルの検証"
tar -tzf "${BACKUP_DIR}/etc-${DATE}.tar.gz" > /dev/null || error_exit "バックアップファイルが破損"
log "検証完了: バックアップファイルは正常"

# 古いバックアップの削除
log "古いバックアップの削除(${RETENTION_DAYS}日以上前)"
find "$BACKUP_DIR" -name "*.tar.gz" -mtime +${RETENTION_DAYS} -delete
log "古いバックアップの削除完了"

# 完了
log "========== バックアップ完了 =========="
log "バックアップサイズ: $(du -h ${BACKUP_DIR}/etc-${DATE}.tar.gz | cut -f1)"
log "ディスク空き容量: $(df -h $BACKUP_DIR | tail -1 | awk '{print $4}')"

exit 0

[実行ユーザー: 一般ユーザー(sudo使用)]

# 実行権限の付与
$ sudo chmod 750 /usr/local/sbin/daily-backup.sh

# テスト実行
$ sudo /usr/local/sbin/daily-backup.sh
2026-01-15 10:00:00 - ========== バックアップ開始 ==========
2026-01-15 10:00:00 - /etc バックアップ開始
2026-01-15 10:00:02 - /etc バックアップ完了: etc-20260115.tar.gz
2026-01-15 10:00:02 - バックアップファイルの検証
2026-01-15 10:00:03 - 検証完了: バックアップファイルは正常
2026-01-15 10:00:03 - 古いバックアップの削除(7日以上前)
2026-01-15 10:00:03 - 古いバックアップの削除完了
2026-01-15 10:00:03 - ========== バックアップ完了 ==========
2026-01-15 10:00:03 - バックアップサイズ: 2.5M
2026-01-15 10:00:03 - ディスク空き容量: 45G

9.6.2 cronでの定期実行設定

作成したスクリプトをcronで毎日深夜3時に実行するよう設定します。

[実行ユーザー: 一般ユーザー(sudo使用)]

# rootのcrontabを編集
$ sudo crontab -e

以下の行を追加:

# 毎日午前3時にバックアップを実行
0 3 * * * /usr/local/sbin/daily-backup.sh

[実行ユーザー: 一般ユーザー(sudo使用)]

# 設定の確認
$ sudo crontab -l
0 3 * * * /usr/local/sbin/daily-backup.sh

9.6.3 バックアップ成功/失敗の通知

バックアップの成功・失敗を把握するには、ログを確認するか、通知の仕組みを導入します。

シンプルな方法: メール通知(mailコマンド)

スクリプトの末尾に以下を追加(メールサーバーが設定されている場合):

# バックアップ完了通知
mail -s "バックアップ完了: $(hostname)" admin@example.com < "$LOG_FILE"

より実用的な方法: 外部監視サービスとの連携

本番環境では、監視サービス(Prometheus、Datadog等)と連携して、バックアップの成功/失敗を監視することが一般的です。これは発展的な内容のため、本ガイドでは概要の紹介にとどめます。

9.6.4 実践例: 毎日深夜のフルバックアップ

より実践的なバックアップスクリプトの例を示します。

#!/bin/bash
#
# comprehensive-backup.sh - 包括的バックアップスクリプト
#

set -euo pipefail

# 設定
BACKUP_DIR="/backup"
DATE=$(date +%Y%m%d)
HOSTNAME=$(hostname)
LOG_FILE="/var/log/backup-${DATE}.log"

# ログ関数
log() {
    echo "[$(date '+%Y-%m-%d %H:%M:%S')] $1" | tee -a "$LOG_FILE"
}

# 開始
log "=== $HOSTNAME バックアップ開始 ==="

# 1. システム設定のバックアップ
log "システム設定(/etc)をバックアップ中..."
tar -czf "${BACKUP_DIR}/etc-${DATE}.tar.gz" /etc 2>/dev/null
log "完了: etc-${DATE}.tar.gz"

# 2. ホームディレクトリのバックアップ(キャッシュ除外)
log "ホームディレクトリ(/home)をバックアップ中..."
tar -czf "${BACKUP_DIR}/home-${DATE}.tar.gz" \
    --exclude='/home/*/.cache' \
    --exclude='/home/*/.local/share/Trash' \
    /home 2>/dev/null
log "完了: home-${DATE}.tar.gz"

# 3. Webコンテンツのバックアップ(存在する場合)
if [ -d "/var/www/html" ]; then
    log "Webコンテンツ(/var/www/html)をバックアップ中..."
    tar -czf "${BACKUP_DIR}/www-${DATE}.tar.gz" /var/www/html 2>/dev/null
    log "完了: www-${DATE}.tar.gz"
fi

# 4. 古いバックアップの削除(7日以上前)
log "古いバックアップを削除中..."
find "$BACKUP_DIR" -name "*.tar.gz" -mtime +7 -delete

# 5. バックアップサマリー
log "=== バックアップサマリー ==="
log "バックアップファイル一覧:"
ls -lh "${BACKUP_DIR}"/*-${DATE}.tar.gz 2>/dev/null | while read line; do
    log "  $line"
done
log "ディスク使用量: $(du -sh $BACKUP_DIR | cut -f1)"
log "ディスク空き容量: $(df -h $BACKUP_DIR | tail -1 | awk '{print $4}')"

log "=== バックアップ完了 ==="

9.7 ログローテーションの設定

第8章でログ管理を学びました。この節では、ログファイルが肥大化しないよう管理する「ログローテーション」について詳しく学びます。

9.7.1 ログローテーションとは

ログローテーションとは、ログファイルを定期的に新しいファイルに切り替え、古いログファイルを圧縮・削除する仕組みです。これにより、ディスク容量の枯渇を防ぎます。

ログローテーションの流れ:

  1. 現在のログファイルをリネーム(例: app.log → app.log.1)
  2. 新しい空のログファイルを作成(app.log)
  3. 古いログファイルを圧縮(app.log.1 → app.log.1.gz)
  4. 一定数を超えた古いログファイルを削除

9.7.2 logrotateの仕組み

AlmaLinux 10では、logrotateというツールがログローテーションを担当します。logrotateはcronによって毎日実行されます。

[実行ユーザー: 一般ユーザー]

# logrotateのバージョン確認
$ logrotate --version
logrotate 3.21.0

# logrotateを実行するcronジョブの確認
$ cat /etc/cron.daily/logrotate
#!/bin/sh
/usr/sbin/logrotate /etc/logrotate.conf

9.7.3 /etc/logrotate.confの構造

logrotateのメイン設定ファイルを確認しましょう。

[実行ユーザー: 一般ユーザー]

$ cat /etc/logrotate.conf
# ログローテーションの頻度(週次)
weekly

# 保存する世代数(4世代)
rotate 4

# ローテーション後に新しいログファイルを作成
create

# 圧縮を有効化(必要に応じてコメント解除)
#compress

# /etc/logrotate.d/ 以下の設定ファイルを読み込む
include /etc/logrotate.d

# 特定ファイルの設定
/var/log/wtmp {
    monthly
    create 0664 root utmp
    minsize 1M
    rotate 1
}

/var/log/btmp {
    missingok
    monthly
    create 0600 root utmp
    rotate 1
}

9.7.4 アプリケーション個別の設定(/etc/logrotate.d/)

各アプリケーションの設定は/etc/logrotate.d/ディレクトリに配置されます。

[実行ユーザー: 一般ユーザー]

# 設定ファイル一覧
$ ls /etc/logrotate.d/
dnf  httpd  nginx  rsyslog  samba  syslog

# rsyslogの設定例を確認
$ cat /etc/logrotate.d/rsyslog
/var/log/messages
/var/log/secure
/var/log/maillog
/var/log/spooler
/var/log/cron
{
    sharedscripts
    postrotate
        /usr/bin/systemctl kill -s HUP rsyslog.service >/dev/null 2>&1 || true
    endscript
}

9.7.5 ローテーション設定の例

主要なディレクティブとその意味を解説します。

ディレクティブ 説明
daily / weekly / monthly ローテーション頻度 daily
rotate N 保存する世代数 rotate 7
compress 古いログを圧縮 compress
delaycompress 1世代目は圧縮しない delaycompress
missingok ファイルがなくてもエラーにしない missingok
notifempty 空のファイルはローテーションしない notifempty
create MODE OWNER GROUP 新ファイルのパーミッション指定 create 0640 root adm
postrotate / endscript ローテーション後に実行するコマンド (下記参照)

カスタムアプリケーション用の設定例

[実行ユーザー: 一般ユーザー(sudo使用)]

# カスタムアプリケーション用のlogrotate設定を作成
$ sudo vim /etc/logrotate.d/myapp
/var/log/myapp/*.log {
    daily
    rotate 7
    compress
    delaycompress
    missingok
    notifempty
    create 0640 root root
    postrotate
        systemctl reload myapp > /dev/null 2>&1 || true
    endscript
}

この設定の意味:

  • /var/log/myapp/*.log: 対象ファイル
  • daily: 毎日ローテーション
  • rotate 7: 7世代保存
  • compress: gzipで圧縮
  • delaycompress: 1世代目は圧縮しない(直前のログを読みやすく)
  • missingok: ファイルがなくてもエラーにしない
  • notifempty: 空ファイルはローテーションしない
  • create 0640 root root: 新ファイルを640権限で作成
  • postrotate...endscript: ローテーション後にサービスをリロード

9.7.6 手動でのローテーション実行とテスト

設定が正しいか確認するには、デバッグモードとforceオプションを使用します。

[実行ユーザー: 一般ユーザー(sudo使用)]

# デバッグモード(実際にはローテーションしない)
$ sudo logrotate -d /etc/logrotate.d/myapp
reading config file /etc/logrotate.d/myapp

Handling 1 logs

rotating pattern: /var/log/myapp/*.log  after 1 days (7 rotations)
empty log files are not rotated, old logs are removed
considering log /var/log/myapp/app.log
  log does not need rotating (log is empty)

# 強制実行(テスト用)
$ sudo logrotate -f /etc/logrotate.d/myapp

# 詳細表示付きで実行
$ sudo logrotate -v /etc/logrotate.conf

9.8 システムメンテナンスの基礎

安定したサーバー運用には、定期的なメンテナンスが欠かせません。

9.8.1 定期メンテナンスの重要性

サーバーは放置すると、徐々に問題が蓄積していきます。

  • セキュリティパッチが適用されず、脆弱性が放置される
  • ログファイルやキャッシュでディスクが圧迫される
  • 不要なサービスが動き続け、リソースを消費する
  • 設定の変更履歴が追えなくなる

定期的なメンテナンスで、これらの問題を未然に防ぎましょう。

9.8.2 システムアップデートのタイミング

セキュリティアップデートは速やかに、それ以外のアップデートは計画的に行います。

[実行ユーザー: 一般ユーザー(sudo使用)]

# 利用可能なアップデートを確認
$ sudo dnf5 check-update
Last metadata expiration check: 2:30:00 ago on Wed Jan 15 08:00:00 2026.

kernel.x86_64                    6.12.5-100.el10              baseos
openssl.x86_64                   3.2.1-2.el10                 baseos

# セキュリティアップデートのみ適用
$ sudo dnf5 update --security

# 全アップデートの適用(計画的なメンテナンス時)
$ sudo dnf5 update

アップデートのベストプラクティス:

  • 本番適用前にテスト環境で検証する
  • カーネルアップデート後は再起動が必要
  • アップデート前後でバックアップを取る
  • 変更履歴を記録する

9.8.3 不要ファイルのクリーンアップ

ディスク容量を確保するために、定期的にクリーンアップを行います。

パッケージキャッシュのクリア

[実行ユーザー: 一般ユーザー(sudo使用)]

# キャッシュのサイズを確認
$ du -sh /var/cache/libdnf5/
245M    /var/cache/libdnf5/

# キャッシュをクリア
$ sudo dnf5 clean all
Cleaning up packages and metadata cache.

古い一時ファイルの削除

[実行ユーザー: 一般ユーザー(sudo使用)]

# /tmp の古いファイルを確認(7日以上前)
$ sudo find /tmp -type f -mtime +7 -ls

# 古い一時ファイルを削除
$ sudo find /tmp -type f -mtime +7 -delete

# /var/tmp も同様
$ sudo find /var/tmp -type f -mtime +30 -delete

古いカーネルの削除

[実行ユーザー: 一般ユーザー(sudo使用)]

# インストールされているカーネルを確認
$ rpm -qa kernel
kernel-6.12.4-100.el10.x86_64
kernel-6.12.5-100.el10.x86_64

# 古いカーネルを削除(最新2つを残す)
$ sudo dnf5 remove $(dnf5 repoquery --installonly --latest-limit=-2 -q)

9.8.4 ディスク容量監視

ディスク容量は定期的に確認しましょう。

[実行ユーザー: 一般ユーザー]

# ファイルシステムの使用状況
$ df -h
Filesystem      Size  Used Avail Use% Mounted on
/dev/sda3        50G   15G   33G  32% /
/dev/sda1       500M  150M  350M  30% /boot
/dev/sda4       100G   45G   51G  47% /home

# 大きなディレクトリを特定
$ sudo du -sh /* 2>/dev/null | sort -rh | head -10
15G     /var
8.5G    /usr
3.2G    /home
1.5G    /opt
...

監視の自動化例(簡易スクリプト):

#!/bin/bash
# disk-check.sh - ディスク使用率チェック

THRESHOLD=80

df -h | grep -vE '^Filesystem|tmpfs' | awk '{print $5 " " $6}' | while read usage mount; do
    usage_num=${usage%\%}
    if [ "$usage_num" -ge "$THRESHOLD" ]; then
        echo "警告: $mount が ${usage} 使用中です"
    fi
done

9.8.5 サービス稼働確認

重要なサービスが正常に動作しているか確認します。

[実行ユーザー: 一般ユーザー(sudo使用)]

# 重要なサービスの状態確認
$ sudo systemctl status sshd httpd firewalld --no-pager
● sshd.service - OpenSSH server daemon
     Active: active (running) since ...
● httpd.service - The Apache HTTP Server
     Active: active (running) since ...
● firewalld.service - firewalld - dynamic firewall daemon
     Active: active (running) since ...

# 失敗しているサービスがないか確認
$ sudo systemctl --failed
  UNIT LOAD ACTIVE SUB DESCRIPTION
0 loaded units listed.

9.8.6 メンテナンスウィンドウの設定

定期メンテナンスは、ユーザーへの影響が少ない時間帯に行います。

メンテナンスチェックリスト例:

タスク 頻度 コマンド/手順
セキュリティアップデート確認 毎日 dnf5 check-update --security
ディスク容量確認 毎日 df -h
バックアップ成功確認 毎日 ログファイル確認
システムアップデート 週次 dnf5 update
不要ファイル削除 週次 dnf5 clean all
ログ確認 週次 エラーログの確認
リストアテスト 月次 バックアップからの復元テスト

9.9 ドキュメンテーション

良いサーバー運用には、適切なドキュメントが不可欠です。

9.9.1 なぜドキュメントが必要か

「自分しか分からない」状態は危険です。

  • 担当者が休暇・病気のとき、誰も対応できない
  • 退職時に引き継ぎができない
  • 半年後の自分が「なぜこの設定にしたか」を忘れている
  • 障害発生時にパニックになり、復旧手順を思い出せない

ドキュメントは「将来の自分」と「チームメンバー」へのプレゼントです。

9.9.2 システム構成図の作成

サーバーの構成を視覚的に把握できる図を作成しましょう。

最低限記載すべき情報:

  • サーバー名、IPアドレス
  • OS、主要なソフトウェアとバージョン
  • ネットワーク構成(サブネット、ゲートウェイ)
  • 提供しているサービス(Web、DB等)
  • 依存関係(どのサーバーがどのサーバーに接続するか)

9.9.3 運用手順書の作成

定型作業の手順書を作成しておくと、誰でも同じ品質で作業できます。

バックアップ手順書の例:

## バックアップ運用手順書

### 概要
本書は、サーバー「web-server-01」のバックアップ運用について記載する。

### バックアップスケジュール
- 日次: 毎日 03:00 に自動実行
- 保存期間: 7日間

### バックアップ対象





### 手動バックアップ手順
1. SSHでサーバーにログイン
2. 以下のコマンドを実行:
   ```
   sudo /usr/local/sbin/daily-backup.sh
   ```
3. 実行結果を確認:
   ```
   tail -20 /var/log/backup.log
   ```

### バックアップ確認方法
```bash
ls -lh /backup/
tar -tzf /backup/etc-YYYYMMDD.tar.gz | head
```

### 担当者
- 主担当: 山田太郎 (yamada@example.com)
- 副担当: 鈴木花子 (suzuki@example.com)

### 更新履歴

9.9.4 変更履歴の記録

サーバーに変更を加えたら、必ず記録を残します。

変更履歴の例:

## サーバー変更履歴(web-server-01)

### 2026-01-15 山田太郎
- 作業内容: Apache設定変更(MaxClients: 150 → 200)
- 理由: 同時接続数増加への対応
- 影響: なし(設定リロードのみ)
- ロールバック手順: /etc/httpd/conf.d/mpm.conf を以前の値に戻す

### 2026-01-10 鈴木花子
- 作業内容: セキュリティアップデート適用
- 対象パッケージ: openssl-3.2.1-1 → 3.2.1-2
- 影響: 再起動なし

9.9.5 ナレッジベースの構築

トラブル対応の経験を蓄積し、チームで共有しましょう。

ナレッジ記事の例:

## タイトル: SSHログインが遅い場合の対処

### 症状
- SSHでログインすると、パスワード入力後に10秒以上かかる

### 原因
- DNSの逆引きに時間がかかっている

### 解決方法
/etc/ssh/sshd_config に以下を追加:
```
UseDNS no
```

その後、sshdを再起動:
```
sudo systemctl restart sshd
```

### 発生日
2026-01-10

### 担当者
山田太郎

【コラム8】バックアップがなくて全データ消失した話(架空)

これは、私の知人から聞いた話です(プライバシー保護のため、詳細は変えています)。

Aさんは小さな会社でWebシステムを開発・運用していました。顧客管理システムを載せたサーバーは1台。「いつかバックアップを設定しよう」と思いながら、日々の開発に追われ、そのまま1年が経過しました。

ある月曜日の朝、出社するとサーバーが応答しません。データセンターに連絡すると、「週末にハードディスクが故障しました」との報告。RAIDは組んでいましたが、運悪く2台同時に壊れる「RAID崩壊」が発生していました。

失われたもの:

  • 3年分の顧客データ(約5,000件)
  • 請求書・見積書のPDF
  • システムの設定ファイル
  • 開発中だった新機能のソースコード

復旧業者に依頼しましたが、「物理的な損傷が大きく、復旧は困難」との回答。データは永遠に失われました。

その後、Aさんは顧客に頭を下げて回り、紙の書類から顧客データを再入力する作業に追われました。一部の顧客からは契約を解除され、会社の信用は大きく傷つきました。

Aさんは言いました。「バックアップにかかる時間は1日30分。それをケチった結果、3ヶ月分の復旧作業と、取り戻せない信用を失った」

教訓:

  • バックアップは「保険」です。事故が起きてからでは遅い
  • 「明日やろう」は永遠にやらない。今日設定する
  • RAIDはバックアップではない(同時故障やランサムウェアには無力)
  • バックアップの存在確認とリストアテストを定期的に行う

この話を読んで、「自分のサーバーは大丈夫だろうか」と思った方。今すぐバックアップの設定状況を確認してください。


章末まとめ

この章では、サーバー運用の基礎となるバックアップと日常メンテナンスについて学びました。

学んだこと

  • バックアップの重要性: データ損失の原因と3-2-1ルール、RPO/RTOの概念
  • バックアップ戦略: フル/増分/差分バックアップの違いと使い分け
  • tarによるバックアップ: タイムスタンプ付きファイル名、圧縮オプション、除外設定
  • rsyncによる同期: 差分転送の効率性、–deleteオプションの注意点
  • リストアの実践: 「リストアできなければ意味がない」という原則
  • バックアップ自動化: シェルスクリプトとcronによる定期実行
  • ログローテーション: logrotateの設定方法とディレクティブ
  • システムメンテナンス: アップデート、クリーンアップ、監視の基礎
  • ドキュメンテーション: 手順書、変更履歴、ナレッジベースの重要性

重要なコマンド

目的 コマンド
gzip圧縮アーカイブ作成 tar -czvf archive.tar.gz /path
xz圧縮アーカイブ作成 tar -cJvf archive.tar.xz /path
アーカイブ展開 tar -xzvf archive.tar.gz -C /dest
アーカイブ内容確認 tar -tzvf archive.tar.gz
ディレクトリ同期 rsync -av /src/ /dest/
削除も含めた同期 rsync -av --delete /src/ /dest/
ドライラン rsync -av --dry-run /src/ /dest/
logrotateテスト logrotate -d /etc/logrotate.d/xxx
logrotate強制実行 logrotate -f /etc/logrotate.d/xxx
パッケージキャッシュ削除 dnf5 clean all

練習問題

問題1: /homeディレクトリを、タイムスタンプ付きのgzip圧縮アーカイブとして/backupに作成するコマンドを書いてください。ただし、.cacheディレクトリは除外すること。

解答例を見る
$ sudo tar -czvf /backup/home-$(date +%Y%m%d).tar.gz --exclude='/home/*/.cache' /home

--excludeオプションで.cacheディレクトリを除外し、$(date +%Y%m%d)でタイムスタンプ付きのファイル名を生成しています。

問題2: rsyncで/var/www/html/backup/wwwに同期するコマンドを書いてください。まず--dry-runで確認してから実行する想定で、両方のコマンドを示してください。

解答例を見る
# 1. ドライランで確認
$ sudo rsync -av --delete --dry-run /var/www/html/ /backup/www/

# 2. 問題なければ実際に実行
$ sudo rsync -av --delete /var/www/html/ /backup/www/

パスの末尾の/に注意。/var/www/html/(末尾に/あり)はディレクトリの中身を同期します。

問題3: アプリケーション/var/log/webapp/*.logに対して、以下の要件を満たすlogrotate設定ファイルを作成してください。

  • 日次でローテーション
  • 7世代保存
  • gzip圧縮(ただし直前のログは圧縮しない)
  • 空のログはローテーションしない
  • ファイルがなくてもエラーにしない
解答例を見る
/var/log/webapp/*.log {
    daily
    rotate 7
    compress
    delaycompress
    notifempty
    missingok
    create 0640 root root
}

delaycompressは直前のログ(.log.1)を圧縮せず、次のローテーション時に圧縮します。これにより、直近のログを読みやすくなります。

問題4: 以下のバックアップスクリプトを毎日深夜3時30分に実行するcrontabエントリを書いてください。

スクリプト: /usr/local/sbin/daily-backup.sh

解答例を見る
30 3 * * * /usr/local/sbin/daily-backup.sh

crontabの書式は「分 時 日 月 曜日 コマンド」です。30分、3時、毎日(*)、毎月(*)、毎曜日(*)なので、「30 3 * * *」となります。

rootのcrontabに追加するには、sudo crontab -eを使用します。


次章への橋渡し

この章では、バックアップとシステムメンテナンスの基礎を学びました。これで、サーバーを「運用できる状態」に保つための知識が身につきました。

次の第10章「実践 – 総合演習」では、これまで学んだ知識を統合して、実際のサービスを構築します。LAMP環境の構築、Nginxリバースプロキシの設定、あるいはPodmanを使ったコンテナアプリケーションの実行など、実践的なプロジェクトに挑戦します。

第1章から第9章まで積み重ねてきた知識が、次章でひとつの形になります。「本当に自分でサーバーを構築できた」という達成感を味わってください。そして、その過程で必ずトラブルに遭遇するでしょう。それこそが最高の学びです。

前の記事
次の記事