Auto Scaling、CloudWatch、Elastic Load Balancing、カスタムAMIの組み合わせ

この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。

Auto ScalingとCloudWatchとElastic Load Balancingを組み合わせた動作

複数のアベイラビリティゾーンに渡ったAuto Scalingグループを作成し、ELBでリクエストを振り分けるようにします。そして、CloudWatchのアラーム機能によってインスタンスのCPU使用率が80%を超えたらスケールアウトするようにします。

最初にElastic Load Balancingを作成する

Auto Scalingグループ作成時にELBを指定できるように、先にELBを作成して設定も行います。

$ elb-create-lb MyLB --headers --listener "lb-port=80,instance-port=80,protocol=HTTP" \
  --availability-zones ap-northeast-1a,ap-northeast-1b --region ap-northeast-1
DNS_NAME  DNS_NAME
DNS_NAME  MyLB-0000000000.ap-northeast-1.elb.amazonaws.com

ヘルスチェックを設定します。

$ elb-configure-healthcheck MyLB --headers --target "HTTP:80/ping.txt" --interval 30 \
  --timeout 3 --unhealthy-threshold 2 --healthy-threshold 2 --region ap-northeast-1
HEALTH_CHECK  TARGET        INTERVAL  TIMEOUT  HEALTHY_THRESHOLD  UNHEALTHY_THRESHOLD
HEALTH_CHECK  HTTP:80/ping  30        3        2                  2

単独で使う場合、elb-register-instances-with-lbコマンドを使ってELBにインスタンスを追加しますが、今回はAuto Scalingにて勝手に追加してもらいます。

自動起動用のカスタムAMIを作成する

Auto Scalingポリシーによってインスタンスが起動する際、素の状態のAMIを起動してしまうと、必要なソフトウェアのインストールや設定を全て最初から行わなければなりません。ですから、あらかじめ設定済みのAMIを用意する必要があります。そして、起動コンフィグで指定してあげましょう。これで、スケールアウト/ダウンする際に設定済みのインスタンスが立ち上がります。

まずは、ベースとなるインスタンスの起動をします。今回のデモでは、あらかじめmykey1という名前でキーペアを作成しておきました。後ほどSSHでログインする際にpemファイルを指定する必要があります。

$ ec2-run-instances ami-300ca731 -g default -k mykey1 -t t1.micro --region ap-northeast-1
RESERVATION	r-e2e5b8e3	771293814336	default
INSTANCE	i-8e30178f	ami-300ca731			pending	mykey1	t1.micro	2011-08-27T13:35:58+0000	ap-northeast-1a	aki-d209a2d3		monitoring-disabled					ebs			paravirtual	xen		sg-06c26807	default

SSH接続できるか確認しましょう。セキュリティポリシーで22番ポートを開きます。そして接続しましょう。

