ローカルで使用したdocker-compose.ymlを使ってECS上でコンテナを起動する

AWSのマネージドなコンテナサービスEC2 Container Service、略してECSのTask definitionを操作していて思うのが、これって**Docker Composeじゃーーん！**です。
各コンテナに必要な定義を別の様式で記述しているわけです。

ECSでもdocker-compose.yml使えたらな〜、と思ったらありました。

> Using the Amazon ECS Command Line Interface
http://docs.aws.amazon.com/ja_jp/AmazonECS/latest/developerguide/ECS_CLI.html


ECSをコマンドラインから使うものではあるのですが、おまけ（？）として、コンテナをデプロイするのにdocker-compose.ymlが使えます。操作があいまいになりがちなGUIを使わなくていい上に、Composeのymlまで使えてしまうという。ステキ。
とりあえずノウハウが豊富なWordPressを題材にやってみます。
なお、**2016年9月26日現在、ecs-cliのWindows版は提供されておらず、Mac版とLinux版だけ**の模様。
Windowsな方、すみません。

なお今回の記事にはクラスメソッドさんの記事を超参考にさせて頂きました。

>  http://dev.classmethod.jp/cloud/aws/using-ecs-cl/


# WordPress用 docker-compose.ymlを作成する

まずローカルで動かそう、ということでymlを作成します。

```docker-compose.yml
wordpress:
  image: wordpress
  mem_limit: 268435456
  ports:
    - "80:80"
  links:
    - mysql

mysql:
  image: mysql
  mem_limit: 268435456
  environment:
    MYSQL_ROOT_PASSWORD: password

```

mem_limitでコンテナのメモリを制限しています。これは本来いらない設定なのですが、後ほどAWS上のt2-microで動作させようと目論んでおり、その際に必要となります。


# WordPressをローカルで起動する

では早速起動。

```sh
$ docker-compose up -d
Creating tmp_mysql_1
Creating tmp_wordpress_1

```

WordPressのwelcomeが表示されれば成功です。
<img width="320" alt="Screen Shot 2016-09-26 at 13.42.49.png" src="https://qiita-image-store.s3.amazonaws.com/0/74328/fd23e57e-43e9-068f-e5a0-b31c2161bb6d.png">




確認が済んだので停止してお掃除します。

```sh
$ docker-compose stop
Stopping tmp_wordpress_1 ... done
Stopping tmp_mysql_1 ... done

$ docker-compose rm -f
Going to remove tmp_wordpress_1, tmp_mysql_1
Removing tmp_wordpress_1 ... done
Removing tmp_mysql_1 ... done
```

# ECS-CLIをインストールする

ではECSにコンテナをデプロイするための準備としてECS-CLIをダウンロード、インストールします。


## brewでECS-CLIをインストールする
ちなみにMacの場合はbrewでインストールできます。

```sh
brew install amazon-ecs-cli
```

# ECS-CLIを設定する

ecs-cliが使用するAWSの情報を設定します。
リージョン、アクセスキー、シークレットキーが必要になりますので事前に準備してください。

```sh
ecs-cli configure --region ap-northeast-1 --access-key XXXXXXXX --secret-key XXXXXXXX --cluster ecs-cli-test
```

--clusterでクラスタ名を指定しています。これはてきとうで。

# ECSクラスタを起動する

では、クラスタを起動します。テストなのでケチってt2.microインスタンスX2です。

```sh
ecs-cli up --keypair KEY_NAME --capability-iam --size 2 --instance-type t2.micro
```

KEY_NAMEにはインスタンスアクセス用の鍵名を指定します。

この時点でAWSのコンソールにアクセスすると、クラスタが起動していることが確認できます。
なお、クラスタの作成には結構時間がかかります。約5分。お茶でも飲みながら待ちましょう。

