【aws】オートスケーリング(Auto Scaling)を実際に動かしてみてec2の冗長化に入門する

はじめに

想定する構成は以下のような形

f:id:yoppy0066:20160711111407p:plain

図の通りだが可用性を高めるために最低限なものをイメージしてみた。
まずはwebサーバーをec2で構築。

このwebサーバに何かあった時には別のアベイラビリティゾーンで別のec2インスタンスが起動するようにする

auto scalingでサービスアウトされるec2インスタンスはターミネートされてインスタンスごと消えてしまうのでapacheとかアプリで出力しているログはs3に残しておく

また、auto scalingでサービスインする際はec2のイメージが必要なのだが、プログラムの修正などを行うたびにイメージを作成するのは手間なので最新のプログラムはs3に置いておく形にして、ec2の起動時にそこから最新のプログラムを取得する形とする

本当はgitとかから最新のコードを取得する仕組みの方がいいかとは思うが今回はとりあえずこれで

実装

vpc、サブネット、セキュリティグループとかは既に作成済みの前提で

サブネット

用途 サブネット アベイラビリティゾーン
elb用サブネット test-subnet-elb AZ-a
web用サブネット test-subnet-web AZ-a
web用サブネット2 test-subnet-web2 AZ-c

s3にバケット作成して最新のプログラムをあげておく

s3の画面から作成
とりあえずtest-autoscalingというバケット名とする

プログラムのアップロードは画面からでもawsコマンドでもどちらでもok
ただ、実際に運用していくとなるとaws syncとかであげることになるのかなと思います

aws syncの例

aws s3 sync /var/www/html/ s3://test-autoscaling/src/ --delete

aws syncでは--excludeとか--deleteとかrsyncみたいなオプションも使える

elbの作成

基本的に画面の通りに進めてゆけばok
今回はロードバランサー名を「test-elb」としてVPC等は現在作業中のvpcをいれてゆく。

iamロールを作る

ec2からs3へのアクセスが必要なのでそれ用のiamロールを作成
必要なポリシーは「AmazonS3FullAccess」
本当はバケット単位でアクセス制御した方がいいとは思うけど今回はとりあえず全開放で

ec2インスタンスを作る

いつもどおりに画面にそってインスタンスを作ってゆく。
サブネットはAZ-a、iamロールは上記で作ったものを指定する

セキュリティグループは動作確認なので適当に。
最低限インバウンドを設定してsshとhttpが使えるようにしておけばokです

ec2で諸々セットアップしてイメージを作成する

apacheインストール

sudo yum install -y httpd

sudo vi /etc/init.d/init_terminate

#!/bin/sh
# chkconfig: 2345 90 10
# description: init and terminate script

PROG="init_terminate"
LOCK=/var/lock/subsys/$PROG

case "$1" in
  start)
    /bin/touch $LOCK
    service httpd stop
    /usr/bin/aws s3 sync s3://test-autoscaling/src/ /var/www/html/ --exclude="logs/*"
    chown -R apache:apache /var/www/html
    service httpd start
    ;;
stop)
    /bin/rm -f $LOCK
    IP=`ip addr show eth0 | sed -nEe 's/^[ \t]*inet[ \t]*([0-9.]+)\/.*$/\1/p'`
    aws s3 sync /var/log/httpd/ s3://test-autoscaling/logs/$IP/
   ;;
esac

実行権限追加

> chmod 744 /etc/init.d/init_terminate

動作確認

> service init_terminate start
/var/www/html以下にプログラムがダウンロードされていればok

> service init_terminate stop
s3://test-autoscaling/logs以下にログがアップロードされていればok

サービスに登録

> chkconfig --add init_terminate
> (chkconfig init_terminate on)
> chkconfig --list # 確認

ここまでokならawsのコンソールからイメージを作成する

auto scalingの設定

ここでようやくauto scalingの設定

ec2 > 左メニューのAuto Scalingの起動設定から
「Auto Scaling グループの作成」おして「起動設定の作成」ボタン

「マイAMI」で上記で作ったec2のイメージを選択
名前は適当に。他の項目(vpc、セキュリティグループ)などは上記で作ったweb用の設定を選択


続いて「Auto Scalingグループの作成」の入力画面となる。ここでは以下とした

グループ名 test-autoscaling-group
ネットワーク 作業中のVPC
サブネット test-subnet-web、test-subnet-web2

さらに「高度な詳細」の箇所も入力
「Elastic Load Balancing からトラフィックを受け取る」にチェックを入れて上記で作った「test-elb」を選択

auto scalingの動作確認

ここまでで一通り設定は完了。
auto scalingがec2インスタンスを立ち上げて、test-elbがhttpアクセスをec2に転送してくれるはず。
test-elbの「DNS名」よりドメインを確認してブラウザで表示されればok

また、ec2のインスタンスの一覧からauto scalingが立ち上げたインスタンスが存在すること
elbの画面のインスタンスタブにec2の状態が「InService」となっている

立ちあげるec2のインスタンス数は「Auto Scalingグループ」の詳細タブから確認できる
デフォルトで希望、最小、最大数が全て1なので常に1台が動いている状態が正常となる

試しに今動いているec2を削除すると、しばらくするとauto scalingが別のec2を立ち上げてelbの下においてくれた

さいごに

今回はec2のインスタンスが立ち上がるときと終了するときに
s3から最新プログラムの取得とs3へのログの保存を実装したが、auto scalingにはライフサイクルフックという仕組みが既にあるようでこちらを使えばもっと簡単にできるかも!?

参考
CentOSの起動スクリプトを書き方(+注意点) | 本日も乙


以上です