EBS スナップショットからファイルを復元する

LinuxBeginner
オンラインで実践に進む

はじめに

レポートファイルが削除され、チームはテスト済みのバックアップから復旧する必要があります。架空のレポートデータを用意し、EBS スナップショットを作成してから、練習用ファイルを意図的に削除し、以前の内容を新しいボリュームに復元します。リソースを削除する前に、アプリケーションの復旧後の応答を確認します。

EBS データボリュームの作成、アタッチ、フォーマット、マウントを理解していることが前提です。この独立した環境には専用のイメージ、ネットワーク、キーペアが用意されており、前のラボのリソースを再利用しません。

認定試験との関連

スナップショットによるバックアップと復旧は、AWS Certified Cloud Practitioner CLF-C02 ドメイン 3 の目標にあるタスク 3.6 のストレージ概念の理解に役立ちます。

復旧サーバーを起動する

このステップでは、アプリケーションインスタンスを起動し、そのアベイラビリティーゾーンを確認します。

作業ディレクトリで、用意されたリソース ID を読み込みます。

cd /home/labex/project
source launch.env

recovery-server という名前のインスタンスを 1 台起動します。イメージにはレポートアプリケーションが含まれており、ここではそのデータボリュームを用意します。

aws ec2 \
  run-instances \
  --image-id "$AMI_ID" \
  --instance-type t3.micro \
  --subnet-id "$SUBNET_ID" \
  --security-group-ids "$SECURITY_GROUP_ID" \
  --key-name report-key \
  --count 1 \
  --tag-specifications 'ResourceType=instance,Tags=[{Key=Name,Value=recovery-server}]'

名前タグからインスタンス ID を取得します。

INSTANCE_ID=$(aws ec2 \
  describe-instances \
  --filters Name=tag:Name,Values=recovery-server \
  --query 'Reservations[0].Instances[0].InstanceId' \
  --output text)

インスタンスが実行状態になるまで待ちます。

aws ec2 \
  wait instance-running \
  --instance-ids "$INSTANCE_ID"

アベイラビリティーゾーンは、リージョン内の独立した場所です。EBS ボリュームは同じアベイラビリティーゾーンのインスタンスにアタッチします。ゾーンを推測せず、インスタンスの情報から取得します。

AVAILABILITY_ZONE=$(aws ec2 \
  describe-instances \
  --instance-ids "$INSTANCE_ID" \
  --query 'Reservations[0].Instances[0].Placement.AvailabilityZone' \
  --output text)

状態とゾーンを確認します。

aws ec2 \
  describe-instances \
  --instance-ids "$INSTANCE_ID" \
  --query 'Reservations[].Instances[].{Instance:InstanceId,State:State.Name,Zone:Placement.AvailabilityZone}'

running を確認します。AWS View を開き、Refresh resources をクリックして recovery-server を選択し、Check application をクリックします。ストレージを追加する前に HTTP 200 を確認してください。

元のレポートを用意する

このステップでは、元となるデータボリュームを作成し、バックアップする架空のレポートを書き込みます。

Amazon EBS は EC2 用のブロックストレージを提供します。ボリュームはディスクに相当するリソースで、ファイルシステムはそのディスク上のファイルを整理します。ボリュームをアタッチするとブロックデバイスが利用可能になりますが、ファイルシステムは作成されません。EBS ボリュームガイドでは、アタッチとデータの永続性について説明しています。

小さな空の汎用 SSD ボリュームを作成します。gp3 はボリュームタイプ、--size 1 は 1 GiB の容量を指定し、ゾーン変数はインスタンスと同じゾーンに配置します。後の操作で使うため ID を保存します。

VOLUME_ID=$(aws ec2 \
  create-volume \
  --availability-zone "$AVAILABILITY_ZONE" \
  --size 1 \
  --volume-type gp3 \
  --tag-specifications 'ResourceType=volume,Tags=[{Key=Name,Value=source-report}]' \
  --query 'VolumeId' \
  --output text)

新しいボリュームが利用可能になるまで待ちます。

aws ec2 \
  wait volume-available \
  --volume-ids "$VOLUME_ID"

API のデバイス名 /dev/sdf を使ってアタッチします。

aws ec2 \
  attach-volume \
  --volume-id "$VOLUME_ID" \
  --instance-id "$INSTANCE_ID" \
  --device /dev/sdf

アタッチが完了するまで待ちます。

aws ec2 \
  wait volume-in-use \
  --volume-ids "$VOLUME_ID"

ボリュームとアタッチ情報を確認します。

aws ec2 \
  describe-volumes \
  --volume-ids "$VOLUME_ID" \
  --query 'Volumes[].{Volume:VolumeId,State:State,Zone:AvailabilityZone,Size:Size,Type:VolumeType,Attachments:Attachments}'

in-use、サイズ 1、タイプ gp3、自分のインスタンスへのアタッチを確認します。AWS View を更新し、ボリュームの行を確認してください。ルートボリュームは新しいデータボリュームとは別です。

インスタンスの現在のパブリックアドレスを取得します。

