こんにちはfujyaです。
今日はAWSの超便利な機能、snapshotを良い感じに使うTipsを紹介したいと思います。
AWSのsnapshotは超便利なので色々なサーバのバックアップ用途としてがんがん取得したくなりますが、数十台・数百台にサーバが増加すると管理が煩雑になってしまいます。これをスッキリさせるために、マネジメントコンソール上で
「世代数の管理」と
「snapshot対象かどうか」を分かるようにしてみました。
手順としては4Stepで環境が構築可能です。
1:snapshotを取得したいインスタンスのtagにbackup:ON / generation:N(世代数)を設定する
2:apitoolsがインストールされてるサーバにX.509証明書を設置しておく
3:2のサーバにsnapshot取得スクリプトを配置
4:CronもしくはJenkinsで定期的に3のスクリプトを実行する
■Step1:インスタンスにtagを設定する
使うタグは [backup]と[generation]の二つです。
tag | 説明 |
backup | snapshot対象のインスタンスとするか |
generation | 何世代分のスナップショットを取得するか |
■Step2:X.509証明書を取得する
https://portal.aws.amazon.com/gp/aws/securityCredentials
からX.509証明書取得してください。
取得方法等はWEB上探せばたくさん情報があるので、詳細は割愛します。
■Step3:スクリプトを設置
ここでは二つのスクリプトを設置します。
- /root/bin/all_createsnapshot.sh
- /root/bin/createsnapshot.sh
all_createsnapshot.sh
#!/bin/bash
#
# All Instances CreateSnapshot script
. /etc/bashrc
export EC2_PRIVATE_KEY=<EC2_PRIVATE_KEY_PATH>
export EC2_CERT=<EC2_CERT_PATH>
export EC2_URL="https://ec2.ap-northeast-1.amazonaws.com"
AWS_REGION=`curl -s http://169.254.169.254/latest/meta-data/placement/availability-zone | sed -e 's/[a-z]$//'`
opterror(){
echo "Usage: $prog -c [config]" 1>&2
echo " -h HELP"
exit 1
}
while getopts c:h OPT
do
case $OPT in
"h" ) HELP=1 ;;
"c" ) CONFIG="$OPTARG" ;;
* ) opterror
esac
done
test ! -z $HELP && opterror
test ! -z $CONFIG && . $CONFIG
if [ ! -f $EC2_PRIVATE_KEY -o ! -f $EC2_CERT ];then
echo "$EC2_PRIVATE_KEY or $EC2_CERT does not exist."
exit 1
fi
ec2-describe-instances -F tag:backup=ON --show-empty-fields | grep ^TAG | grep backup | awk '{print $3}' | while read INSTANCE_ID
do
GENERATION=`ec2-describe-instances -F instance-id=${INSTANCE_ID} | grep generation | awk '{print $5}'`
test -z ${GENERATION} && GENERATION=5
if [ ! -z $CONFIG ];then
/root/bin/createsnapshot.sh -i ${INSTANCE_ID} -g ${GENERATION} -c $CONFIG
else
/root/bin/createsnapshot.sh -i ${INSTANCE_ID} -g ${GENERATION}
fi
echo "${INSTANCE_ID} createsnapshot : ${GENERATION} generations." | logger -p local0.info -t snapshot
done
ポイントとして
ec2-describe-instances -F tag:backup=ON --show-empty-fields | grep ^TAG | grep backup | awk '{print $3}'
このコマンドでinstance-idのリストを取得して
ec2-describe-instances -F instance-id=${INSTANCE_ID} | grep generation | awk '{print $5}
このコマンドで対象intance-idの世代数を取得します
またスクリプト内部でX.509証明書のパスはハードコードされていますが、オプションでコンフィグを読み込ませ変更できるようになっています
※ コンフィグサンプル
export EC2_PRIVATE_KEY=<EC2_PRIVATE_KEY_PATH>
export EC2_CERT=<EC2_CERT_PATH>
export EC2_URL=<EC2_URL>
export AWS_REGION=<AWS_REGION>
ex ) /root/bin/all_createsnapshot.sh -c <config_path> で実行
これでsnapshot対象のinstance-idと世代数がわかったので、次に実際にスナップショットを取得するスクリプトが実行されます。
※ このスクリプトはid:rx7さんのブログの記事を参考に改良したものです
参考元:RX-7乗りの適当な日々 – Amazon EBSのスナップショット(バックアップ)を取得しつつ世代管理も行うスクリプト
createsnapshot.sh
#!/bin/bash
#
# CreateSnapshot script
. /etc/bashrc
export EC2_PRIVATE_KEY=<EC2_PRIVATE_KEY_PATH>
export EC2_CERT=<EC2_CERT_PATH>
export EC2_URL="https://ec2.ap-northeast-1.amazonaws.com"
AWS_REGION=`curl -s http://169.254.169.254/latest/meta-data/placement/availability-zone | sed -e 's/[a-z]$//'`
ALERT_ADDRESS="alert_to@example.com"
if [ ! -f $EC2_PRIVATE_KEY -o ! -f $EC2_CERT ];then
echo "$EC2_PRIVATE_KEY or $EC2_CERT does not exist."
exit 1
fi
opterror(){
echo "Usage: $prog -i [instance_id] -g [backup generation] -c [config]" 1>&2
echo " -h HELP"
exit 1
}
while getopts i:g:c:h OPT
do
case $OPT in
"h" ) HELP=1 ;;
"i" ) EC2_INSTANCE_ID="$OPTARG" ;;
"g" ) EBS_GENERATION_COUNT="$OPTARG" ;;
"c" ) CONFIG="$OPTARG" ;;
* ) opterror
esac
done
test ! -z $HELP && opterror
test ! -z $CONFIG && . $CONFIG
test -z $EC2_INSTANCE_ID && EC2_INSTANCE_ID=`curl -s http://169.254.169.254/latest/meta-data/instance-id`
test -z $EBS_GENERATION_COUNT && EBS_GENERATION_COUNT=5
for EBS_VOLUME_ID in `ec2-describe-volumes | grep $EC2_INSTANCE_ID | awk '{print $2}'`
do
ec2-create-snapshot --private-key ${EC2_PRIVATE_KEY} --cert ${EC2_CERT} --region ${AWS_REGION} --description "${EC2_INSTANCE_ID} create snapshot `date`" ${EBS_VOLUME_ID}
RESULT=$?
if [ ${RESULT} -ne 0 ];then
echo "${EC2_INSTANCE_ID} create snapshot `date` ${EBS_VOLUME_ID} faile." | mail -s "[AWS] snapshot create failed." ${ALERT_ADDRESS}
fi
SNAPSHOTS=`ec2-describe-snapshots --private-key ${EC2_PRIVATE_KEY} --cert ${EC2_CERT} --region ${AWS_REGION} | grep ${EBS_VOLUME_ID} | sort -k5 -r | awk '{print $2}'`
COUNT=1
for SNAPSHOT in ${SNAPSHOTS}
do
if [ ${COUNT} -le ${EBS_GENERATION_COUNT} ]; then
echo "[keeping] " ${SNAPSHOT} | logger -p local0.info -t snapshot
else
echo -n "[deleting...] " | logger -p local0.info -t snapshot
ec2-delete-snapshot --private-key ${EC2_PRIVATE_KEY} --cert ${EC2_CERT} --region ${AWS_REGION} ${SNAPSHOT}
fi
COUNT=`expr ${COUNT} + 1`
done
done
このスクリプトが実行されれば指定した世代数分のsnapshotが保管されるようになります。
また、このスクリプトは単体でも動作するようになっており、オプション無しで実行すると実行したインスタンスのsanpshotが取得されるようになっています。
■Step4:最後にall_createsnapshot.shを定期実行されるようにすれば完了
とりあえずCronで実行されるように設定
# crontab -e
00 04 * * * /root/bin/all_createsnapshot.sh
これで毎朝4時にbackup:ONと設定されているインスタンスの指定した世代数分のsanpshotが取得されるようになります。
実行履歴をloggerコマンドに渡すようにしてあるので、スクリプトを設置した翌日にでもログを確認すると良いでしょう。もちろん実際にSnapshotが取得できているかマネジメントコンソール上でも確認しておきましょう。
■さいごに
AWSは単体でも非常に強力な機能が提供されていますが、それらを組み合わせることによってより強固なインフラを構築する事ができます。今回はTagの有効活用といったところでしょうか。
他にTagを利用して監視のON/OFF設定や名前解決に利用しているケースも見られますので、他にもたくさん良い感じの使い方ができそうですね!(シャノンでは課金管理にもTagを活用しています)
・
・
・
あれ?遠くの方で声が聞こえる。
「間違ってファイル消したんだけど、昨日のデータ復元できるーーー?」
しょうがないなーw まぁsnapshot取ってるからそこからcreate volumeしてattachして取り出すかー
(つд⊂)ゴシゴシ
。・゚・(ノД`)・゚・。
バックアップのご利用は計画的に!