JAWS-UG Advent Calendar 2013 4日目の投稿です
昨日は@j3tm0t0さんのg2インスタンスを使って宇宙へ行こう!です
11/2の第9回JAWS-UG大阪で発表したときにはManualScalingとして紹介した方法の解説
ゲームに限らず、アクセス数の多いブログやニュースサイトなんかでは、例えばお昼の12時からの1時間のほうが、その前後の1時間に比べて数倍のトラフィックがくることがよくありますよね
1日のピーク値にあわせてサーバを用意しておくというのはイマイチ「クラウド」っぽくありません
そこで、毎日のトラフィックの増減の予想から、指定時間でサーバを起動させる仕組みを作ってみました
なお、指定時刻でサーバを増減させる仕組みを、AWSのドキュメントではScheduled Scalingっていうらしいです。AutoScalingのコマンドで実現可能です。
詳しくはこちら
この公式のScheduled Scalingは、既に運用面も含めてAutoScaling構成になっている環境では簡単に使えるのですが、今回はあえてAutoScalingを使わない方法をご紹介します
今回ご紹介する方法には、コチラのようなメリットがあります
・サーバ減少時にTerminateではなくStop状態でサーバを保存しておける。ログ消えない
・サーバ増加時にはStop状態のサーバをStartさせる。インスタンスの作成時間を短縮
・最新プログラムをサーバへダウンロードするときは前回Stop時からの差分のみなのでわりと高速
・最新プログラムの反映を待ってからELBにサーバを組み込む
ということで、まずは全サーバに次のような起動スクリプトを仕掛けます
#!/bin/bash
#
# Auto associate Elastic IP , rsync and register ELB
#
# chkconfig: 345 98 6
# description: rsync and register ELB
# processname: rsync-elb
#
export JAVA_HOME=/usr/lib/jvm/jre
export EC2_HOME=/opt/aws/apitools/ec2
export AWS_ELB_HOME=/opt/aws/apitools/elb
# 初期化
RSYNC_SERVER=""
ELB_SERVER=""
# 自分のインスタンスIDを取得
INSTANCE_ID=$(/usr/bin/curl http://169.254.169.254/latest/meta-data/instance-id)
# インスタンスIDを元にtagを取得
TAGS=`/opt/aws/apitools/ec2/bin/ec2-describe-tags -O アクセスキー -W シークレットキー --filter "resource-id=${INSTANCE_ID}" --region ap-northeast-1|/usr/bin/awk '{print $4,$5}'`
# スペース区切りでtagが返ってくるので配列へ
ARR_TAGS=(`echo $TAGS`)
# tagのキーとバリューが交互に入っているのでループ
for i in `seq 1 ${#ARR_TAGS[@]}`
do
if [[ 'rsync' == ${ARR_TAGS[$i-1]} ]];then
RSYNC_SERVER=${ARR_TAGS[$i]}
fi
if [[ 'elb' == ${ARR_TAGS[$i-1]} ]];then
ELB_SERVER=${ARR_TAGS[$i]}
fi
# キーとバリューが交互なので1つ飛ばす
i=`expr $i + 1`
done
if [[ $RSYNC_SERVER != "" && $ELB_SERVER != "" ]]; then
# rsync実行
/usr/bin/sudo -u ユーザー /usr/bin/rsync -av --update -e "/usr/bin/ssh -i /home/ユーザー/.ssh/秘密鍵 -o \"StrictHostKeyChecking no\"" --include="いろいろ" --exclude="*" "${RSYNC_SERVER}:/コピー元ディレクトリ" /コピー先ディレクトリ
if [ $? -eq 0 ]; then
# rsync成功 ELB登録
/opt/aws/apitools/elb/bin/elb-register-instances-with-lb ${ELB_SERVER} --instances ${INSTANCE_ID} -O アクセスキー -W シークレットキー --region ap-northeast-1
if [ $? -eq 0 ]; then
# ELB登録成功 Apache起動
/etc/init.d/httpd start
fi
else
# 失敗はシャットダウン
/sbin/shutdown -h now
fi
else
# 失敗はシャットダウン
/sbin/shutdown -h now
fi
ttyがない状態でもsudoが使えるように下記の修正
# visudo
コメントアウト
#Defaults requiretty
そして、次のようなマネージメントコンソールからタグを仕掛けます
rsync:rsync先のサーバのPublicDNS
elb:elbのLoad Balancer Name
次に指定時間に増減させたいインスタンスIDを指定した起動・停止用スクリプトを作成します
起動用スクリプト
vi /home/ec2-user/EC2-server-start.sh
------------------------------------------------------------------------------
#!/bin/sh
/opt/aws/bin/ec2-start-instances -O アクセスキー -W シークレットキー --region ap-northeast-1 i-XXXXXXXX i-YYYYYYYY
------------------------------------------------------------------------------
chmod +x EC2-server-start.sh
停止用スクリプト
vi /home/ec2-user/EC2-server-stop.sh
------------------------------------------------------------------------------
#!/bin/sh
# ELB切り離し
elb-deregister-instances-from-lb ELBの名前 --instances i-XXXXXXXX,i-YYYYYYYY -O アクセスキー -W シークレットキー --region ap-northeast-1
# ELB切り離し後、30秒ほど時間を空ける
sleep 30
# インスタンス停止
/opt/aws/bin/ec2-stop-instances -O アクセスキー -W シークレットキー --region ap-northeast-1 i-XXXXXXXX i-YYYYYYYY
------------------------------------------------------------------------------
chmod +x EC2-server-stop.sh
最後にお好みの起動・停止時間をcronで設定して終わり
明日は@ar1さんです。