ECS+ECR環境でDockerコンテナをデプロイする


#前置き

Dockerで開発環境が動作するようになったはいいけれど、これだけではまだ道半ば。
開発で使用したDockerイメージがそのまんま本番環境にデプロイされるところまでいってなんぼでしょう。

個人的にはGCPのGKE使いたいんですが、まだ日本リージョンオープンしていないし、CloudSQLがVPNサポートしていないし、ということでAWS ECSでいきます。正直むずかったです。。

最終的にはGihubにpushしたコードからDocker imageを生成してTravisでECSにデプロイまで持っていきたいですが、まずはECRに手動でpushしたDocker imageを使ってECS上でコンテナを動作させます。


#ECRのセットアップ

EC2 Container Registry。Docker imageを登録するAWS謹製のレジストリサービスです。ECS使うならほぼセットと思われます。
コンテナを登録するためのレジストリをセットアップします。
1Gまでは無料ですので、イメージは死ぬ気で1G以内に収めることをオススメします。


<img width="300" alt="ecr.png" src="https://qiita-image-store.s3.amazonaws.com/0/74328/fa9dbcfa-0597-71ce-9a4f-f8e387bd343c.png">


- AWSのサービスからECSを選択 
- Repositoriesを選択 
- Create repositoryをクリック
- Repository nameにてきとうな名を入力(ここではhogehoge)
- Next Step をクリック
- 表示されたページの手順通りに操作して、あらかじめ用意しておいたコンテナをレジストリに登録

![ecr_push.png](https://qiita-image-store.s3.amazonaws.com/0/74328/9b9adcb7-f5d9-e18b-cb93-854e40ad438d.png)





#Task Definitionの作成

使うECR上のコンテナイメージとコンテナの詳細を定義し紐付けます。Composerからコンテナひとつだけ抜き出して定義するイメージでしょうか。オーケストレーションツールはComposerしか使ったことないのですが、DevicesとかCAP_ADDとかなくて困りました。最終的にはPrivileged=true（rootに近い権限で動作させる)で切り抜けましたが。。セキュリティ上これでいいのかちょっと不安。


<img width="300" alt="task_def.png" src="https://qiita-image-store.s3.amazonaws.com/0/74328/a2648cde-2251-26dc-f44c-353d877e8d6d.png">



- Task Definitionsを選択
- Create new Task Definitionをクリック
- Task Definition nameにてきとうな名を入力(ここではhogehoge-web)
- Add containerをクリック


<img width="300" alt="add_container.png" src="https://qiita-image-store.s3.amazonaws.com/0/74328/48cac299-d1fc-61d7-228a-23dd479695fa.png">



- Container nameにてきとうな名を入力(ここではhogehoge-web-container)
- ImageにECRに作成したリポジトリのURLを入力
- Memory Limitsにてきとうな値を入力(ここでは200)
- Port mappingsに80:80と入力
- CPU unitsにてきとうな値を入力(ここでは10)
- Addをクリック(コンテナがTask Definitionに追加される)
- Createをクリック(Task Definitionが生成される)


#Clusterの作成

コンテナを動作させるClusterを作成します。この枠の中で全てが動作します。



<img width="300" alt="create_cluster.png" src="https://qiita-image-store.s3.amazonaws.com/0/74328/784dee67-1738-9d6d-6ef9-3fa250fd2a92.png">


- Clustersを選択
- Create Clusterをクリック
- Cluster nameにてきとうな名を入力(ここではhogehoge-cluster)
- 作成したClusterを選択


#Serviceの作成

複数のTask Definitionと、Dockerが動作するEC2インスタンスを紐付けるサービスを作成します。ホストn個上で、コンテナn個動作させる役割?？すごくわかりづらい。。1コンテナ内に複数サービス定義できるので、ホストとなるEC2を分けたい時には別サービスを作成するイメージでしょうか。まずはautoscaleは使わない方向で作成します。



<img width="300" alt="create_service.png" src="https://qiita-image-store.s3.amazonaws.com/0/74328/8e7bb771-267b-0cde-284c-365dfc859d3b.png">


- Serviceを作成するためにServicesタブのCreateをクリック
- Service nameにてきとうな名を入力(ここではhogehoge-container)
- Number of tasksにてきとうな値を入力(ここでは2)
- ELBを作成するためにConfigure ELBをクリック
- あらかじめ作成しておいたELBを選択
- Create Serviceをクリック


![create_service2.png](https://qiita-image-store.s3.amazonaws.com/0/74328/f0fbb0fa-0432-c525-afb1-c88aeaa257cb.png)



#EC2インスタンスの作成

いわずもがなのEC2。ECSで動作させるのでそれ用のイメージを使うと面倒がなさそうです。


<img width="300" alt="Screen Shot 2016-09-09 at 11.52.09.png" src="https://qiita-image-store.s3.amazonaws.com/0/74328/0277b805-5ef8-dcec-d2dc-fde67d436071.png">


- AWSのサービスからEC2を選択
- インスタンスの作成をクリック
- AMIにAmazon ECS-Optimized Amazon Linux AMIを選択


<img width="300" alt="Screen Shot 2016-09-09 at 11.52.31.png" src="https://qiita-image-store.s3.amazonaws.com/0/74328/5cdf401e-ae69-cbdf-6748-498d8f9b6aab.png">


- IAMロールにecsInstanceRoleを選択
- ユーザーデータに以下を入力

```sh
#!/bin/bash
echo ECS_CLUSTER=hogehoge-cluster >> /etc/ecs/ecs.config
```

- セキュリティグループを**正しく**設定


#動作確認

うまくいっていれば、コンテナが起動して、ELBに割り振ったURLにアクセスすればページが表示される...はず！



#参考にさせていただいた記事

> CircleCI+ECS+ECR環境でDockerコンテナのCD(継続的デプロイ)環境を構築する
http://dev.classmethod.jp/cloud/circleci-ecr-ecs-1/