share facebook facebook twitter menu hatena pocket slack

2012.05.01 TUE

定時にEC2を起動 & バッチが終了したらターミネート(クラウドデザインパターン(CDP):Scheduled Autoscali…

鈴木 宏康

WRITTEN BY 鈴木 宏康

今回は、Cloud Design Pattern(CDP)の記事になります。
対象は「Scheduled Autoscalingパターン」です。

このパターンの注意点に下記のような記載があります。

バッチ処理が終了する時刻を決めるのが難しい場合は、
EC2上のバッチ処理が終了してから、EC2自身が自分を終了する
作り込みを行う方法もよく用いられる。

今回は、上記の方法を実際に作り込んでみました。

はじめに、Auto Scalingにてスケールアウトに使われるAMIの作成です。
このAMIはEC2起動時にバッチ処理を開始し、バッチ処理が終了する時に自分自身(EC2)も
ターミネートされるようにする必要があります。

具体的には、起動時にバッチ処理(/opt/suz-batch/bin/run-batch)が開始されるように、
下記の起動スクリプト(/etc/init.d/suz-batch)を用意します。

#!/bin/bash
#
# suz-batch Run Batch.
#
# chkconfig: 2345 99 10
# description: Run Batch

# Source function library.
. /etc/init.d/functions

prog=suz-batch
lock=/var/lock/subsys/$prog
log=/opt/suz-batch/log/error.log

# Source config
if [ -f /etc/sysconfig/$prog ] ; then
. /etc/sysconfig/$prog
fi

case "$1" in
start)
echo `date +"%Y-%m-%d %T"` "begin" > $log
/opt/suz-batch/bin/run-batch &
touch $lock
;;
stop)
echo `date +"%Y-%m-%d %T"` "end" >> $log
/opt/suz-batch/sbin/upload-log
rm -f $lock
;;
*)
echo $"Usage: $0 {start|stop}"
exit 1
esac

exit $?

※終了時はログをS3にアップロード(/opt/suz-batch/sbin/upload-log)します。

当然ですが、上記の起動スクリプトが有効になるようにもしておきます。

# chkconfig --add suz-batch
# chkconfig suz-batch on
# chkconfig --list suz-batch
suz-batch 0:off 1:off 2:on 3:on 4:on 5:on 6:off

バッチ処理のスクリプト(/opt/suz-batch/bin/run-batch)は下記の通りとなり、
バッチ終了時に自分自身(EC2)をターミネート(/opt/suz-batch/sbin/terminate-instance)
するようにしています。

log=/opt/suz-batch/log/error.log
echo `date +"%Y-%m-%d %T"` "run" >> $log
/opt/suz-batch/sbin/terminate-instance
exit 0

自分自身(EC2)をターミネート(/opt/suz-batch/sbin/terminate-instance)する
スクリプトは下記のようにしています。

require_once("/opt/aws/php/latest/sdk.class.php");
date_default_timezone_set("Asia/Tokyo");

$as = new AmazonAS(array(
"key" => "ACCESS KEY",
"secret" => "SECRET KEY"
));
$as->set_region(AmazonAS::REGION_APAC_NE1);
$response = $as->update_auto_scaling_group(
"as-test",
array(
"MinSize" => 0,
"MaxSize" => 0,
"DesiredCapacity" => 0
)
);

if(!$response->isOK()) {
error_log(
date("Y-m-d H:i:s") . " " . basename($_SERVER["PHP_SELF"]) . " " . $response->body->Error->to_json() . "n",
3,
"/opt/suz-batch/log/error.log"
);
exit(1);
}
exit(0);

上記のように、EC2をターミネートするのではなく、Auto ScalingのEC2起動数を0にすることで、
結果的に自分自身(EC2)がターミネートされるようにしています。

尚、自分自身(EC2)をターミネートする時に実行される、ログをS3にアップロードする
スクリプト(/opt/suz-batch/sbin/upload-log)は下記のようにしています。

require_once("/opt/aws/php/latest/sdk.class.php");
date_default_timezone_set("Asia/Tokyo");

$s3 = new AmazonS3(array(
"key" => "ACCESS KEY",
"secret" => "SECRET KEY"
));
$s3->set_region(AmazonS3::REGION_APAC_NE1);
$s3->use_ssl = false;
$response = $s3->create_object("www.suz-lab.com", "test/error-" . date("YmdHis") . ".log", array(
"fileUpload" => "/opt/suz-batch/log/error.log"
));

if(!$response->isOK()) {
error_log(
date("Y-m-d H:i:s") . " " . basename($_SERVER["PHP_SELF"]) . " " . $response->body->to_json() . "n",
3,
"/opt/suz-batch/log/error.log"
);
exit(1);
}
exit(0);

次に、このAMIを使ってAuto Scalingの設定を行います。
具体的にはLaunch ConfigurationとAuto Scaling Groupを設定するのですが、以前紹介しました
下記の記事が参考になるかと思います。

Auto ScalingでEC2を自動復旧(クラウドデザインパターン(CDP):Multi-Serverパターン)

特にAuto Scaling Groupの設定は、初期時にEC2は起動していない状態にしたいので、
最大起動数と最小起動数を共に0にしておきます。
(ELB関係の設定も必要ありません)

最後に、今回の記事のポイントである、定期的にAutoScalingがEC2を起動(0 → 1にスケール)
する部分です。

設定は下記のようにPHP(AWS SDK)で行なっています。

require_once("/opt/aws/php/latest/sdk.class.php");

$as = new AmazonAS(array(
"key" => "ACCESS KEY",
"secret" => "SECRET KEY"
));
$as->set_region(AmazonAS::REGION_APAC_NE1);
$response = $as->put_scheduled_update_group_action(
"as-test", // auto scaling group name
"as-test", // scheduled action name
array(
"Recurrence" => "*/5 * * * *", // unix cron syntax format
"MinSize" => 1,
"MaxSize" => 1,
"DesiredCapacity" => 1
)
);

var_dump($response->body);

APIはput_scheduled_update_group_actionを利用しており、Recurrenceにcronの文法でスケールアウトする時刻を
指定することができます。

そして上記は、5分毎にEC2が1インスタンス稼働している状態にするように設定しています。
つまり、はじめから稼働していない(0インスタンス)の場合は、上記のタイミングで
1インスタンス、新規に稼働することになります。

結果としては、下記のように動作し、S3へのログも下記のように5分毎にアップロードされることがわかります。

5分後 → EC2起動 → バッチ終了 → EC2ターミネート → 5分後 → EC2起動 → …

上記の流れを図にすると、下記のようになります。

こちらの記事はなかの人(suz-lab)監修のもと掲載しています。
元記事は、こちら

鈴木 宏康

鈴木 宏康

愛知県生まれ。東京工業大学大学院修士課程修了。在学時より、ベンチャー企業でインターネットに関する業務に携わり、現在はクラウド(主にAmazon Web Services)上での開発・運用を軸とした事業の、業務の中心として活躍。

cloudpack

cloudpackは、Amazon EC2やAmazon S3をはじめとするAWSの各種プロダクトを利用する際の、導入・設計から運用保守を含んだフルマネージドのサービスを提供し、バックアップや24時間365日の監視/障害対応、技術的な問い合わせに対するサポートなどを行っております。
AWS上のインフラ構築およびAWSを活用したシステム開発など、案件のご相談はcloudpack.jpよりご連絡ください。