まったり技術ブログ

Webエンジニアのセキュリティブログ

【AWS】ECSで構築した環境でオートスケーリング (2018/09)

はじめに

 「Docker(コンテナ) = 開発環境の構築に便利」という認識で止まっていましたが、最近では本番環境での利用のノウハウがネット上でも溜まりつつありますので、実際にどのようにして本番のコンテナ環境の構築・運用を実現しているのかを調べてみました。
 独自のコンテナツールを利用している企業(Netflix等)もありましたが、AWS上ではAmazon ECSというサービスが人気だそうなので、実際にさわってみました。(東京リージョンにはまだないですが、KubernetesをうんぬんするAmazon EKSもありだとか...)

 さわってみた感じ、何も考えなくでも複数のコンテナインスタンスで運用している場合にブルーグリーンデプロイメント(サービスを停止せずにデプロイ)が可能というのは非常にうれしいです。シェルで、ターゲットグループから外して、デプロイ後にターゲットグループに戻す、ということを書かずに済むので...。

 この記事では、環境の構築までを書き、オートスケーリングの検証・デプロイ時の挙動の確認は次の記事で書いていきます。

今回やりたいことのイメージ

 「リバースプロキシのNginx」、「アプリケーションサーバのSpring Boot」をそれぞれのDockerコンテナ上で動作させます。
 今回使用するDockerイメージは下記に公開しています。
GitHub - motikan2010/SpringBoot-on-Docker at release/20180909

構築の流れ

 この記事では、以下の流れで構築していきます。
 今回は 空のECSクラスタ を作成していますが、クラスタを作成するタイミングで起動するEC2コンテナインスタンスのインスタンス等の詳細を決めるようなこともでき、下記の方法以外にもやり方・手順は様々です。

  1. IMA ロールの作成
  2. 空のECSクラスタの作成
  3. Auto Scaling 起動設定の作成
  4. Auto Scaling グループの作成
  5. ALBの作成
  6. ECS サービスの作成

この記事で作成するリソース

 以下のリソース名を付けた前提で手順を説明してきます。

ECSサービス用 IAM ロール ecsServiceRole
EC2用 IAMロール ecsInstanceRole
ECSクラスター sample-ecs-cluster
ECSサービス sample-ecs-service
ALB ターゲットグループ sample-ecs-tg
ALB sample-ecs-alb
ALB セキュリティグループ sample-alb-sg
Auto Scaling セキュリティグループ sample-autoscaling-sg
Auto Scaling 起動設定 sample-autoscaling-setting
Auto Scaling グループ sample-autoscaling-group
スケールアウトアラーム EcsScaleOutAlarm
スケールインアラーム EcsScaleInAlarm

 実際にコンテナ上で動作するアプリケーションである タスク定義は事前に作成してあります ので、そこの説明は省きます。

構築

1. IMA ロールの作成

以下、2つのロールの作成を行います。

ロール名 ecsServiceRole
エンティティ Elastic Container Service
ポリシー AmazonEC2ContainerServiceRole
ロール名 ecsInstanceRole
エンティティ EC2
ポリシー AmazonEC2ContainerServiceforEC2Role

2. 空のECSクラスタの作成

"ステップ 1: クラスターテンプレートの選択"

"ステップ 2: クラスターの設定"

 「空のクラスターの作成」にチェックを入れます。
ここでチェックを入れず、起動するインスタンスタイプやインスタンス数を指定することが可能となっていますが、今回はこの画面で指定せずに、オートスケーリング起動設定時にでインスタンスの詳細を指定することにします。

3. Auto Scaling 起動設定の作成

 アプリケーションに対しての負荷によって、EC2インスタンス数の増加(スケールアウト)・削減(スケールイン)を自動的に実行する為に、オートスケーリングの設定をします。
 まずはどのようなEC2インスタンスを起動させるのかを決めるためのAuto Scaling 起動設定の作成を行なっていきます。

"1. AMI の選択"
 ECS用AMIの「amzn-ami-2018.03.f-amazon-ecs-optimized」を指定します。
このAMIにはDockerとECS コンテナエージントが導入されています。