$ ssh -i key/mykey1.pem ec2-user@ec2-XXX-XXX-XXX-XXX.ap-northeast-1.compute.amazonaws.com

       __|  __|_  )  Amazon Linux AMI
       _|  (     /     Beta
      ___|\___|___|

次にHTTP(80ポート)アクセスに対して応答するようにHTTPサーバをインストールし起動します。

$ sudo yum install httpd
Loaded plugins: fastestmirror, priorities, security
Loading mirror speeds from cached hostfile
amzn-main                                                | 2.1 kB     00:00     
amzn-updates                                             | 2.1 kB     00:00     
Setting up Install Process
Resolving Dependencies
--> Running transaction check
---> Package httpd.i686 0:2.2.16-1.11.amzn1 set to be updated
--> Processing Dependency: httpd-tools = 2.2.16-1.11.amzn1 for package: httpd-2.2.16-1.11.amzn1.i686
--> Processing Dependency: libapr-1.so.0 for package: httpd-2.2.16-1.11.amzn1.i686
--> Processing Dependency: libaprutil-1.so.0 for package: httpd-2.2.16-1.11.amzn1.i686
--> Processing Dependency: system-logos for package: httpd-2.2.16-1.11.amzn1.i686
--> Processing Dependency: apr-util-ldap for package: httpd-2.2.16-1.11.amzn1.i686
--> Running transaction check
---> Package apr.i686 0:1.3.9-3.8.amzn1 set to be updated
---> Package apr-util.i686 0:1.3.9-3.9.amzn1 set to be updated
---> Package apr-util-ldap.i686 0:1.3.9-3.9.amzn1 set to be updated
---> Package httpd-tools.i686 0:2.2.16-1.11.amzn1 set to be updated
---> Package system-logos.noarch 0:4.9.99-11.13.amzn1 set to be updated
--> Finished Dependency Resolution

Dependencies Resolved

================================================================================
 Package            Arch        Version                 Repository         Size
================================================================================
Installing:
 httpd              i686        2.2.16-1.11.amzn1       amzn-main         1.1 M
Installing for dependencies:
 apr                i686        1.3.9-3.8.amzn1         amzn-updates      126 k
 apr-util           i686        1.3.9-3.9.amzn1         amzn-main          84 k
 apr-util-ldap      i686        1.3.9-3.9.amzn1         amzn-main         6.9 k
 httpd-tools        i686        2.2.16-1.11.amzn1       amzn-main          60 k
 system-logos       noarch      4.9.99-11.13.amzn1      amzn-main         9.7 k

Transaction Summary
================================================================================
Install       6 Package(s)
Upgrade       0 Package(s)

Total download size: 1.4 M
Installed size: 3.3 M
Is this ok [y/N]: y
Downloading Packages:
(1/6): apr-1.3.9-3.8.amzn1.i686.rpm                      | 126 kB     00:00     
(2/6): apr-util-1.3.9-3.9.amzn1.i686.rpm                 |  84 kB     00:00     
(3/6): apr-util-ldap-1.3.9-3.9.amzn1.i686.rpm            | 6.9 kB     00:00     
(4/6): httpd-2.2.16-1.11.amzn1.i686.rpm                  | 1.1 MB     00:00     
(5/6): httpd-tools-2.2.16-1.11.amzn1.i686.rpm            |  60 kB     00:00     
(6/6): system-logos-4.9.99-11.13.amzn1.noarch.rpm        | 9.7 kB     00:00     
--------------------------------------------------------------------------------
Total                                           3.7 MB/s | 1.4 MB     00:00     
amzn-main/gpgkey                                         | 1.9 kB     00:00 ... 
Importing GPG key 0x21C0F39F "Amazon Linux AMI (Beta) <linux-security@amazon.com>" from /etc/pki/rpm-gpg/RPM-GPG-KEY-amazon-beta
Is this ok [y/N]: y
Running rpm_check_debug
Running Transaction Test
Transaction Test Succeeded
Running Transaction
  Installing     : system-logos-4.9.99-11.13.amzn1.noarch                   1/6 
  Installing     : apr-1.3.9-3.8.amzn1.i686                                 2/6 
  Installing     : apr-util-1.3.9-3.9.amzn1.i686                            3/6 
  Installing     : httpd-tools-2.2.16-1.11.amzn1.i686                       4/6 
  Installing     : apr-util-ldap-1.3.9-3.9.amzn1.i686                       5/6 
  Installing     : httpd-2.2.16-1.11.amzn1.i686                             6/6 

Installed:
  httpd.i686 0:2.2.16-1.11.amzn1                                                

Dependency Installed:
  apr.i686 0:1.3.9-3.8.amzn1               apr-util.i686 0:1.3.9-3.9.amzn1     
  apr-util-ldap.i686 0:1.3.9-3.9.amzn1     httpd-tools.i686 0:2.2.16-1.11.amzn1
  system-logos.noarch 0:4.9.99-11.13.amzn1

Complete!

WEBサーバを起動します。

$ sudo service httpd start
Starting httpd:                                            [  OK  ]

再起動時の自動起動をONにします。

$ sudo chkconfig httpd on
$ sudo chkconfig --list httpd
httpd          	0:off	1:off	2:on	3:on	4:on	5:on	6:off

まずはEC2インスタンスのWEBサーバに繋がるかブラウザで確認します。

次にELBがヘルスチェックする固定ファイルを作成して実際にアクセスできるか確認します。ここで気をつけるのは、ルートパスを指定してはいけないことです。必ず存在する固定ファイル(ping.txtなど)の場所を指し示してください。タイムアウトの可能性がありますので動的な応答をする.phpや.jspは避けてください。

$ cd /var/www/html/
$ sudo vi ping.txt
hello

ブラウザで表示できました。

それでは、カスタムAMIを作成します。AMI名はそれぞれの環境で異なります。

$ ec2-create-image i-8e30178f --region ap-northeast-1 -n Httpd
IMAGE	ami-9a54e19b

しばらく待ってから仕様可能な状態か確認します。

$ ec2-describe-images -o self --region ap-northeast-1 
IMAGE	ami-9a54e19b	771293814336/Httpd	771293814336	available	private		i386	machine	aki-d209a2d3			ebs	paravirtual	xen
BLOCKDEVICEMAPPING	/dev/sda1		snap-5a187831	8

availableということで使える状態になりました。

複数AZに渡ったAuto Scalingグループを作成する

as-create-auto-scaling-groupコマンドで複数AZに渡ったAuto Scalingグループを作成します。 まず始めに、ELBからの疎通確認用にEC2インスタンス内でWEBサーバを起動するためにSSHログイン用のキーペアを指定した起動コンフィグを作成します。 自動起動するインスタンスは、先ほど作成したカスタムAMIを指定してあげます。

$ as-create-launch-config t1config2 --region ap-northeast-1 --image-id ami-9a54e19b \
  --instance-type t1.micro --group default --key mykey1
OK-Created launch config

続きまして、上記で作成したELBと起動コンフィグを指定してAuto Scalingグループを作成します。

$ as-create-auto-scaling-group mygroup3 --launch-configuration t1config2 \
  --availability-zones ap-northeast-1a,ap-northeast-1b --min-size 2 --max-size 4 \
  --load-balancers MyLB --region ap-northeast-1
OK-Created AutoScalingGroup

最後にELBからAuto Scalingグループへのアクセスが正常に動いているか確認をします。InServiceになっていればOKです。

$ elb-describe-instance-health MyLB --region ap-northeast-1 --headers
INSTANCE_ID  INSTANCE_ID  STATE      DESCRIPTION  REASON-CODE
INSTANCE_ID  i-680b2c69   InService  N/A          N/A
INSTANCE_ID  i-6a0b2c6b   InService  N/A          N/A

それでは本線に戻ります。

Auto Scalingポリシーの作成とCloudWatchアラートの作成

CPUが80%を超えたとき用の動作として、スケールアップのポリシーを作成します

$ as-put-scaling-policy myscaleuppolicy2 --g mygroup3 --adjustment=1 \
  --type ChangeInCapacity --cooldown 30 --region ap-northeast-1
arn:aws:autoscaling:ap-northeast-1:771293814336:scalingPolicy:ec3bc7b7-42c7-48b0-9dfd-666285ab8e55:autoScalingGroupName/mygroup3:policyName/myscaleuppolicy2

スケールアップポリシーを呼び出すCloudWatchのアラートを登録します。

$ mon-put-metric-alarm myhighcpualarm2 --comparison-operator GreaterThanThreshold --evaluation-periods 1 \
  --metric-name CPUUtilization --namespace "AWS/EC2" --period 600 --statistic Average \
  --threshold 80 --alarm-actions arn:aws:autoscaling:ap-northeast-1:771293814336:scalingPolicy:ec3bc7b7-42c7-48b0-9dfd-666285ab8e55:autoScalingGroupName/mygroup3:policyName/myscaleuppolicy2 \
  --dimensions "AutoScalingGroupName=mygroup3" --region ap-northeast-1
OK-Created Alarm

スケールダウンのポリシーを作成します

$ as-put-scaling-policy myscaledownpolicy2 --g mygroup3 --adjustment=-1 \
  --type ChangeInCapacity --cooldown 30 --region ap-northeast-1
arn:aws:autoscaling:ap-northeast-1:771293814336:scalingPolicy:3d5a4ee0-0f9f-413d-a66b-21f50e36bb04:autoScalingGroupName/mygroup3:policyName/myscaledownpolicy2

スケールダウンポリシーを呼び出すCloudWatchのアラートを登録します。

$ mon-put-metric-alarm mylowcpualarm2 --comparison-operator LessThanThreshold --evaluation-periods 1 \
  --metric-name CPUUtilization --namespace "AWS/EC2" --period 600 --statistic Average \
  --threshold 40 --alarm-actions arn:aws:autoscaling:ap-northeast-1:771293814336:scalingPolicy:3d5a4ee0-0f9f-413d-a66b-21f50e36bb04:autoScalingGroupName/mygroup3:policyName/myscaledownpolicy2 \
  --dimensions "AutoScalingGroupName=mygroup3" --region ap-northeast-1
OK-Created Alarm

これでインスタンスの状態が変わった際にCloudWatchのアラートを経由してAuto Scalingポリシーが実行されます。

まとめ

Auto Scaling、CloudWatch、Elastic Load Blancing、カスタムAMIを組み合わせることによって、EC2インスタンスの運用を自動化することができました。Amazon Web Servicesは、サービスを組み合わせてプロアクティブに設定をすることによって運用に関する負荷を最小化できることを感じて頂けたと思います。サービスの組み合わせを理解して楽しく設定しましょう!