AWS EC2 インスタンスが起動できなくなった場合のデータのレスキュー方法と失敗談
はじめに
AWS EC2 インスタンス上でボリュームを拡張している最中にインスタンスを再起動したところ、ステータスチェックが常に失敗し、インスタンスが完全に起動しなくなるという問題が発生しました。インスタンスのスクリーンショットを確認したところ、ブートファイルが読み込めないというエラーが表示されていました。結果として、インスタンスの復旧を断念し、データのみを救出して新しいインスタンスにコンテンツを再構築することにしました。
しかし、手順を誤ってデータを完全に失ってしまいました。幸い、このシステムは規模が大きくなく、サービスのローンチ前であったため、大きな影響はありませんでした。
この記事ではその反省として、その失敗経験と、本来実施すべきだった手順について解説します。
失敗した手順
EC2インスタンスにEBSをマウントする手順を調べ、以下の作業を実施しました。
- 壊れたEC2インスタンスを停止する。
- 壊れたインスタンスのルートボリュームをデタッチする。
- デタッチしたルートボリュームを別のEC2インスタンスにアタッチする。
- アタッチしたボリュームをEC2インスタンス上で認識し、マウントするための手順に従う。
- EBSの内容を確認する。
通常、「EC2インスタンスにEBSをマウントする」と言う場合、新しいEBSボリュームを作成し、ルートボリューム以外にマウントすることを指します。このプロセスには、EBSボリュームのファイルシステムを初期化する手順が含まれます。
ここまで書けばお気づきかと思いますが、ここでの失敗は、救出を試みていたルートボリュームに対してファイルシステムの初期化を行ってしまったことです。ファイルシステムを初期化すると、データは全て消去され、新たなファイルシステムが作成されます。マウント作業を終えた後、lost+found というディレクトリのみが存在しており、これを見た瞬間に失敗に気づきました。
失敗が許されないケースでは、EBSスナップショットを取っておき、必要に応じてここからデータを復元します。しかし、このプロジェクトの規模や進行状況から、スナップショットも準備していなかったため、この時点でデータは失われ、復旧は不可能となりました。
本来実施すべきだった手順
ファイルシステムの初期化を行わず、直接 EC2 インスタンス上でマウントを行うことです。 今回は問題再現のため、破損する EC2 インスタンスのディスク上に以下のファイルを配置しておきました。
$ cat /opt/shared/rescue.data
このデータを救出してください。
host by ip-172-31-42-49.ap-northeast-1.compute.internal
このボリュームを/dev/sdfとして新しいEC2インスタンスにアタッチした後、以下のようにデバイスが認識されました。検証はNVMe技術を使用するt3a系インスタンスで実施しました(詳細はAWSのドキュメントを参照)
$ sudo file -s /dev/sdf
/dev/sdf: symbolic link to nvme1n1
$ sudo file -s /dev/nvme1n1
/dev/nvme1n1: DOS/MBR boot sector, extended partition table (last)
$ sudo fdisk -l /dev/nvme1n1
Disk /dev/nvme1n1: 8 GiB, 8589934592 bytes, 16777216 sectors
Disk model: Amazon Elastic Block Store
Units: sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 4096 bytes / 4096 bytes
Disklabel type: gpt
Disk identifier: 2FD755DF-0512-4707-9D86-E60B86C1EBFA
Device Start End Sectors Size Type
/dev/nvme1n1p1 24576 16777182 16752607 8G Linux filesystem
/dev/nvme1n1p127 22528 24575 2048 1M BIOS boot
/dev/nvme1n1p128 2048 22527 20480 10M EFI System
データボリュームは/dev/nvme1n1p1であることが確認できたため、以下のディレクトリにマウントしました。
$ sudo mount -t xfs /dev/nvme1n1p1 /mnt/rescue/
この操作を実行すると、時に以下のようなエラーが発生することがあります。
mount: /mnt/rescue: wrong fs type, bad option, bad superblock on /dev/nvme1n1p1, missing codepage or helper program, or other error.
エラーの詳細はjournalctlまたは/var/log/messageに出力され、今回は XFS (nvme1n1p1): Filesystem has duplicate UUID **************** – can’t mountと表示されました。これはUUIDが重複しているためです。blkidコマンドでディスクのID重複を確認できます。
一時的なマウントのため、この問題は無視してマウントすることができます。以下のコマンドでマウントを行い、データを正常に取得することができました。
$ sudo mount -t xfs -o nouuid /dev/nvme1n1p1 /mnt/rescue/
$ cat /mnt/rescue/opt/shared/rescue.data
このデータを救出してください。
host by ip-172-31-42-49.ap-northeast-1.compute.internal
おわりに
この事例から、EC2 インスタンスおよび EBS ボリュームの取り扱いにおいては、作業手順の内容を正確に理解し実行することの重要性を再確認できました。また、失敗のリスクが伴う作業には、重要なデータの保護のためにもスナップショットなどのバックアップ手段を用意することが肝要です。
今回の経験から、具体的な作業手順を再考し、学びを深めることができました。この記事を通じて、同じような失敗を避けるための一助となれば幸いです。