Amazon ECS に最適化された AMI - Amazon Elastic Container Service

 ECS用AMIを利用しなくてもエージェントを手動でインストールすることによって、ECSコンテナインスタンスの作成は可能です。

Amazon ECS コンテナエージェントをインストールする - Amazon Elastic Container Service

"2. インスタンスタイプの選択" は、今回NginxとSpring Bootの2つを動作させる為に「t2.medium(6.75円/時)」を選択しました。

"3. 詳細設定"
 名前には「sample-autoscaling-setting」、IAM ロールは先ほどに作成した「ecsInstanceRole」を指定します。
 IPアドレスタイムには、パブリックIPが割り当てられる設定(デフォルト)にする必要があります。インターネットと通信ができないインスタンスだとECS コンテナインスタンスと認識されなくなります。

EC2起動時にECSコンテナインスタンスとして登録する

 ユーザデータに以下を記載することにより、EC2インスタンス起動時に指定したECSクラスターに紐づけることができます。 下記の場合は「sample-ecs-cluster」というクラスターに紐づくことになります。

#!/bin/bash
echo "ECS_CLUSTER=sample-ecs-cluster" >> /etc/ecs/ecs.config

"4. ストレージの追加" は特に設定をせずに次へ

"5. セキュリティグループの設定"
 HTTPのみを許可するようにしています。
コンテナインスタンスにSSH通信したい場合はSSHも許可するように追加する必要があります。

4. Auto Scaling グループの作成

"1. Auto Scaling グループの詳細設定"

"2. スケーリングポリシーの設定" は後ほど設定します。
今回は「通知の設定」、「タグの設定」は行わないので、この設定内容でAuto Scaling グループを作成します。

"5. 確認"

時間が経過すると2つのインスタンスが自動的に作成されました。

ECS コンテナインスタンスを見てみると、2つのインスタンスが登録されていることが確認できます。

5. ALBの作成

"1. ロードバランサーの設定"
「アベイラビリティーゾーン」はap-northeast-1a・ap-northeast-1cを指定しました。

"2. セキュリティ設定の構成"はそのまま次へ

"3. セキュリティグループの設定"

"4. ルーティングの設定"

"5. ターゲットの登録"

"6. 確認"は設定した内容で作成します。

6. ECS サービスの作成

"ステップ 1: サービスの設定"

"ステップ 2: ネットワーク構成"

「サービスの検出の統合の有効化 」のチェックを外す

"ステップ 3: Auto Scaling (オプション)"

タスクの最小数 2
タスクの必要数 2
タスクの最大数 4
スケールアウトの設定

▼▼▼ ※ 2018/10/22追記 ▼▼▼
 この記事で紹介するやり方は、EC2インスタンス数とECSタスク数それぞれにオートスケーリングの設定を行う方法を紹介している。

下記記事の方法では、EC2インスタンスのオートスケーリングのみを設定し、そのオートスケーリングをトリガとして、ECSタスク数を設定している。
こちらの方がスケールアウト・インの順番が担保されるので、安心さがある。 Amazon ECSのDockerコンテナをLambdaでAuto Scalingに連携させる | DevelopersIO ▲▲▲


CPU使用率 平均 40%以上 が検出された場合にスケールアウトが行われます。

スケールインの設定


CPU使用率 平均 20%未満 が検出された場合にスケールインが行われます。

 この設定でECS サービスを作成します。

 ECS サービスのオートスケーリング設定をしたので、閾値を超えた場合は自動的にタスクを作成しようとします。しかし、そのタスクの作成先となるコンテナインスタンスは存在していないので、結果タスクは作成されずにスケールアウトは実施されません。  それを解決する為に、閾値を超えた場合にコンテナインスタンスも自動的に作成されるようにEC2側のオートスケーリングのポリシーも設定していきます。

ECS コンテナインスタンスのオートスケーリング設定

 スケールアウト・インのアラームの閾値はECS サービスと同じ値でよいので、ECS サービス作成時に作成したアラームを指定します。

動作確認

 作成したALBに設定されているDNS名にアクセスしてみてください。