PUBLIC_IP=$(aws ec2 \
  describe-instances \
  --instance-ids "$INSTANCE_ID" \
  --query 'Reservations[0].Instances[0].PublicIpAddress' \
  --output text)

用意された SSH 設定で接続します。

ssh -F ssh_config ubuntu@"$PUBLIC_IP"

インスタンス内で、新しくアタッチしたデバイスを確認します。このラボでの Linux 名は /dev/xvdf です。デバイス名は API のアタッチ名と異なる場合があります。他の EC2 イメージでは NVMe 名が使われることもあるため、操作前にディスクを特定してください。公式の Linux ボリューム準備ガイドでは、この違いを説明しています。

lsblk -f /dev/xvdf

デバイスにファイルシステムタイプがないことを確認します。新しく作成した空のデータボリュームにのみ ext4 ファイルシステムを作成してください。既存のデータがあるボリュームをフォーマットすると、そのデータが消去されます。

sudo mkfs.ext4 /dev/xvdf

マウントポイントは、ファイルシステムにアクセスするためのディレクトリです。レポートアプリケーション用に用意されたディレクトリに、新しいファイルシステムをマウントします。

sudo mount /dev/xvdf /srv/reports

ソースデバイス、ファイルシステム、マウントポイントを確認します。

findmnt /srv/reports

/dev/xvdf、ext4、/srv/reports を確認します。架空のデータを使った CSV レポートを作成します。sudo tee は管理者が所有するファイルシステムに書き込み、区切り文字を引用符で囲んだヒアドキュメントは 2 行をそのまま保持します。

sudo tee /srv/reports/report.csv <<'CSV'
period,total
Q1,320
CSV

ファイルを読み戻します。

cat /srv/reports/report.csv

LabEx ターミナルに戻ります。

exit

AWS View で recovery-server を選択し、Read volume report をクリックします。HTTP 200 と CSV のテキスト period,total、Q1,320 を確認します。この応答は、アプリケーションがマウントされたボリューム上のファイルを読み取れることを示します。

このラボのマウントは手動です。再起動しても手動のマウントは自動復元されません。本番環境では通常、設定をテストした後に /etc/fstab にファイルシステム UUID を設定します。

整合性のあるスナップショットを作成する

このステップでは、ファイルシステムへのアクセスを一時停止し、元のボリュームをバックアップします。

EBS スナップショットは、特定の時点のボリュームのバックアップです。バックアップには必要なデータが含まれている必要があり、リソースの状態が成功であるだけでは十分ではありません。スナップショット作成ガイドにあるように、AWS は整合性のために書き込みの一時停止やボリュームのアンマウントを推奨しています。このラボでは、バックアップ前にデータファイルシステムをアンマウントします。

インスタンスに接続します。

ssh -F ssh_config ubuntu@"$PUBLIC_IP"

元のファイルシステムをアンマウントし、書き込みを反映してファイルシステムへのアクセスを止めます。

sudo umount /srv/reports

LabEx ターミナルに戻ります。

exit

元のボリュームのスナップショットを作成します。ID を保存し、report-backup というタグを付けます。

SNAPSHOT_ID=$(aws ec2 \
  create-snapshot \
  --volume-id "$VOLUME_ID" \
  --description 'Report before accidental deletion' \
  --tag-specifications 'ResourceType=snapshot,Tags=[{Key=Name,Value=report-backup}]' \
  --query 'SnapshotId' \
  --output text)

スナップショット作成は非同期です。完了するまで待ちます。

aws ec2 \
  wait snapshot-completed \
  --snapshot-ids "$SNAPSHOT_ID"

状態と元のボリュームを確認します。

aws ec2 \
  describe-snapshots \
  --snapshot-ids "$SNAPSHOT_ID" \
  --query 'Snapshots[].{Snapshot:SnapshotId,State:State,SourceVolume:VolumeId}'

completed と想定した元のボリュームを確認します。AWS View を更新してスナップショットを確認してください。ファイルを意図的に削除した後、復元によって内容をテストします。

ファイルの誤削除の影響を確認する

このステップでは、元のボリュームから架空のレポートを削除し、アプリケーションでレポートがない状態を確認します。

再接続して元のボリュームを再度マウントします。

ssh -F ssh_config ubuntu@"$PUBLIC_IP"
sudo mount /dev/xvdf /srv/reports

この練習用に作成した架空のファイルだけを削除します。

sudo rm /srv/reports/report.csv

LabEx ターミナルに戻ります。

exit

AWS View で recovery-server を選択し、Read volume report をクリックします。リクエストは引き続き HTTP 200 を返しますが、report は null になります。アプリケーションは動作しており、必要なファイルがなくなっています。これにより、ストレージ内容の問題とサーバー停止の問題を区別できます。

スナップショットはこの削除前に作成しました。元のボリュームを変更せず、以前のレポートを含む新しいボリュームを用意できます。

スナップショットから新しいボリュームを復元する

このステップでは、バックアップを独立したボリュームに復元し、アプリケーションを復元後のファイルシステムに切り替えます。

復元では新しいボリュームを作成し、既存のボリュームの変更を取り消すわけではありません。完了したスナップショットを使い、インスタンスのアベイラビリティーゾーンに代替ボリュームを作成します。公式の復元ガイドでは、この置き換え手順を説明しています。

