CoreOS で ECS クラスタを構築する

ECS クラスタを作るにあたって土台の EC2 インスタンスが必要となるわけですが、そこで使う AMI として公式では [ECS-optimized AMI](http://docs.aws.amazon.com/AmazonECS/latest/developerguide/ecs-optimized_AMI.html) を推奨しています。ECS-optimized AMI は Amazon Linux AMI に新し目の Docker と ecs-agent、ecs-init スクリプトを同梱したやつです。初回チュートリアルでクラスタを立てる時もこの AMI が使われます。

ただ、実際のところ EC2 の中身に関しては (2016-06-15 時点)

- Linux Kernel 3.10 以上で
- Docker 1.5.0 以上で
- ecs-agent コンテナが立ってる

のであれば何でもよいのです。ECS-optimized AMI はそれを満たした推奨構成であるだけです。

というわけで、Docker 環境に特化した CoreOS を使ってみましょう。

## ECS クラスタを準備
まっさらからクラスタ建てる場合は、Management Console なり ecs-cli なりで新しくクラスタを作ってください。
もしくは、既存クラスタにノード追加の形で CoreOS インスタンスを追加することもできます。

## （ないなら）IAM Role `ecsInstanceRole` を作成
ecs-agent が ECS API にアクセスするため、その権限をインスタンスに付与してあげる必要があります。
初回チュートリアルでクラスタを立ち上げた場合は作られてると思いますが、まっさらからクラスタを構築する場合はこの Role がないので作る必要があります。

1. [IAM -> Roles -> Create New Role](https://console.aws.amazon.com/iam/home?region=ap-northeast-1#roles) を開く
2. [AWS Service Role] の [Amazon EC2] を開き、`AmazonEC2ContainerServiceforEC2Role` にチェックを入れる
3. [Create Role]
4. 作った Role を開き、[Trusted Relationships] -> [Show policy document] が以下のようになっているのを確認。なってなかったら上書き。

```json
{
  "Version": "2008-10-17",
  "Statement": [
    {
      "Sid": "",
      "Effect": "Allow",
      "Principal": {
        "Service": "ec2.amazonaws.com"
      },
      "Action": "sts:AssumeRole"
    }
  ]
}
```

## CoreOS EC2 インスタンスを建てる
最低限 ECS クラスタノードに必要な設定です。インスタンスタイプなどはお好みで設定してください。

- __AMI:__ [Running CoreOS on EC2](https://coreos.com/os/docs/latest/booting-on-ec2.html) から自分の使うリージョンと update channel に合ったのを選んでください。
- __IAM Role:__ `ecsInstanceRole` これがないと ecs-agent が起動しません。
- __User Data:__ 以下のように、ecs-agent を Systemd Unit として起動させます。`ECS_CLUSTER` は先ほど作った or 追加させる既存の ECS クラスタ名にしてください。

```yaml
#cloud-config

---
coreos:
  units:
    - name: docker-tcp.socket
      command: start
      enable: true
      content: |
        [Unit]
        Description=Docker Socket for the API

        [Socket]
        ListenStream=2375
        Service=docker.service
        BindIPv6Only=both

        [Install]
        WantedBy=sockets.target
    - name: amazon-ecs-agent.service
      command: start
      runtime: true
      content: |
        [Unit]
        Description=AWS ECS Agent
        Documentation=https://docs.aws.amazon.com/AmazonECS/latest/developerguide/
        Requires=docker.socket
        After=docker.socket

        [Service]
        Environment=ECS_CLUSTER=your-cluster-name
        Environment=ECS_LOGLEVEL=info
        Environment=ECS_VERSION=latest
        Restart=on-failure
        RestartSec=30
        RestartPreventExitStatus=5
        SyslogIdentifier=ecs-agent
        ExecStartPre=-/bin/mkdir -p /var/log/ecs /var/ecs-data /etc/ecs
        ExecStartPre=-/usr/bin/touch /etc/ecs/ecs.config
        ExecStartPre=-/usr/bin/docker kill ecs-agent
        ExecStartPre=-/usr/bin/docker rm ecs-agent
        ExecStartPre=/usr/bin/docker pull amazon/amazon-ecs-agent:${ECS_VERSION}
        ExecStart=/usr/bin/docker run --name ecs-agent \
                                    --env-file=/etc/ecs/ecs.config \
                                    --volume=/var/run/docker.sock:/var/run/docker.sock \
                                    --volume=/var/log/ecs:/log \
                                    --volume=/var/ecs-data:/data \
                                    --volume=/sys/fs/cgroup:/sys/fs/cgroup:ro \
                                    --volume=/run/docker/execdriver/native:/var/lib/docker/execdriver/native:ro \
                                    --publish=127.0.0.1:51678:51678 \
                                    --env=ECS_LOGFILE=/log/ecs-agent.log \
                                    --env=ECS_LOGLEVEL=${ECS_LOGLEVEL} \
                                    --env=ECS_DATADIR=/data \
                                    --env=ECS_CLUSTER=${ECS_CLUSTER} \
                                    amazon/amazon-ecs-agent:${ECS_VERSION}
```

この設定で直接建てるなり、Launch Configuration に書いて Auto Scaling 経由で建てるなりします。

## インスタンスがクラスタに追加されたか確認
ECS Management Console で対象のクラスタの [ECS Instances] タブを開き、Container Instance が追加されているかどうかを確認してください。

![image](https://qiita-image-store.s3.amazonaws.com/0/17508/d2ac37cd-cba1-eaa5-742c-907cdde16e0d.png)

終わりです。

## REF
- [Amazon EC2 Container Service (coreos.com)](https://coreos.com/os/docs/latest/booting-on-ecs.html)
- [Amazon ECS Container Instance IAM Role - Amazon EC2 Container Service](http://docs.aws.amazon.com/ja_jp/AmazonECS/latest/developerguide/instance_IAM_role.html)