AWSでウェブアプリケーション環境構築：⑧サーバ負荷に応じてwebサーバがオートスケーリングする仕組みを構築

# はじめに
これはシリーズ記事の中の1つです。

[AWSでウェブアプリケーション環境構築：⓪概要](https://qiita.com/minato-naka/items/ddb5f5301f9f590cdcbf)
[AWSでウェブアプリケーション環境構築：①EC2インスタンスにwebサーバを構築](https://qiita.com/minato-naka/items/c21e4d53db7a720f8fdd)
[AWSでウェブアプリケーション環境構築：②RDSでDBを作成し、Laravelサンプルアプリを動かす最小構成を構築](https://qiita.com/minato-naka/items/03f9dbd09eb3919a501f)
[AWSでウェブアプリケーション環境構築：③ロードバランサーを作成し、webサーバを冗長化する](https://qiita.com/minato-naka/items/396e2a25ec9a94840a67)
[AWSでウェブアプリケーション環境構築：④ElastiCacheのRedisを作成し、セッション共有可能にする](https://qiita.com/minato-naka/items/76cd5f660d987d34f7be)
[AWSでウェブアプリケーション環境構築：⑤webサーバをプライベートサブネットに配置し、メンテナンス用踏み台サーバを構築](https://qiita.com/minato-naka/items/406c2f247c0d29a93665)
[AWSでウェブアプリケーション環境構築：⑥Route53を利用して独自ドメインでアクセス可能にする](https://qiita.com/minato-naka/items/6f29694c1540f04dedb2)
[AWSでウェブアプリケーション環境構築：⑦ACMを利用してHTTPS通信可能にする](https://qiita.com/minato-naka/items/1a4f03e85857b8f61c4f)
[AWSでウェブアプリケーション環境構築：⑧サーバ負荷に応じてwebサーバがオートスケーリングする仕組みを構築](https://qiita.com/minato-naka/items/c0fab5d9fbb1cce68ac9)
**↑↑↑現在の記事↑↑↑**


# 前回まで
![7.png](https://qiita-image-store.s3.amazonaws.com/0/297693/4f885d07-a7ee-d569-b5e7-2d95275287d0.png)

前回はACMを利用してSSL証明書を作成し、
ALBにHTTPSリスナーを追加してLaravelサンプルアプリにHTTPSアクセスできるように設定しました。

# 今回構築する環境
![8.png](https://qiita-image-store.s3.amazonaws.com/0/297693/6918e477-81e6-1fc3-5f8c-ddccd61f6af4.png)

webサーバの周りにあるこれが今回の追加箇所です。
![aws laravelサンプル-ページ9.png](https://qiita-image-store.s3.amazonaws.com/0/297693/429888e8-1852-1063-25a7-3624a1eaa46c.png)

現在はこのLaravelサンプルアプリに大量のアクセスが発生し
サーバ負荷が高くなった場合、
レスポンスが極端に遅くなったり
最悪の場合はサーバが停止してしまったりします。

この課題を解決するために、
オートスケーリングという機能を利用して
webサーバに一定の負荷がかかったら自動でサーバ台数が増えるような仕組みを構築します。

また、すでに今使っているwebサーバ2台は
もう利用しないので停止しておきます。

いま https://laravel-sample.net/ にアクセスするとタイムアウトする状態です。

# オートスケーリング設定
オートスケーリングの仕組みを構築するには、
1. 起動設定の作成
2. Auto Scalingグループの作成
の作業が必要です。

## 起動設定の作成
起動設定とは、簡単に言うと
**どのようなEC2インスタンスを作成するか？**
の設定です。

オートスケーリングの仕組みができると
サーバ負荷に応じてEC2インスタンスが自動で作られたり削除されたりしますが、
その自動で作成されるEC2インスタンスが
どのAMIを使うか？
インスタンスタイプは何にするか？
ボリュームサイズはどうするか？
などを設定します。

いつも手動でEC2インスタンスを作成するときに設定しているものですね。

マネジメントコンソールの[EC2]のページの
サイドメニューの[起動設定]をクリックし、
上部にある[起動設定の作成]ボタンをクリック。

### AMI の選択
[マイAMI]から以前作成した[laravel-sample-ami-web-2]を選択します。

### インスタンスタイプの選択
いつも通りt2.microです。

### 詳細設定
起動設定の名前は[laravel-sample-launch-config]にして、
あとはデフォルトのままで進みます。
![screencapture-us-east-2-console-aws-amazon-ec2-autoscaling-home-2019-02-07-14_05_42.png](https://qiita-image-store.s3.amazonaws.com/0/297693/642efc45-f74c-1383-08bf-02087a3b14e4.png)

### ストレージの追加
デフォルト設定のまま進めます。

### セキュリティグループの設定
[laravel-sample-sg-web]を選択します。

### 確認
設定内容を確認し、
[起動設定の作成]をクリックして
最後のキーペア選択で[laravel-sample-key-pair]を選択して
作成します。

これで起動設定の作成は完了です。

## Auto Scalingグループの作成
Auto Scalingグループの設定は、簡単に言うと
サーバ台数の最大最小と、
サーバを配置するネットワーク
の設定をするものです。

オートスケーリングの仕組みができると
サーバ負荷に応じてサーバが自動で増えたり減ったりしますが、
負荷が高くなれば無限に台数が増えるわけではなく、
また負荷が低ければ1台まで減ってしまうわけではありません。

自分で最大の台数と最小の台数を決定する必要があります。

マネジメントコンソールの[EC2]のページの
サイドメニューの[Auto Scalingグループ]をクリックし、
上部にある[Auto Scalingグループの作成]ボタンをクリック。

表示された起動設定選択画面で、
先ほど作成した[laravel-sample-launch-config]を選択します。
![screencapture-us-east-2-console-aws-amazon-ec2-autoscaling-home-2019-02-07-14_22_00.png](https://qiita-image-store.s3.amazonaws.com/0/297693/18cad4c3-e1ee-a4a2-e2be-f16f8419c16d.png)

### Auto Scaling グループの詳細設定
下記のように設定します。
![screencapture-us-east-2-console-aws-amazon-ec2-autoscaling-home-2019-02-07-15_21_17.png](https://qiita-image-store.s3.amazonaws.com/0/297693/187c21be-5776-bc29-d8d2-01fe9cf6b2bf.png)

|項目|設定値|説明|
|:------------------------|:-------------------------|:-------------------------|
|グループ名|laravel-sample-auto-scaling-group|このAuto Scaling グループの名前。<br>自分が管理するための任意の名前を付ける。|
|起動設定|{先ほど作成した[laravel-sample-launch-config]の起動設定}|このAuto Scaling グループで作成されるインスタンスの元になる起動設定。|
|グループサイズ|2|このAuto Scaling グループの初期のインスタンス台数。|
|ネットワーク|{[laravel-sample-vpc]のVPCを選択}|インスタンスが配置されるVPC。|
|サブネット|{[laravel-sample-subnet-private-a]と[laravel-sample-subnet-private-b]を選択}|インスタンスが配置されるサブネット。|

### スケーリングポリシーの設定
ここで
[このグループを初期のサイズに維持する]を選択した場合は
サーバ負荷に応じてサーバ台数を増やしたり減らしたりはせず、
先ほど設定したグループサイズである2台構成を常にキープしようとします。

つまり、サーバに障害が発生したりして1台が使えない状態になったら
2台構成をキープするために自動でサーバが追加されるということです。

[スケーリングポリシーを使用して、このグループのキャパシティを調整する]を選択したら、
今回やろうとしている
サーバ負荷に応じたサーバ増減の仕組みを作ることができます。

スケーリングポリシーには現在
・Target tracking scaling
・Step scaling
・Simple scaling
の3種類がありますが、
一番設定が簡単でわかりやすいTarget tracking scalingを設定します。
3つのスケーリングポリシーの違いについては下記を確認するといいです。
https://docs.aws.amazon.com/ja_jp/autoscaling/ec2/userguide/as-scale-based-on-demand.html


今回は下記のように設定してみます。
![screencapture-us-east-2-console-aws-amazon-ec2-autoscaling-home-2019-02-07-16_44_22.png](https://qiita-image-store.s3.amazonaws.com/0/297693/c4d30507-49e9-1749-974d-c015fd8dbb61.png)


[スケーリング範囲 **2** および **3** インスタンス]
の項目については、
先ほど述べたサーバの最大台数、最小台数です。

今回は最小で2台、最大で3台に設定します。

[スケールグループサイズ]は下記のように設定します。

|項目|設定値|説明|
|:------------------------|:-------------------------|:-------------------------|
|名前|laravel-sample-scaling-group-size|このスケールグループサイズの名前。<br>自分が管理するための任意の名前を付ける。|
|メトリクスタイプ|CPUの平均使用率|オートスケールのトリガーになるメトリクスの種類。|
|ターゲット値|70|CPU使用率が何%になったらスケールイン・アウトさせたいか。|
|インスタンスは（スケーリング後にウォームアップする秒数）|300|デフォルトの300秒に設定する。|
|スケールインの無効化|チェック無し|スケールインを無効にするかどうかの設定。|

この設定内容を要約すると、
オートスケーリングのインスタンスたちのCPU平均使用率が70%以下になるように、
自動でサーバを増減する。
という設定になります。

### 通知の設定
オートスケーリング機能によってサーバが増えた時やサーバが減ったときに、
通知を行うかどうかの設定です。

今回は不要なのでこのまま次に進みます。

### タグを設定
Nameタグに[laravel-sample-auto-scaling-group]を設定します。

### 確認
これまでの入力内容を確認し、
問題なければ[Auto Scalingグループの作成]をクリックします。

これでAuto ScalingグループのEC2サーバが作られます。
EC2の一覧ページを確認すると、
インスタンスが2台追加されていると思います。

# ALBのターゲットグループに追加
先ほどオートスケーリング設定のされたEC2サーバが2台できましたが、
この2台はALBに紐づいていないため、
ただ孤立したwebサーバが存在しているだけです。

https://laravel-sample.net/ にアクセスしても
Laravelサンプルアプリは表示されません。

オートスケーリング機能によって作成されるEC2サーバが
ALBに自動で紐づくように設定します。

Auto Scalingグループの一覧ページで
先ほど作成した[laravel-sample-auto-scaling-group]をチェックし、
ページ上部の[操作]→[編集]をクリック。

[ターゲットグループ]の項目で、
以前作成した[laravel-sample-target-group]を選択し、
[保存]ボタンをクリックします。
<img width="380" alt="screencapture-us-east-2-console-aws-amazon-ec2-autoscaling-home-2019-02-07-15_48_00.png" src="https://qiita-image-store.s3.amazonaws.com/0/297693/80fd71e7-7c9a-b351-1ed4-959b6811e2ed.png">

これで、オートスケーリングによって作成されたインスタンスが
自動でALBに紐づくようになりました。

https://laravel-sample.net/ にアクセスして
正常にLaravelサンプルアプリが表示されれば正しく設定できています。
※設定が反映されるのに少し時間がかかります

# スケーリングテスト
オートスケーリングの設定がすべて完了し、
ALB経由でアプリに接続できる状態になったので、
実際にサーバに負荷をかけてスケールアウトするかどうか、
負荷を減らしてスケールインするかのテストを行ってみます。

## スケールアウトのテスト
まずは踏み台サーバにSSH接続し、
そこからオートスケーリングで作成されたwebサーバにSSH接続します。

そこでこのコマンドを実行します。

```shell
yes > /dev/null
```

これは、 ただひたすら `yyyyyyyyyyyyyyy` と出力するコマンドで、
サーバに負荷をかけるテストの際によく使われるコマンドです。
（停止する場合は`Ctl + C`をしてください）

yesコマンドを実行したままで、
topコマンドを実行すればサーバのCPU使用率が確認できます。
<img width="962" alt="キャプチャ.PNG" src="https://qiita-image-store.s3.amazonaws.com/0/297693/20b64e71-55a0-bd55-ab28-e47a73885a5f.png">

赤枠がCPU使用率で、
99.3%になっているので十分に負荷がかかっています。
※グループ内のインスタンスのCPU **平均使用率** がトリガーになるため、
稼働中の各サーバで負荷をかけてCPU使用率を上げてください。

しばらくこの状態にして、
EC2インスタンス一覧ページを見ながら
インスタンスが追加されるかどうか確認してみます。

しばらく待つと、
EC2インスタンス一覧ページに新しいインスタンスが1台追加され
3台構成になりました。
正しくスケールアウトしています。
※スケールアウトするのに最低でも5分以上は負荷をかけ続ける必要があります。

## スケールインのテスト
次に、yesコマンドを停止してサーバ負荷を減らし、
自動でサーバが減って2台構成に戻るか確認します。

`Ctl + C`でyesコマンドを停止し、
またEC2インスタンス一覧ページを確認します。

しばらく待つと、
1台のインスタンスのステータスが[terminated]に変わりました。
正しくスケールインできています。

これで、オートスケーリングの設定はすべて完了です。

# 最後に
もし機会があれば、
CloudFront経由でアクセスできるようにしたり、
S3と連携してみたり、
これまでのサーバ構成をCloudFormationを使って構築してみたり
さらに続きを実践してみたいと思います。