AWS EC2のストレージを担当するEBSには、ボリュームのバックアップとして使用できるスナップショット機能があります。
スナップショットにも従量課金が適用されるため、当面使う予定のないスナップショットはダウンロードして手元に置いておきたくなる場合もあります。
本記事では、主にamazon web services - Download EBS volume or snapshot to file - Server Faultに従って、スナップショットをダウンロードする方法を紹介します。
従来の方法
スナップショットは内部的にはS3のバケットとして保存されますが、通常のS3バケットとは異なりアクセスできない領域に保存されます。このため、従来(2019年くらいまで?)は、スナップショットをローカルにダウンロードできるマネージドな方法はありませんでした。
とはいえ、EC2を使うことでデータを取り出すことはもちろん可能です。つまり、ボリュームとしてEC2インスタンスにアタッチした上で、アンマウントした状態で(データの破損を防ぐため)、ddコマンド(と、適宜bzipやzstdなどの圧縮コマンドやncなどのネットワークコマンド)を使用してimgファイルに書き込むことができます。(上記のServer Faultにもコマンドラインの例が載っています)
coldsnapを使う方法
2019年からはEBS direct APIというのが追加され、EBSのスナップショットに直接アクセスできるようになりました。スナップショットのダウンロードを手軽にできるユーティリティとしてはcoldsnapというのがAWSの公式リポジトリ(AWS Labs)から提供されています。
cargoでインストールできます。aws configureで認証情報を設定していればそれをそのまま使ってくれますが、環境変数で直接認証情報を渡すことも可能らしいです。
ダウンロード時のコマンドラインはcoldsnap download <snapshot ID> disk.imgと、非常に単純明快です。
ただしデメリットとして、わずかに料金が発生します。上記のServer Faultによると1GBあたり$0.006とのことです。
imgのサイズ・内容について
coldsnapでダウンロードしたimgファイルとddで保存したimgファイルは基本的には全く同じ内容になるものと思っていますが、確かめてはいません。
coldsnapでダウンロードしたファイルは、サイズは8Gや16Gなど元のボリュームのサイズぴったりになっていましたが、スパースファイルなので、duコマンドで見てみると実際の使用量はもっと少なく、AWS上で見たときのスナップショットの実際のサイズと概ね一致しているのがわかると思います。
ddでも多分スパースファイルになるんじゃないでしょうか。
ダウンロードしたimgファイルをマウントしてみる
ここまでだとほぼServer Faultの内容そのままになってしまうので、ddあるいはcoldsnapで取得したimgファイルの中身を見る方法をついでに書いておきます。
まず
# fdisk -l /path/to/your.img
これで中身を見てみましょう。Disklabel type: gpt(あるいはdos)などとパーティションテーブルの種類がわかり、パーティションの個数や大まかな種類(Linux、BIOS)もわかります。しかし個々のパーティションのフォーマットなどはこの段階ではわかりません。
では、このimgをループバックデバイスとして使えるようにします。
# losetup -Pf --show /path/to/your.img
これで/dev/loop39(39のところは未使用の最小のもの)といったループバックデバイスとしてyour.imgにアクセスできるようになります。
次に、この/dev/loop39の中身をlsblkで見てみます。
# lsblk -f /dev/loop39
NAME FSTYPE FSVER LABEL UUID FSAVAIL FSUSE% MOUNTPOINTS
loop39
├─loop39p1 ext4 1.0 / xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx
└─loop39p128
このように、ファイルシステムの種類がちゃんと見られるようになりました。ここまでくれば通常のディスクと同じです。
# mount -t ext4 -r /dev/loop39p1 /media/test/
例えばこんな感じで読み取り専用マウントできます。