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


ECS クラスタを作るにあたって土台の EC2 インスタンスが必要となるわけですが、そこで使う AMI として公式では ECS-optimized AMI を推奨しています。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 を開く
  2. [AWS Service Role] の [Amazon EC2] を開き、AmazonEC2ContainerServiceforEC2Role にチェックを入れる
  3. [Create Role]
  4. 作った Role を開き、[Trusted Relationships] -> [Show policy document] が以下のようになっているのを確認。なってなかったら上書き。
{
  "Version": "2008-10-17",
  "Statement": [
    {
      "Sid": "",
      "Effect": "Allow",
      "Principal": {
        "Service": "ec2.amazonaws.com"
      },
      "Action": "sts:AssumeRole"
    }
  ]
}

CoreOS EC2 インスタンスを建てる

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

  • AMI: Running CoreOS on EC2 から自分の使うリージョンと update channel に合ったのを選んでください。
  • IAM Role: ecsInstanceRole これがないと ecs-agent が起動しません。
  • User Data: 以下のように、ecs-agent を Systemd Unit として起動させます。ECS_CLUSTER は先ほど作った or 追加させる既存の ECS クラスタ名にしてください。
#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 が追加されているかどうかを確認してください。

終わりです。

REF