```sh
INFO[0000] Created cluster                               cluster=ecs-cli-test
INFO[0001] Waiting for your cluster resources to be created 
INFO[0001] Cloudformation stack status                   stackStatus=CREATE_IN_PROGRESS
INFO[0061] Cloudformation stack status                   stackStatus=CREATE_IN_PROGRESS
INFO[0121] Cloudformation stack status                   stackStatus=CREATE_IN_PROGRESS
INFO[0182] Cloudformation stack status                   stackStatus=CREATE_IN_PROGRESS
INFO[0242] Cloudformation stack status                   stackStatus=CREATE_IN_PROGRESS
```

# ECS上でコンテナを起動する

ではいよいよコンテナを起動します。使用するのはローカルで使ったymlそのまんまです。

```sh
ecs-cli compose -f docker-compose.yml up
```

うまくいけば、コンテナがデプロイされます。 AWSのコンソールでタスクが走っているのがわかります。

<img width="320" alt="tasks.png" src="https://qiita-image-store.s3.amazonaws.com/0/74328/640265e4-c636-ed20-141f-4ceee25e9375.png">


コンテナの起動状況を確認

```sh
$ ecs-cli ps
Name                                            State    Ports                    TaskDefinition
9070ad27-7798-4018-9389-42842eb5ee7d/wordpress  RUNNING  52.xx.xx.xx:80->80/tcp  ecscompose-tmp:3
9070ad27-7798-4018-9389-42842eb5ee7d/mysql      RUNNING                           ecscompose-tmp:3
```


表示されたIPにアクセスすればWordPressが表示されます。
<img width="320" alt="fd23e57e-43e9-068f-e5a0-b31c2161bb6d.png" src="https://qiita-image-store.s3.amazonaws.com/0/74328/8334193a-6edb-6ed6-0ace-d4d5f40b0619.png">



ローカルで動作させたコンテナがそのまんまAWSでも動作する。しかもこんなに簡単に。**すごい！**


# ECS上でコンテナをスケールさせる

せっかくEC2を2つ使っているのでスケールさせてみます。

```sh
ecs-cli compose -f docker-compose.yml scale 2
```

かくにん。

```sh
$ ecs-cli ps
Name                                            State    Ports                     TaskDefinition
9070ad27-7798-4018-9389-42842eb5ee7d/wordpress  RUNNING  52.xx.xx.xxx:80->80/tcp   ecscompose-tmp:3
9070ad27-7798-4018-9389-42842eb5ee7d/mysql      RUNNING                            ecscompose-tmp:3
caad2e0b-6ad6-48fc-a9b0-2d2a23cdea13/mysql      RUNNING                            ecscompose-tmp:3
caad2e0b-6ad6-48fc-a9b0-2d2a23cdea13/wordpress  RUNNING  52.xx.xxx.xxx:80->80/tcp  ecscompose-tmp:3
```

無事増えてます！

なお今回はmysqlごとまとめてタスクにしているので、スケールしたコンテナ毎にストレージがついていることになります。そのため、片方のタスクで操作しても、もう一方のタスクには反映されないという悲しいことになっております。実運用ではmysqlはRDSを使って、アプリケーション部分のみコンテナにするのが常套手段と思われます。



# ECSのサービスを定義する

最後にサービスを定義します。サービスを定義することにより、オートスケールやコンテナがコケた場合の再起動が可能になります。詳しい設定はただいま調査中のため、とりあえずサービスを定義するところまでです。


## まずコンテナを落とす

```sh
$ ecs-cli compose -f ./docker-compose.yml down
```

## サービスとして起動する

```sh
$ ecs-cli compose -f ./docker-compose.yml service up
```


<img width="320" alt="service.png" src="https://qiita-image-store.s3.amazonaws.com/0/74328/9cacac44-104b-d859-1795-3c71236c63e7.png">

無事サービスが上がってますね。



# ECSクラスタを削除する
では最後にクラスタを削除します。まるっと綺麗に消えちゃうので本番運用している場合には注意が必要です。

```sh
ecs-cli compose -f ./docker-compose.yml service rm
ecs-cli down --force
```

--forceで稼働中であろうが無慈悲に削除します。気をつけましょう。



----------------

以上です。参考になれば。