2012年4月6日金曜日

"Auto Scaling"でEC2を自動復旧

スズキです。

CDPネタです。今回の対象は「Multi-Serverパターン」です。


このパターンの利点の一つに
"ELB"と"Auto Scaling"の設定により、ある一定数のサーバ(例えば、3台)を設定して、
常に3台で稼働させることを行える。
というものがあり、実際に試してみました。

まずは、"Auto Scaling"で起動する"AMI"を用意します。

このAMIは下記のように起動時にApacheが立ち上がり、
"/index.html"でアクセスできるようにしておきます。
# yum -y install httpd
# chkconfig httpd on
# chkconfig --list httpd
httpd           0:off 1:off 2:on 3:on 4:on 5:on 6:off
# /etc/init.d/httpd start
# cat /var/www/html/index.html 
<html>
    <body>AS</body>
</html>

つまり起動すると、何もしなくてもブラウザで、下記のようにアクセスできるように
しておきます。


その状態で"AMI"を作成します。


この"AMI"が"Auto Scaling"で利用(起動)される"AMI"となります。


"Auto Scaling"で"EC2"が起動した時に追加される"ELB"も作成しておきます。


今回は、"EC2"が別々の"AZ"(ap-northeast-1a/ap-northeast-1b)に分散するよに
配置するので、"ELB"の"AZ"も両方登録しておきます。


これで、AWSリソースの準備は終わりました。次は"Auto Scaling"の設定です。
(今回も"AWS PHP SDK"で設定します。)

まずは、"Launch Configuration"です。下記のPHPスクリプトで設定します。

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->create_launch_configuration(
    "as-test",      // "Launch Configration"名
    "ami-5c25945d", // 上記で作成した"AMI"
    "t1.micro",     // EC2のタイプ
    array(
        "SecurityGroups" => array(
            "default" // "0.0.0.0/0"からPort80へのアクセスが許可
        )
    )
);

var_dump($response->body);

そして、"Auto Scaling Group"です。下記のPHPスクリプトで設定します。

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->create_auto_scaling_group(
    "as-test", // "Auto Scaling Group"名
    "as-test", // "Launch Configration"名
    2,         // "EC2"の最小起動数
    2,         // "EC2"の最大起動数
    array("ap-northeast-1a", "ap-northeast-1b"),
    array(
        "LoadBalancerNames"      => "as-test",
        "HealthCheckType"        => "ELB", // 後述(ポイントです!)
        "HealthCheckGracePeriod" => 60     // 後述(ポイントです!)
    )
);

var_dump($response->body);

ポイントは二つです。

一つ目のポイントは、"Auto Scaling"で起動する"EC2"の最大値と最小値を
同じ値(2)にしているところです。こうすることで、ある"EC2"が機能しなくなると、
その"EC2"をターミネートして、上記の"AMI"から新しい"EC2"を作成し、
ELBにも追加し、常に正常な"EC2"が2インスタンス稼働している状態にしてくれます。

二つ目のポイントは"HealthCheckType"を"ELB"にしているところです。
(デフォルトは"EC2"です)

そもそも"HealthCheckType"とは、"EC2"インスタンスが正常(healthy)か
異常(unhealthy)かを判断する方法で、"EC2"と"ELB"の違いは下記となります。

▼ EC2(デフォルト)
"EC2"インスタンスの"State"でチェックします。"runnning"なら"healthy"、
それ以外なら"unhealthy"となります。
▼ ELB
ELBのヘルスチェックをそのまま使います。ELBがEC2インスタンスを
"In Service"と判断している場合は"healthy"、"Out of Service"と
判断している場合は"unhealthy"となります。

今回は、"Apache"が落ちたりした場合でも("EC2"インスタンスは"running"でも)、
"Auto Scaling"で自動復旧して欲しいので、"HealthCheckType"は"ELB"としました。

また"ELB"を設定すると、"HealthCheckGracePeriod"も指定する必要があります。
これは、"EC2"インスタンスが"Auto Scaling"で起動した後に、"ELB"がヘルスチェックを
開始するまでの時間です。

"EC2"インスタンスが起動して、さらにApacheが起動するまでに"ELB"のヘルスチェックが
行われてしまうと、当然"unhealthy"と判断され、すぐにターミネートされてしまいます。
"HealthCheckGracePeriod"はこのような問題を調整する値となり、今回は60秒にしています。

実は、この"Auto Scaling Group"を設定した時点で、下記のように
"EC2”インスタンスが起動されています。


そして、当然、"ELB"にも追加されています。


"ELB"のDNS名をブラウザでアクセスすると、"EC2"インスタンスに直接アクセスしたものと
同じ画面が表示され、正しく機能していろことがわかります。


それでは、"EC2"インスタンスに障害が起きたときの実験です。

一方の"EC2"インスタンスの"Apache"を停止してみます。

# /etc/init.d/httpd stop

すると当然、"ELB"から切り離されます。


そして"ELB"から切り離さた"EC2"インスタンスは"unhealthy"とみなされるので、
下記のように"Auto Scaling"によりターミネートされます。


その後"EC2"インスタンスが二つになるように"Auto Scaling"が
新しいインスタンスを起動します。


当然"ELB"にも追加されるので、もとの2インスタンス体制に復旧したことになります。


図にすると、こんな感じでしょうか?


CDPネタは長文化の傾向にあるなー...
--------
http://www.suz-lab.com/

0 コメント: