Amazon ECSでALBとFargate使ってNginxのコンテナを動かしてみる

## Amazon ECSについて

Amazon ECS(Amazon Elastic Container Service)とはDockerコンテナを実行させるためのサービスです。

ECSでのコンテナの動かし方には2種類あり、EC2上で動かすものと、Fargateと呼ばれるインスタンスを抽象化してコンテナのみ扱うものがあります。

今回はFargateを使用する方のECSの設定を行っていきます。

## Dockerイメージの準備

まずはnginxのイメージを元にしたDockerのイメージを作成します。

### Dockerfile作成

```Dockerfile
FROM nginx:latest
  
COPY index.html /usr/share/nginx/html

EXPOSE 80
```

```index.html
<!DOCTYPE html>
<html lang="ja">
<head>
  <meta charset="UTF-8">
  <title>Title</title>
</head>
<body>
  <h1>INDEX</h1>
</body>
</html>
```

Dokerイメージをビルドします。

```sh
docker build -t nginx-test .
```

### Amazon ECRへpush

リポジトリからpullする必要がありますのでDocker用のリポジトリが必要となります。
幸いAWSにはAmazon ECRというリポジトリサービスがありますのでこちらを使用します。

```sh
aws ecr get-login --no-include-email --region ap-northeast-1
-> 出力されたコマンドを実行する
docker tag nginx-test:latest xxxxxxxx.dkr.ecr.ap-northeast-1.amazonaws.com/nginx-test:1
docker push xxxxxxxx.dkr.ecr.ap-northeast-1.amazonaws.com/nginx-test:1
```

## ECSの設定

作業の流れとしては

1. タスク定義作成
2. クラスター作成
3. ALB作成
4. サービス作成

となります。

### タスク定義

ECSのタスク定義を開きます。

<img width="1680" alt="Screen Shot 2019-11-28 at 15.51.30.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/31268/1333b85f-30b6-f99d-204d-00eaf93c903d.png">

新しいタスク定義の作成をクリックし、起動タイプをFargateにします。

<img width="1224" alt="Screen Shot 2019-11-28 at 15.51.46.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/31268/debc4708-5874-2686-d99b-9fdcbb858dfa.png">

#### タスク定義とコンテナの設定

タスク定義名を設定します。

<img width="889" alt="Screen Shot 2019-12-06 at 17.53.21.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/31268/55955dc2-2b2b-1d9c-6cd9-cba8fa54d26c.png">

#### タスクの実行ロール IAMロール

タスク実行ロールは初めてだと自動的に作成されます。

<img width="873" alt="Screen Shot 2019-12-04 at 15.25.24.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/31268/0def6f66-20e8-9bb2-6b79-ecd2101f3f55.png">

#### タスクサイズ

タスクサイズですが、特定の組み合わせでしか設定できません。組み合わせについてはこちらにあります。
https://docs.aws.amazon.com/ja_jp/AmazonECS/latest/developerguide/task-cpu-memory-error.html
今回はミニマムのメモリ 0.5GB / CPU 0.25 vCPU で設定します。

<img width="891" alt="Screen Shot 2019-12-06 at 17.54.51.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/31268/f413f391-de9b-45cd-1067-ce1308cd638f.png">

#### コンテナの定義

コンテナの設定をします。

コンテナの追加をクリックして、コンテナのリポジトリやタグを設定します。

<img width="881" alt="Screen Shot 2019-12-06 at 17.55.42.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/31268/8fbf9904-ae71-d724-eacd-84c09da55d9c.png">

#### コンテナの追加

イメージは先程pushしたECRのリポジトリとタグを記載します。

ポートマッピング部分にはリッスンさせるportを設定します。

![Screen Shot 2019-11-28 at 15.57.22.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/31268/78b831e6-79a4-6487-d3b9-2fc707e0182e.png)

その他はそのままで作成します。

<img width="933" alt="Screen Shot 2019-12-06 at 17.58.04.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/31268/889f98df-27cb-7c57-5ebd-1205fe83dc25.png">

### クラスター

クラスターの作成をクリックします。

<img width="1680" alt="Screen Shot 2019-11-28 at 16.44.20.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/31268/94859bbc-b97d-7dae-cea9-440fc0e641c9.png">

#### クラスターテンプレートの選択

Fargateの場合はネットワーキングのみを選択します。

<img width="1176" alt="Screen Shot 2019-11-28 at 16.44.31.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/31268/e33d6f53-c1eb-132e-63f9-4085f978a0a8.png">

#### クラスターの設定

クラスター名をいれて完了です。

<img width="1182" alt="Screen Shot 2019-11-28 at 16.46.29.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/31268/4076ab3e-8bc7-b5c2-ad4a-e92913f4d888.png">

### ALB作成

ロードバランサーの作成をクリックします。

<img width="1680" alt="Screen Shot 2019-11-28 at 16.48.36.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/31268/4c25b6ea-8ae0-3216-bcf7-ec0684623a26.png">

#### ロードバランサーの種類の選択

種類からALBを選びます。

<img width="1680" alt="Screen Shot 2019-11-28 at 16.48.43.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/31268/3deda5e3-35b9-8102-e160-dbb52f9bea77.png">

#### ロードバランサーの設定

ロードバランサーの設定です。

リスナーは一旦80だけにします。

設置するアベイラビリティーゾーンを選択します(今回はデフォルトのVPCを使用します)。

<img width="1680" alt="Screen Shot 2019-11-28 at 16.59.11.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/31268/263dca95-c59f-ff0a-50f3-10ac818efb14.png">

#### セキュリティグループの設定

セキュリティグループを設定します。

80に対して0.0.0.0からアクセスできるような設定のものにします。

<img width="1673" alt="Screen Shot 2019-12-06 at 19.21.27.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/31268/e91e8de1-1cec-f0b9-3a90-d84e5c53be16.png">

#### ルーティングの設定

ルーティングの設定です。

ターゲットグループは新しいターゲットグループに、ターゲットの種類をIPにしてポートを80とします。

<img width="1664" alt="Screen Shot 2019-12-06 at 18.10.47.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/31268/a2dde63c-9ed5-2599-6759-bc52ee31a7ca.png">

#### ターゲットの登録

ターゲットの登録はここでは行わないのでそのまま確認に進みます（登録はECSで行います）。

<img width="1680" alt="Screen Shot 2019-11-28 at 17.03.53.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/31268/61b9c676-0eb9-dbc1-4818-5b0b07cea9ad.png">

確認し、作成します。

### サービスの作成

ECSの画面からサービスの作成をクリックします。

<img width="1432" alt="Screen Shot 2019-11-28 at 16.47.00.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/31268/03d76273-6e13-a21b-638c-b5f6584a8152.png">

#### サービスの設定

サービスの設定でタスク定義を先程作成したものにします。

起動タイプはFargate、タスクの数がコンテナの数になります。

<img width="888" alt="Screen Shot 2019-12-06 at 14.26.05.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/31268/42df54c5-c76c-b521-35a6-31ced6c3c4e7.png">

デプロイメントはローリングアップデートにします。

そして次のステップに進みます。

<img width="903" alt="Screen Shot 2019-12-06 at 14.28.56.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/31268/ae4f1c95-5d5e-9b4c-5eee-f86c8eb7dfa3.png">

#### VPCとセキュリティグループ

ネットワークの設定です。
　
サブネットには設置するサブネットを設定します(今回はデフォルトのVPC使います)。

セキュリティグループは新規作成されるものをそのまま使用します。

<img width="897" alt="Screen Shot 2019-12-06 at 14.30.44.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/31268/850e2b61-f23b-88fb-bb2f-1e6c68c8e7fd.png">

#### Load balancing

ヘルスチェックの猶予期間を飛ばして、Load balancingの項目に進みます。

ロードバランサーの種類をALBにしてロードバランサー名のボックスから先程作成したALBを選択します。

<img width="905" alt="Screen Shot 2019-12-06 at 14.33.28.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/31268/68b5b465-4be8-20e5-5ff0-59f73be9ba1d.png">

#### ロードバランス用のコンテナ

ロードバランス用のコンテナでロードバランサーへ追加ボタンをクリックします。

<img width="889" alt="Screen Shot 2019-12-06 at 14.34.39.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/31268/a87a2565-4aa8-1596-e555-c574e4b4148a.png">

ターゲットグループ名に先程作成したターゲットグループを指定します。

<img width="907" alt="Screen Shot 2019-12-06 at 14.38.33.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/31268/75a71d2d-b160-9144-1dc8-2edb190d8dbd.png">

サービス検出はそのままで問題ありません。

オートスケーリングの設定は今回なしにします。

<img width="1136" alt="Screen Shot 2019-11-28 at 18.25.09.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/31268/73d12535-ff83-ebc0-f1d8-52499568619f.png">

しばらく待つとタスクにコンテナが作成されます。

<img width="1420" alt="Screen Shot 2019-12-06 at 14.52.24.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/31268/c0d6416f-7d4c-d1f8-41d2-406491c2b549.png">

ALBのDNSにアクセスすると、index.htmlの内容が表示されます。

<img width="1065" alt="Screen Shot 2019-12-06 at 17.43.42.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/31268/53d119dd-fc25-e3eb-b5a8-41d2f031762c.png">

## コンテナの更新

コンテナの更新方法ですが

1. タスク定義の更新(新しいリビジョンの作成)
2. サービスを更新(タスク定義のリビジョンを上げて更新)

となります。

### docker更新

まずは、index.htmlの内容を書き換えます。

```index.html
<!DOCTYPE html>
<html lang="ja">
<head>
  <meta charset="UTF-8">
  <title>Title</title>
</head>
<body>
  <h1>Hello</h1>
</body>
</html> 
```

ビルドして、ECRにpushします。

```sh
docker build -t nginx-test .
docker tag nginx-test:latest xxxxxxxx.dkr.ecr.ap-northeast-1.amazonaws.com/nginx-test:2
docker push xxxxxxxx.dkr.ecr.ap-northeast-1.amazonaws.com/nginx-test:2
```

### タスク定義の更新

タスク定義の一覧からnginx-test-taskを選択し、新しいリビジョンを作成をクリックします。

![Screen Shot 2019-12-06 at 18.31.46.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/31268/512fa6fe-d818-34d2-a7fc-89e423f58d37.png)

コンテナの定義から設定してあるコンテナを選択し、更新画面にいきます。

#### コンテナの編集

イメージのタグを1から2に変更し、更新をクリックします。

![Screen Shot 2019-12-06 at 18.34.06.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/31268/2496a367-fa29-e4a0-4ac4-ad6685517797.png)

作成すると、タスク定義の新しいリビジョンが作成されます。

<img width="1424" alt="Screen Shot 2019-12-06 at 18.36.06.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/31268/e39c48e8-3e66-6683-0095-b1af94f8c3c4.png">

クラスターのサービス一覧からnginx-test-serviceを選択し、更新ボタンをクリックします。

<img width="1415" alt="Screen Shot 2019-12-06 at 18.38.05.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/31268/8ec9f40b-bbb5-30d7-4179-7fd3222f6b4a.png">

リビジョンを1から2に変更してサービスを更新します。

<img width="886" alt="Screen Shot 2019-12-06 at 18.38.55.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/31268/74d1a7f4-843f-48a9-b3cb-d2dc7f3dca2a.png">

すると、リビジョン2のタスクが作成されていきます。

<img width="1429" alt="Screen Shot 2019-12-06 at 18.40.06.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/31268/54e4a19a-32a1-68a0-473b-eb1fb51f91ab.png">

RUNNINGになるとALBからアクセス可能になります。

<img width="1428" alt="Screen Shot 2019-12-06 at 18.40.53.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/31268/d1c02789-6e01-bb75-c7f2-4883effac3b1.png">

ALBにアクセスしてみると、index.htmlが書き換わって表示されました。

<img width="1064" alt="Screen Shot 2019-12-06 at 18.31.02.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/31268/f40cd5f9-2a9e-a267-8b08-27676020488e.png">

リビジョン:1のタスクたちはしばらく時間が立つと自動で停止されます。

## おわりに

以上でECSのFargateの基本的な使い方の説明は終わりです。

ECS固有の名称が多く初めてだと分かりづらいかと思いますが一度流れをつかめば理解しやすいと思います。

実際の運用時はコンテナの配置をprivateなVPCにしたりデプロイメントをCodePipelineつかったりAuto Scalingを有効にしたりとかでしょうか。