デプロイメント
バックアップとリカバリ
Vaultのデータ保護とディザスタリカバリ
最終更新: 2026/2/17
バックアップとリカバリ
Vaultのデータを保護し、障害時に迅速に復旧するためのバックアップとリカバリ戦略をご紹介します。
バックアップの重要性
Vaultには以下の重要なデータが保存されています:
- シークレット: すべての機密情報
- ポリシー: アクセス制御ルール
- 認証設定: 認証方法の設定
- 監査ログ: すべての操作履歴
- 暗号化キー: データ暗号化に使用
データ損失のリスク適切なバックアップがない場合、以下のリスクがあります:
- ハードウェア障害によるデータ損失
- 人的ミスによる誤削除
- ランサムウェア攻撃
- 自然災害
バックアップの種類
1. Raftスナップショット
用途: Raftストレージバックエンドの完全バックアップ
# スナップショットの作成
vault operator raft snapshot save backup.snap
# スナップショットの情報確認
vault operator raft snapshot inspect backup.snap
出力例:
ID: 2-12345-1704067200
Size: 1234567
Index: 12345
Term: 2
Version: 1
2. ストレージバックエンドのバックアップ
Consulの場合:
# Consulスナップショット
consul snapshot save backup.snap
ファイルシステムの場合:
# データディレクトリのバックアップ
tar -czf vault-data-backup.tar.gz /vault/data/
3. 設定ファイルのバックアップ
# 設定ファイルのバックアップ
cp /etc/vault.d/vault.hcl /backup/vault.hcl.$(date +%Y%m%d)
# TLS証明書のバックアップ
cp -r /vault/tls/ /backup/tls-$(date +%Y%m%d)/
バックアップ戦略
完全バックアップ
頻度: 毎日
#!/bin/bash
# /usr/local/bin/vault-full-backup.sh
BACKUP_DIR="/backup/vault"
DATE=$(date +%Y%m%d-%H%M%S)
# Raftスナップショット
vault operator raft snapshot save "$BACKUP_DIR/raft-$DATE.snap"
# 設定ファイル
cp /etc/vault.d/vault.hcl "$BACKUP_DIR/config-$DATE.hcl"
# TLS証明書
tar -czf "$BACKUP_DIR/tls-$DATE.tar.gz" /vault/tls/
# 監査ログ
cp /var/log/vault/audit.log "$BACKUP_DIR/audit-$DATE.log"
# バックアップの圧縮
tar -czf "$BACKUP_DIR/vault-full-backup-$DATE.tar.gz" \
"$BACKUP_DIR/raft-$DATE.snap" \
"$BACKUP_DIR/config-$DATE.hcl" \
"$BACKUP_DIR/tls-$DATE.tar.gz" \
"$BACKUP_DIR/audit-$DATE.log"
# 個別ファイルの削除
rm "$BACKUP_DIR/raft-$DATE.snap" \
"$BACKUP_DIR/config-$DATE.hcl" \
"$BACKUP_DIR/tls-$DATE.tar.gz" \
"$BACKUP_DIR/audit-$DATE.log"
# 古いバックアップの削除(30日以上前)
find "$BACKUP_DIR" -name "vault-full-backup-*.tar.gz" -mtime +30 -delete
echo "Backup completed: vault-full-backup-$DATE.tar.gz"
増分バックアップ
頻度: 毎時
#!/bin/bash
# /usr/local/bin/vault-incremental-backup.sh
BACKUP_DIR="/backup/vault/incremental"
DATE=$(date +%Y%m%d-%H%M%S)
# Raftスナップショット(軽量)
vault operator raft snapshot save "$BACKUP_DIR/raft-$DATE.snap"
# 圧縮
gzip "$BACKUP_DIR/raft-$DATE.snap"
# 古いバックアップの削除(7日以上前)
find "$BACKUP_DIR" -name "raft-*.snap.gz" -mtime +7 -delete
cronジョブの設定
# crontabの編集
crontab -e
# 完全バックアップ(毎日午前2時)
0 2 * * * /usr/local/bin/vault-full-backup.sh
# 増分バックアップ(毎時)
0 * * * * /usr/local/bin/vault-incremental-backup.sh
リモートバックアップ
AWS S3へのバックアップ
#!/bin/bash
# /usr/local/bin/vault-backup-to-s3.sh
BACKUP_DIR="/backup/vault"
S3_BUCKET="s3://my-vault-backups"
DATE=$(date +%Y%m%d-%H%M%S)
# ローカルバックアップ
vault operator raft snapshot save "$BACKUP_DIR/raft-$DATE.snap"
# S3へアップロード
aws s3 cp "$BACKUP_DIR/raft-$DATE.snap" \
"$S3_BUCKET/raft-$DATE.snap" \
--storage-class STANDARD_IA
# ローカルファイルの削除
rm "$BACKUP_DIR/raft-$DATE.snap"
# S3の古いバックアップを削除(30日以上前)
aws s3 ls "$S3_BUCKET/" | \
awk '{print $4}' | \
while read file; do
file_date=$(echo $file | grep -oP '\d{8}')
if [ ! -z "$file_date" ]; then
days_old=$(( ($(date +%s) - $(date -d "$file_date" +%s)) / 86400 ))
if [ $days_old -gt 30 ]; then
aws s3 rm "$S3_BUCKET/$file"
fi
fi
done
Azure Blob Storageへのバックアップ
#!/bin/bash
# /usr/local/bin/vault-backup-to-azure.sh
BACKUP_DIR="/backup/vault"
CONTAINER="vault-backups"
DATE=$(date +%Y%m%d-%H%M%S)
# ローカルバックアップ
vault operator raft snapshot save "$BACKUP_DIR/raft-$DATE.snap"
# Azureへアップロード
az storage blob upload \
--container-name "$CONTAINER" \
--file "$BACKUP_DIR/raft-$DATE.snap" \
--name "raft-$DATE.snap"
# ローカルファイルの削除
rm "$BACKUP_DIR/raft-$DATE.snap"
GCS(Google Cloud Storage)へのバックアップ
#!/bin/bash
# /usr/local/bin/vault-backup-to-gcs.sh
BACKUP_DIR="/backup/vault"
GCS_BUCKET="gs://my-vault-backups"
DATE=$(date +%Y%m%d-%H%M%S)
# ローカルバックアップ
vault operator raft snapshot save "$BACKUP_DIR/raft-$DATE.snap"
# GCSへアップロード
gsutil cp "$BACKUP_DIR/raft-$DATE.snap" \
"$GCS_BUCKET/raft-$DATE.snap"
# ローカルファイルの削除
rm "$BACKUP_DIR/raft-$DATE.snap"
リカバリ手順
Raftスナップショットからのリストア
1. すべてのノードを停止
# すべてのVaultノードで実行
sudo systemctl stop vault
2. スナップショットのリストア
# リーダーノードで実行
vault operator raft snapshot restore -force backup.snap
3. すべてのノードを起動
# すべてのVaultノードで実行
sudo systemctl start vault
4. アンシール
# すべてのVaultノードで実行
vault operator unseal <key1>
vault operator unseal <key2>
vault operator unseal <key3>
5. 動作確認
# ステータス確認
vault status
# シークレットの確認
vault kv get secret/myapp/config
# Raftピアの確認
vault operator raft list-peers
部分的なリカバリ
特定のシークレットのリストア
# バックアップからシークレットをエクスポート
vault kv get -format=json secret/myapp/config > config-backup.json
# 新しいVaultにインポート
cat config-backup.json | jq -r '.data.data' | \
vault kv put secret/myapp/config -
ポリシーのリストア
# バックアップからポリシーをエクスポート
vault policy read myapp-read > myapp-read-backup.hcl
# 新しいVaultにインポート
vault policy write myapp-read myapp-read-backup.hcl
ディザスタリカバリ
DR(Disaster Recovery)レプリケーション(Enterprise版)
# プライマリクラスターの設定
replication {
resolver_discover_servers = false
}
# DRレプリケーションの有効化
vault write -f sys/replication/dr/primary/enable
# セカンダリトークンの生成
vault write sys/replication/dr/primary/secondary-token id=secondary1
セカンダリクラスター:
# セカンダリクラスターの有効化
vault write sys/replication/dr/secondary/enable token=<secondary-token>
手動DRプロセス
1. 定期的なバックアップ
# プライマリサイトで毎時バックアップ
0 * * * * /usr/local/bin/vault-backup-to-s3.sh
2. セカンダリサイトへの同期
# S3からセカンダリサイトへダウンロード
aws s3 sync s3://my-vault-backups /backup/vault/
3. フェイルオーバー手順
# セカンダリサイトでVaultを起動
sudo systemctl start vault
# 最新のスナップショットをリストア
vault operator raft snapshot restore -force /backup/vault/latest.snap
# アンシール
vault operator unseal <key1>
vault operator unseal <key2>
vault operator unseal <key3>
# DNSまたはロードバランサーを更新
# vault.example.com → secondary-vault.example.com
バックアップの検証
定期的なリストアテスト
#!/bin/bash
# /usr/local/bin/vault-backup-test.sh
BACKUP_FILE="/backup/vault/latest.snap"
TEST_DIR="/tmp/vault-test"
# テスト環境の準備
mkdir -p "$TEST_DIR/data"
# テスト用設定ファイル
cat > "$TEST_DIR/config.hcl" <<EOF
storage "raft" {
path = "$TEST_DIR/data"
node_id = "test"
}
listener "tcp" {
address = "127.0.0.1:8300"
tls_disable = true
}
disable_mlock = true
ui = false
EOF
# Vaultの起動
vault server -config="$TEST_DIR/config.hcl" &
VAULT_PID=$!
sleep 5
# 環境変数の設定
export VAULT_ADDR='http://127.0.0.1:8300'
# 初期化
vault operator init -key-shares=1 -key-threshold=1 > "$TEST_DIR/init.txt"
# アンシール
UNSEAL_KEY=$(grep 'Unseal Key 1:' "$TEST_DIR/init.txt" | awk '{print $NF}')
vault operator unseal "$UNSEAL_KEY"
# Root Tokenの取得
ROOT_TOKEN=$(grep 'Initial Root Token:' "$TEST_DIR/init.txt" | awk '{print $NF}')
export VAULT_TOKEN="$ROOT_TOKEN"
# スナップショットのリストア
vault operator raft snapshot restore -force "$BACKUP_FILE"
# 動作確認
if vault kv get secret/myapp/config > /dev/null 2>&1; then
echo "Backup test PASSED"
exit 0
else
echo "Backup test FAILED"
exit 1
fi
# クリーンアップ
kill $VAULT_PID
rm -rf "$TEST_DIR"
自動テストの設定
# 週次でバックアップテスト(日曜日午前3時)
0 3 * * 0 /usr/local/bin/vault-backup-test.sh
バックアップの暗号化
GPGを使用した暗号化
#!/bin/bash
# /usr/local/bin/vault-encrypted-backup.sh
BACKUP_DIR="/backup/vault"
DATE=$(date +%Y%m%d-%H%M%S)
GPG_RECIPIENT="backup@example.com"
# スナップショットの作成
vault operator raft snapshot save "$BACKUP_DIR/raft-$DATE.snap"
# GPGで暗号化
gpg --encrypt --recipient "$GPG_RECIPIENT" \
"$BACKUP_DIR/raft-$DATE.snap"
# 元のファイルを削除
rm "$BACKUP_DIR/raft-$DATE.snap"
# S3へアップロード
aws s3 cp "$BACKUP_DIR/raft-$DATE.snap.gpg" \
"s3://my-vault-backups/raft-$DATE.snap.gpg"
# ローカルファイルの削除
rm "$BACKUP_DIR/raft-$DATE.snap.gpg"
復号化とリストア
# S3からダウンロード
aws s3 cp "s3://my-vault-backups/raft-20240115.snap.gpg" \
/tmp/raft-20240115.snap.gpg
# 復号化
gpg --decrypt /tmp/raft-20240115.snap.gpg > /tmp/raft-20240115.snap
# リストア
vault operator raft snapshot restore -force /tmp/raft-20240115.snap
バックアップのベストプラクティス
1. 3-2-1ルール
- 3: 3つのコピーを保持
- 2: 2つの異なるメディアに保存
- 1: 1つはオフサイトに保存
コピー1: プライマリサイトのローカルストレージ
コピー2: プライマリサイトのS3
コピー3: セカンダリサイトのS3
2. 定期的なテスト
# 月次でリストアテスト
0 3 1 * * /usr/local/bin/vault-backup-test.sh
3. バックアップの保持期間
| バックアップタイプ | 保持期間 |
|---|---|
| 毎時バックアップ | 7日 |
| 毎日バックアップ | 30日 |
| 毎週バックアップ | 90日 |
| 毎月バックアップ | 1年 |
4. 監視とアラート
# バックアップの成功/失敗を監視
if [ $? -eq 0 ]; then
echo "Backup successful" | mail -s "Vault Backup Success" admin@example.com
else
echo "Backup failed" | mail -s "Vault Backup FAILED" admin@example.com
fi
トラブルシューティング
スナップショットが破損している
確認:
# スナップショットの検証
vault operator raft snapshot inspect backup.snap
解決策:
- 別のバックアップを使用
- 増分バックアップから復元
リストア後にデータが見つからない
確認事項:
# Raftピアの確認
vault operator raft list-peers
# ログの確認
sudo journalctl -u vault -f
解決策:
- 正しいスナップショットを使用しているか確認
- すべてのノードがアンシールされているか確認
次のステップ
バックアップとリカバリを理解したら、次は監視でVaultの運用監視を学びましょう。
バックアップの重要性バックアップは保険です。障害が発生する前に、適切なバックアップ戦略を実装し、定期的にテストしてください。