【AWS】ECSのクラスターの目的と作成の流れ

AWSでDockerを扱うサービスである、ECS（Elastic Container Service）のクラスターの目的と作成方法について。

##目次
1. [ECSのクラスターとは？](#ecsのクラスターとは)
2. [クラスターを使ったサービスの流れ](#クラスターを使ったサービスの流れ)
2. [クラスターの作成](#クラスターの作成)
3. [ECSのクラスターテンプレートの選択](#1-ecsのクラスターテンプレートの選択)
4. [クラスターの設定](#2-クラスターの設定)
    5. [クラスター名（必須）](#2-1-クラスター名必須)
    6. [ネットワーキング（任意）](#2-2-ネットワーキング任意)
    7. [Tags（任意）](#2-3-tags任意)
    8. [CloudWatch Container Insights（任意）](#2-4-cloudwatch-container-insights任意)
9. [サービスの作成](#3-サービスの作成)
    10. [サービスを作成するクラスターの選択](#3-1-サービスを作成するクラスターの選択)
    11. [起動タイプの選択](#3-2-起動タイプの選択)
    12. [タスク定義](#3-3-タスク定義)
    13. [サービス名](#3-4-サービス名)
    14. [サービスタイプとは？](#3-5-サービスタイプとは)
    15. [タスクの数](#3-6-タスクの数)
    16. [最小ヘルス率と最大率](#3-7-最小ヘルス率と最大率)
    17. [Blue/Greenデプロイタイプの場合](#bluegreenデプロイタイプの場合)
    18. [Deployment circuit breaker](#3-8-deployment-circuit-breaker)
19. [デプロイメントの設定](#4-デプロイメントの設定)
    20. [Blue/Green](#4-1-bluegreen)
    21. [ローリングアップデート](#4-2-ローリングアップデート)
    22. [Deployment configuration](#4-3-deployment-configuration)
    23. [CodeDeployのサービスロール](#4-4-codedeployのサービスロール)
23. [ネットワーク構成](#5-ネットワーク構成)
    24. [VPCグループの設定](#5-1-vpcグループの設定)
    26. [ロードバランサーの設定](#5-2-ロードバランサーの設定)
    27. [ロードバランス用のコンテナを設定](#5-3-ロードバランス用のコンテナを設定)
    28. [ヘルスチェックパスの設定](#5-4-ヘルスチェックパスの設定)
    29. [２つめのターゲットグループの作成](#5-5-２つめのターゲットグループの作成)
    30. [Auto Scaling](#5-6-auto-scaling)
31. [サービスの作成](#6-サービスの作成)
32. [ELB（ロードバランサー）の修正](#7-elbロードバランサーの修正)
33. [ページの表示](#8-ページの表示)



<br>
##ECSのクラスターとは？
AWSの説明では、タスクリクエストを実行できる１つ以上のコンテナインスタンスのリージョングループ。

実用例だと、**一つのプロジェクトに対し、一つのクラスターを作り、中にサービスとして、ステージング環境や開発環境をいれる**。

各サービスの中にはタスクを作って、タスクの中で必要なコンテナを定義している。

<br>
**▼クラスター、サービス、タスク、コンテナの関係**
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/563526/7ad69047-1527-7f65-42f7-543d1a6306f0.png)

ECSでクラスターを作成する場合は、単に**クラスターを作成するだけでなく、サービスの作成、ロードバランサーの設定、デプロイ方法の指定も行う**。



<br>
##クラスターを使ったサービスの流れ
複数のサービスを一つのロードバランサーで切り分ける場合のAWSの設定方法について。

###・サービスの構造
クラスターはプロジェクトを管理しやすくするためのグループといった位置付け。

その中にproductionやstagingといったサービスを作成する。

実際のサービスの根幹となるコンテナはタスクの中に定義する。このタスクをサービスの上に乗っける。

###・ネットワーキングの構造
ユーザーがFQDN（sub.example.com）を入力すると、該当するエイリアスコードからホストドメインにつなげる。

ホストドメインにはロードバランサーが設定されており、渡されたFQDNに結び付けられたコンテナにトラフィックを送る。

コンテナはリクエストに応じて、DBなど必要な別のコンテナと連携してレスポンスを返す。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/563526/fb09f8c4-b0c0-f653-d3b2-ac74f2922a20.png)



<br>
###クラスターの作成

##1. ECSのクラスターテンプレートの選択
どの仮想サーバーでコンテナを起動するか選択する。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/563526/424e3efe-8f4a-9b74-82e1-3ca76de577e9.png)

| タイプ | 内容 |
|:-:|:--|
| ネットワーキングのみ  | Fargate起動タイプを使用してタスクを実行する  |
| EC2 Linux + ネットワーク  | Linux コンテナを使用した EC2 起動タイプを使用してタスクのクラスターを起動する  |
| EC2 Windows + ネットワーク  | EC2 起動タイプと Windows コンテナを使用してタスクのクラスターを起動する  |

Fargateは運用管理をAWSが行ってくれるメンテ・保守不要のサーバー（サーバーレス）

##2. クラスターの設定
サービスを起動するためのクラスターを作成する。クラスター自体の作成は超簡単。

###2-1. クラスター名（必須）
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/563526/68b290f7-d93b-a7aa-eda4-d55b656d8eef.png)

最大 255 文字の英字 (大文字と小文字)、数字、ハイフン、アンダースコアを使用できる。

<br>
###2-2. ネットワーキング（任意）
クラスター用に新しいVPC（Virtual Private Cloudの略。 仮想プライベートクラウド）を作成する場合はチェックを入れる。



<br>
**▼作成する場合**
クラスター専用のVPCを作成する場合は、CIDRブロック、サブネットを設定（デフォルトでも可）する。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/563526/78472dbe-704b-297d-fe18-30e704b1e36c.png)



<br>
###2-3. Tags（任意）
クラスターの説明をKV（key-value）形式で記載できる。

クラスタ作成後にTagsタブから確認できる。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/563526/51e03279-38ab-cee7-530b-15f27dd1f4ab.png)


<br>
###2-4. CloudWatch Container Insights（任意）
チェックマークを入れるとCloudWatchと連携して、CPUやメモリの使用状況のログが確認できるようになる。

<br>
**▼ECSクラスターのCloudWatch例**

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/563526/9ffa72c9-f770-7720-a545-0361b1398ba7.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/563526/122e5595-ae2d-4fd7-1161-a0778ca86eb7.png)


###2-5. クラスターの作成
右下の「作成」ボタンをクリックしてクラスターを作成する。

以上でクラスターの作成は完了。




<br>
##3. サービスの作成
作成したクラスターの中にサービスを作成していく。

サービスを作成するには**ECSのタスク定義**で、コンテナの起動時の設定が完了している必要がある。

・[ECSでタスク定義する方法](https://qiita.com/yuta-38/items/03e682a3b6ae499716f1)


###3-1. サービスを作成するクラスターの選択
作成したクラスターを選択する。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/563526/b8975bfb-4203-ef6e-0f06-2bcb696104dc.png)

サービスタブの中で、左下の「作成」ボタンをクリックする。


###3-2. 起動タイプの選択
タスクを実行する仮想サーバ−の種類を選択する。選択しない場合はEC2がデフォルトとなる。

|![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/563526/d2bbb2dc-94c9-debd-35ad-b9a06ad3bba3.png)|
|:--|


###3-3. タスク定義
ECSのタスク定義で作成した項目を選択する。

タスク定義を内容を変更して複数作った場合は、使用する番号（リビジョン）を選択する。

|![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/563526/cad799fb-1d10-9ff0-ebcf-27625e71990f.png)|
|:--|


**▼ECSのタスク定義**

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/563526/67f23661-f323-a275-daea-ffb82009186e.png)


<br>
###3-4. サービス名
作成するサービスにつける名前を指定する。
クラスターを選択した時に、表示されるためわかりやすい名前にする。


|![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/563526/f6510db5-0185-7640-00b3-cf5c515c200a.png)|
|:--|

↓ 表示例

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/563526/2d80e259-6b48-2551-270d-03f80d00147f.png)

**▼Point**
クラスターの名前でどのプロジェクトかは判定可能なため、サービスの名前は各サービスの環境の名前をつけるとわかりやすい。

```:例
・クラスター名： test-app
・サービス名１： production
・サービス名2: staging
```


<br>
###3-5. サービスタイプとは？
**タスクが失敗したときの対応方法**を指定する。スケジュール戦略と呼ばれる。

サービスタイプ（スケジュール戦略）は①REPLICA戦略と②DAEMON戦略の２つがある。

**Fagateを選択した場合は、REPLICA戦略**のみとなる。（DAEMONはサポート外）


>・REPLICA戦略
クラスター全体で必要数のタスクを配置して維持。

>・DAEMON戦略
指定したすべてのタスク配置制約を満たすクラスター内のアクティブなコンテナインスタンスごとに、1 つのタスクのみをデプロイ。


<br>
###3-6. タスクの数
サービスタイプがレプリカの時のみ選択する。

上で指定した**タスク定義で起動したインスタンス（コンテナ）のうち、クラスターで実行状態を保つ数を指定**する。

**起動するコンテナが１つのみの場合は１**となる。複数のコンテナを起動し、起動状態を保ち続ける場合は、その数を記載する。


なお、デーモンの場合は、クラスターのコンテナインスタンス数に自動的に設定。


<br>
###3-7. 最小ヘルス率と最大率
ローリングアップデートのみ選択可能なオプション。

実行中のサービスをローリング更新するときに、サービスが維持するタスクの数を割合で指定する。

####最小ヘルス率とは？
RUNNING状態に保つ必要のあるサービスのタスクの下限数を％で指定したもの。

例えば必要なタスクが４つのサービスで、最小ヘルス率を50％とした場合、スケジューラーが新しいタスクを実行する時に、２つのタスクを停止して、クラスターの容量を開放する。

最小ヘルス率はデフォルトで100％。


####最大率
最大ヘルス率の略。RUNNINGまたはPENDING状態で使用できるサービスタスクの上限数を指定できる。

例えば必要なタスクが４つのサービスで、最大率が200%の場合、スケジューラは4つの古いタスクを停止する前に、4つの新しいタスクを開始することができる。

最大ヘルス率のデフォルト値は 200% です。


####Blue/Greenデプロイタイプの場合
実行中のサービスの更新がBlue/Green (CODE_DEPLOY) の場合は、最小ヘルス率・最大ヘルス率の値はデフォルト値に設定される。

最小ヘルス率： 100%
最大ヘルス率： 200%

つまり、本番環境のサービスを改修してローンチするときに、既存のタスクは停止せず起動したままの状態で、新しいサービスを起動する。

この方法であれば、新しいサービスに問題があった場合にすぐに古いサービスに戻すことができる。容量は使うが安全な更新。


<br>
###3-8. Deployment circuit breaker
ローリングアップデートのみ選択可能なオプション。

サービスの更新に失敗した場合に、自動で昔の正常だったサービスに戻してくれる便利機能。

|![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/563526/6f169e0e-8f94-c207-caa8-60420fdd6836.png)|
|:--|

＞https://aws.amazon.com/jp/blogs/news/announcing-amazon-ecs-deployment-circuit-breaker-jp/

**Blue/Greenの場合は自動的にRollbackしてくれるため設定不要**。

というか、ローリングアップデートの設定で、デフォルトの最小ヘルス率： 100%、最大ヘルス率： 200%、Deployment circuit breakerが有効でrollbackがオンになっているデプロイをBlue/Greenと呼ぶ。


<br>
##4. デプロイメントの設定
サービスを更新したときに、新しいサービスの起動方法を指定する。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/563526/c50280b5-8df1-f3e5-edf6-ceeb660da9d5.png)


###4-1. Blue/Green
ブルー・グリーンと呼ぶ。直近では主流のデプロイ方法。

サービスの更新を安全に行うために、既存のサーバーに手を加えるのではなく、**既存のサーバーはそのまま維持しながら、新しいサーバーを起動する**デプロイ方法。

新旧のサービスで状態を比較し、異常があればエラーとして報告してくれる。

また、新しいサービスが起動しない場合は、自動で旧のサービスに戻るため、サービスが落ちる心配がない。

Blueが古いサービス、Greenが新しいサービスを指している。


###4-2. ローリングアップデート
実行中のタスクを順々に停止して、順々に新しいサービスに切り替えていくデプロイ方法。

Blue/Greenよりも簡易的でスピーディな更新方法。

ただし、どれかのタスク更新で失敗した場合、更新済みのタスクと更新エラーのタスクが混在することになり、元に戻すのに手間がかかる。（このため、現在のトレンドはBlue/Green）

Deployment circuit breakerなど、より安全にサービスを更新する仕組みが用意されている。

ローリングアップデートの設定で、デフォルトの最小ヘルス率： 100%、最大ヘルス率： 200%、Deployment circuit breakerが有効でrollbackがオンになっているデプロイがBlue/Green。


<br>
###4-3. Deployment configuration
デプロイ中にCodePlayが使用する条件を選択する。

旧サービスにアクセスしている**トラフィックの何％ずつを新しいサービスに移行させるか**の、％と経過時間を指定できる。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/563526/5ac76c32-80f7-620c-40c1-0ad210fd70a0.png)


| 設定 | 内容 |
|:-:|:--|
| CodeDeployDefault.ECSAllAtOnce  | すべてのトラフィックを、新しいコンテナに一度に移行。  |
| CodeDeployDefault.ECSLinear10PercentEvery1Minutes  | すべてのトラフィックが移行されるまで、1分ごとに10%を移行  |
| CodeDeployDefault.ECSLinear10PercentEvery3Minutes  | すべてのトラフィックが移行されるまで、3分ごとに10%を移行  |
| CodeDeployDefault.ECSCanary10Percent5Minutes  | 	
最初にトラフィックの10%を移行。残りの90%は5分後にデプロイ  |
| CodeDeployDefault.ECSCanary10Percent15Minutes  | 最初にトラフィックの10%を移行。残りの90%は15分後にデプロイ   |

基本的には`CodeDeployDefault.ECSAllAtOnce`を選択。


<br>
###4-4. CodeDeployのサービスロール
CodeDeployがBlue/Greenで自動更新する際に、ユーザーに変わってAWSに許可を与えるためのIAMロール。

CodeDeploy IAMロール（ecsCodeDeployRole）として設定する。

＞https://docs.aws.amazon.com/AmazonECS/latest/developerguide/codedeploy_IAM_role.html


<br>
##5. ネットワーク構成
###5-1. VPCグループの設定
タスク定義のネットワークグループがAWS VPCの場合に設定可能。

タスク定義のプラットフォームにFagateを選択している場合は、AWS VPCのため設定できる。

|![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/563526/dfb8ca1e-6b9a-8933-d4af-afe669e88d90.png)|
|:--|


**・クラスターVPC**
タスクやサービスのサブネットとセキュリティグループを表すオブジェクト。


**・サブネット**
タスクやサービスに関連づけるサブネットワーク。

|![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/563526/88f3c839-8019-ac73-1bd4-5ffb94f75bc3.png)|
|:--|


**・セキュリティグループ**
タスクやサービスに関連づけるセキュリティグループ。

デフォルトは新規で自動割り当て。既存のセキュリティーグループから選ぶことも可能。

**・パブリックIPの自動割り当て**
ENI（Elastic Network Interface）がパブリックIPアドレスを受け取るかどうか。

EnableかDisableで選択する。


<br>
##5-2. ロードバランサーの設定
タスク間のトラフィックを分散させる。事前にEC2コンソールでロードバランサーを作成しておく必要がある。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/563526/5da16c30-c79c-b8d9-6041-f6808bf9c959.png)


ロードバランサーはApplication Load Balancer（HTTPやHTTPSを振り分ける）か、Network Load Balancer（超高性能タイプ）から選択できる。




###ロードバランサーとRoute53のエイリアスレコード
ロードバランサーでタスク内のコンテナにアクセスするために、Route53のエイリアスレコードを作成しておく。

ネットワーキングの流れは、

```
リクエスト
↓
ロードバランサ
↓
コンテナ
```

となる。

・[エイリアスレコードの作成手順](https://qiita.com/yuta-38/items/7ac74a4be398a0483f36)


<br>
##5-3. ロードバランサー用のコンテナを設定
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/563526/dcedb0e7-e1fa-866d-63ab-5cfd754cd196.png)

指定したタスクの中で定義したコンテナが選択できる。（コンテナが１つの場合は選択肢は１つ）

↓ 追加ボタンをクリック

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/563526/6a4316d8-a27d-fbf3-6f5c-6ab8c96f77ed.png)


**・プロダクションリスナーポート**
HTTP（80）かHTTPS(443)を選択。

指定したロードバランサーで設定してあるリスナーを選ぶ。

<br>
**▼ロードバランサーのリスナーの例**
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/563526/461ca5b0-2f13-8e30-f5ae-40d23fd93b9c.png)

**▼80番ポートの設定例**
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/563526/9bdec78e-d141-f084-22c8-66d871a3e1fa.png)


ここでは、80番ポートにアクセスした場合、443番にリダイレクトする指定になっている。このため、プロダクションリスナーポートは443を選択。



**・テストリスナー**
ロードバランサーでルーティングする前に飛び先のアプリケーションをテストする。

不要の場合はチェックを外す。


<br>
###5-3. ロードバランス用のコンテナを設定
ロードバランサーでトラフィックを接続するための、コンテナにターゲットグループを作成する。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/563526/667a3726-441b-12fd-6750-f6e8b09ea774.png)

**▼ターゲットグループの名前**
既存、または新規作成する。

**▼ターゲットグループのプロトコル**
コンテナの開放ポートに繋ぐ。80番を開けている場合はHTTPにする。

**▼パスパターン**
ロードバランサーのIF文で、〇〇のパスならの部分に当たる。

**スラッシュ以下のパスしか入力できない**ため、FQDN（サブドメ）を入力したい場合は、ここはダミーを設定しておき、別途ロードバランサーで設定する。

**▼評価順**
if文を処理をかけていく順番。番号が小さい条件から検証していく。




<br>
###5-4. ヘルスチェックパスの設定
ヘルスチェックを実行するパスを設定する。
ロードバランサーで（ELBコンソール）で設定する。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/563526/f0ab042d-4216-0784-c172-85cee75bc3c8.png)



<br>
###5-5. ２つめのターゲットグループの作成
デプロイの方法で**Blue/Greenを選択した場合は、ターゲットグループを２つ入力する必要がある**。

新しいGreenのターゲットグループ２にアクセスしたときにエラーが発生した場合、Blueのターゲットグループ１にトラフィックを戻すため。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/563526/22c6758b-7bca-c2ef-ae9d-798ad754edae.png)

**▼パスパターン**
選択不可。ターゲットグループ１のパスパターンを継承する。



###5-6. Auto Scaling
CloudWatchでアラームがでた場合に、オートスケーリングするかどうか。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/563526/7389874c-3163-0006-dc08-a6c4a0d927d4.png)

Auto Scallingする場合は、最小・最大タスク数などを選ぶ。


###6. サービスの作成
作成ボタンを押すと、５つのサービスが一気に作成される。

1. ロードバランサーのターゲットグループ１
2. ロードバランサーのルール
3. ロードバランサーのターゲットグループ２
4. サービスの作成
5. Blue/Green デプロイメント（CodeDeploy）

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/563526/879e66a8-fe53-e689-4e95-9f0198647af6.png)

>※注意
それぞれが別々のサービス上に作成されるため、ミスがあった場合は、全てを削除する必要がある。


↓　サービスを表示

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/563526/41ee65f2-d96e-3b6c-9ce6-347ef51f8203.png)

以上でクラスターの作成が完了。


##7. ELB（ロードバランサー）の修正
5-3のロードバランス用のコンテナを設定ではFQDNを入力することができずダミーを入力したため、ELBコンソールから入力内容を修正する。

ELB（ロードバランサー）から指定のロードバランサーを選択し、ルールを表示する。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/563526/2430d1fd-267a-fc16-6fe7-a2845d2d61e2.png)

先ほどダミーで登録したルーティングが追加されている。

上の鉛筆マークをクリックしてこれを編集する。


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/563526/ff9cf967-f009-dc1f-3847-45d6eb5000a7.png)

FQDNを入力したいため、**ホストヘッダー**を選択する。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/563526/f2d4aa81-7a6d-7011-78bc-d9c5b88aeda4.png)

修正が完了したら、右上の「更新」をクリックして完了。



<br>
##ロードバランサーの注意点
バランサーはユーザーとサービスを繋ぐためとても重要。

**間違って既存のルーティングを変更したり削除してしまうと、サービスにアクセスできなくなってしまう**ため注意が必要。


Route53とバランサーはサービスの根幹で、他のサービスともつながっている場合も多いため注意すること。



<br>
##8. ページの表示
以上で**AWS上での設定が完了**。

クラスターで該当のプロジェクトを確認したときに、RUNNINGになっていればOK。指定したURLを入力すればページを開くことができる。

ページはイメージの中で定義したルーティングやビューに従う。


ページが表示されない場合は、ヘルスチェックでサーバーが動いているか確認するなどの方法がある。（別途設定が必要）


<br>
**▼ヘルスチェックの例**
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/563526/9527734e-f8db-d999-e1a3-0789e44d0e5b.png)


<br>
以上。