web-dev-qa-db-ja.com

Ubuntuを実行しているEBSでバックアップされたEC2インスタンスの自動スナップショット

ソフトウェア開発チームのビルドサーバーとして機能する EBS-backedインスタンス を実行しています(Jenkinsと他のサービスのホストを実行しています)。サーバーは実行中ですLinux公式AMI からの最新のUbuntu)。

インスタンスに関連付けられたEBSボリュームの定期的な自動スナップショットを取得したいと思います。最新のバックアップを1つだけ保持する必要があり(つまり、古いスナップショットを整理する必要があります)、適切な頻度は1日1回です。

Amazonはそのようなバックアップサービスをすぐに提供していないようです。そのため、サードパーティのスクリプトを使用するか、独自のソリューションを提供する必要があります。

私の質問は、これを達成するための最も簡単な方法は何ですか?最小限の手間、構成、および外部依存関係が必要です。 Linuxボックス自体でこれをある種の時限スクリプトとして設定することは、私の知る限り、有効なオプションです。

6
Jonik

さて、それが価値があることのために、これが私がしたことです。私の弱いスクリプトが人々にもっと良い解決策を投稿するように促すことを願っています!

2つの簡単なbashスクリプトを作成し、cronを使用して自動化しました。 (今のところ、これらをローカルサーバーで実行しています。think(?)のように、AWSの証明書をインスタンス/ AMI/EBS自体に配置することはお勧めしません。)

新しいスナップショットを作成するには

# ESB volume associated with the instance we want to back up:
EBS_VOL_ID=vol-xxxxyyyy

ec2-create-snapshot --region eu-west-1 -K pk.pem -C cert.pem -d "Automated backup" $EBS_VOL_ID 

最新のスナップショットを除くすべてを削除するには

EBS_VOL_ID=vol-xxxxyyyy

ec2-describe-snapshots --region eu-west-1 -K pk.pem -C cert.pem  | grep "Automated backup" | grep "$EBS_VOL_ID" | awk '{ print $5 "\t" $2 }' | sort > .snapshots

latest_id=$(tail -n1 .snapshots | awk '{ print $2 }')

cat .snapshots | awk '{ print $2 }' > .snapshot_ids
for i in $(cat .snapshot_ids) 
do
    if [ "$i" != "$latest_id" ]
    then
        echo "Deleting snapshot $i"
        ec2-delete-snapshot --region eu-west-1 -K pk.pem -C cert.pem $i
    fi
done

(これにより、ec2-describe-snapshots出力から適切なスナップショット情報が解析され、[タイムスタンプタブsnapshot-id]エントリ(例:2011-06-01T10:24:36+0000 snap-60507609)を含む一時ファイルが作成されます。最新のスナップショットは最後の行にあります。)

メモ

  • X509証明書と秘密鍵を、スクリプトが見つけられる場所に置きます。
  • 必須すべてのコマンドで--regionを明示的に指定します。それ以外の場合、例: ec2-create-snapshotは、ボリュームIDが不明な場合に失敗します。 (デフォルトのリージョン「us-east-1」を使用する場合はYMMV。)
  • スナップショットの説明(「自動バックアップ」)をマーカーとして使用して、Pruneスクリプトが問題のボリュームの他のスナップショット(AMIに関連するスナップショットなど)を削除しないようにしました。

免責事項:これは、私にとってBash/Unixプログラミング、特にPruneスクリプトの演習になりました。私はあなたが例えばではるかに明確な結果を得る可能性が最も高いことを容易に認めます。 Python、「リストの最後の項目以外のすべてに対して何かを行う」などのロジックが必要な場合。そして、Bashを使用しても、おそらくこれをよりエレガントに行うことができます(たとえば、一時ファイルは実際には必要ありません)。だから他の解決策を投稿してください

4
Jonik

Jonikの概念に基づいて、botoを使用してpythonスクリプトを作成しました。スナップショットするボリュームのリストと、ボリュームごとに保持する後続のスナップショットの数を指定します。

# Define the snapshots manage. We'll snapshot the specified volume ID, and only keep the X newest ones.
snapshots = [("vol-XXXXXXXX", 30), ("vol-YYYYYYYY", 180)]

import boto.ec2
auth = {"aws_access_key_id": "YOURACCESSKEY", "aws_secret_access_key": "YOURSECRETKEY"}
ec2 = boto.ec2.connect_to_region("YOURREGIONNAME", **auth)
description = "automated backup"
for volume, num_trailing in snapshots:
  snaps = ec2.get_all_snapshots(filters={"volume-id": volume, "description": description})
  print "%s: Creating new snapshot. %s automated snapshots currently exist." % (volume, len(snaps))
  ec2.create_snapshot(volume, description)
  purgeable = sorted(snaps, key=lambda x: x.start_time)[:-num_trailing]
  print "Deleting snapshots for %s > %s: %s" % (volume, num_trailing, purgeable)
  for snap in purgeable:
    ec2.delete_snapshot(snap.id)

これを(Pythonプラグインを介して)Jenkinsジョブとして設定し、毎日実行するように構成しました。IAMを使用して認証情報を管理している場合は、ec2ポリシーでDescribeRegions、DescribeVolumes、 CreateSnapshot、DeleteSnapshot、DescribeSnapshots、CreateTags(botoの実装のため)。

5
Michael Rooney

外部ユーティリティを利用できる場合は、 Skeddly を確認してください。

開示:私はSkeddlyの背後にある会社であるEleven41SoftwareのCEOです。

1
Matt Houser

Jonikのスクリプトのアイデアを拡張して、複数のスナップショットを保持できるようにしました。コードが長すぎてコメントに収まらないので、新しい回答を追加します。このコードは、CLIツール用にすべての適切な環境変数が設定されていることを前提としています。また、これはデフォルトで現在のインスタンスのスナップショットを取得します。

# Look up our instance ID using the magic URL
INSTANCE_ID=$(curl -s http://169.254.169.254/latest/meta-data/instance-id)

# The number of previous backups we want to keep
N=3

# get list of locally attached volumes via EC2 API:
VOLUME_LIST=$(ec2-describe-volumes | grep ${INSTANCE_ID} | awk '{ print $2 }')
DATE=$(date '+%Y-%m-%d-%H%M%S')

sync

# actually creating the snapshots
for VOLUME in $(echo $VOLUME_LIST); do
    echo "Processing volume $VOLUME"
    SNAPSHOT_LIST=$(ec2-describe-snapshots | grep completed | grep "Automatic snapshot" | grep $VOLUME | awk '{print $5 "\t" $2}' | sort | head "--lines=-$N" | awk '{print $2}')
    ec2-create-snapshot $VOLUME -d "Automatic snapshot on $DATE"
    for SNAPSHOT in $(echo $SNAPSHOT_LIST); do
        ec2-delete-snapshot $SNAPSHOT
    done
done
1

PHPで、EBSスナップショットを自動化し、古いスナップショットを削除するスクリプトを作成しました。スナップショットの結果もメールで送信されます。AWSを構成する必要がありますPHPメール機能用のSDKとPHPMailerですが、これらの手順はどちらも非常に簡単です。その後、CRONまたはWindowsのスケジュールされたタスクを使用して毎晩スクリプトを実行します。詳細な手順とコードは私のブログにあります。

http://www.caleblloyd.com/software/automatically-take-ebs-snapshots-and-delete-old-ones-with-php-script/

0
Caleb