RESTORED_VOLUME_ID=$(aws ec2 \
  create-volume \
  --availability-zone "$AVAILABILITY_ZONE" \
  --snapshot-id "$SNAPSHOT_ID" \
  --volume-type gp3 \
  --tag-specifications 'ResourceType=volume,Tags=[{Key=Name,Value=recovered-report}]' \
  --query 'VolumeId' \
  --output text)

準備が完了するまで待ちます。

aws ec2 \
  wait volume-available \
  --volume-ids "$RESTORED_VOLUME_ID"

2 台目のデータデバイスとしてアタッチします。

aws ec2 \
  attach-volume \
  --volume-id "$RESTORED_VOLUME_ID" \
  --instance-id "$INSTANCE_ID" \
  --device /dev/sdg
aws ec2 \
  wait volume-in-use \
  --volume-ids "$RESTORED_VOLUME_ID"

代替ボリュームとスナップショットの関係を確認します。

aws ec2 \
  describe-volumes \
  --volume-ids "$RESTORED_VOLUME_ID" \
  --query 'Volumes[].{Volume:VolumeId,State:State,Snapshot:SnapshotId}'

in-use と保存したスナップショット ID を確認します。接続してアプリケーションのマウントを切り替えます。

ssh -F ssh_config ubuntu@"$PUBLIC_IP"

元のファイルシステムをアンマウントします。

sudo umount /srv/reports

このラボで /dev/xvdg として公開される復元デバイスを確認します。

sudo lsblk -f /dev/xvdg

バックアップからコピーされた ext4 ファイルシステムがすでに含まれています。このデバイスをフォーマットしないでください。フォーマットすると復元データが上書きされます。既存のファイルシステムをアプリケーションのレポートディレクトリにマウントします。

sudo mount /dev/xvdg /srv/reports

現在使用しているソースを確認します。

findmnt /srv/reports

/dev/xvdg を確認します。復元したレポートを読みます。

cat /srv/reports/report.csv

元の 2 行、period,total と Q1,320 が期待されます。LabEx ターミナルに戻ります。

exit

AWS View で Refresh resources をクリックし、recovery-server を選択して Read volume report をクリックします。HTTP 200 と元の CSV テキストを確認します。復元テストの成功は、このバックアップに利用可能なアプリケーションデータが含まれていることを証明します。

復旧用リソースを削除する

このステップでは、2 つのデータボリューム、スナップショット、インスタンスを削除します。

接続して復元後のファイルシステムをアンマウントします。

ssh -F ssh_config ubuntu@"$PUBLIC_IP"
sudo umount /srv/reports
exit

復元したボリュームをデタッチします。

aws ec2 \
  detach-volume \
  --volume-id "$RESTORED_VOLUME_ID" \
  --instance-id "$INSTANCE_ID" \
  --device /dev/sdg
aws ec2 \
  wait volume-available \
  --volume-ids "$RESTORED_VOLUME_ID"

元のファイルシステムは復元時にアンマウントしています。そのボリュームもデタッチします。

aws ec2 \
  detach-volume \
  --volume-id "$VOLUME_ID" \
  --instance-id "$INSTANCE_ID" \
  --device /dev/sdf
aws ec2 \
  wait volume-available \
  --volume-ids "$VOLUME_ID"

デタッチした 2 つの練習用ボリュームを削除します。

aws ec2 \
  delete-volume \
  --volume-id "$RESTORED_VOLUME_ID"
aws ec2 \
  delete-volume \
  --volume-id "$VOLUME_ID"

復元テスト後、練習用バックアップを削除します。

aws ec2 \
  delete-snapshot \
  --snapshot-id "$SNAPSHOT_ID"

サーバーを終了し、最終状態を待ちます。

aws ec2 \
  terminate-instances \
  --instance-ids "$INSTANCE_ID"
aws ec2 \
  wait instance-terminated \
  --instance-ids "$INSTANCE_ID"

インスタンスが終了したことを確認します。

aws ec2 \
  describe-instances \
  --instance-ids "$INSTANCE_ID" \
  --query 'Reservations[].Instances[].{Instance:InstanceId,State:State.Name}'

名前を指定して練習用ボリュームとバックアップを一覧表示します。

aws ec2 \
  describe-volumes \
  --filters Name=tag:Name,Values=source-report,recovered-report \
  --query 'Volumes[].VolumeId'
aws ec2 \
  describe-snapshots \
  --filters Name=tag:Name,Values=report-backup \
  --query 'Snapshots[].SnapshotId'

両方の一覧が [] であることを確認します。AWS View を更新し、練習用ボリュームとスナップショットがなく、サーバーが実行中の対象ではないことを確認してください。用意されたネットワークとキーペアはそのまま残します。

まとめ

レポートボリュームを EBS スナップショットでバックアップし、ファイル削除の影響を確認した後、バックアップから独立したボリュームを復元しました。復元された既存のファイルシステムをフォーマットせずにマウントし、元のアプリケーションデータを確認しました。最後に、2 つのデータボリューム、スナップショット、インスタンスを削除しました。