Docker for AWS 試してみた その1

[DockerCon 2016 で発表](http://www.publickey1.jp/blog/16/docker_for_aws_docker_for_azure.html)され、現在 プライベート β 公開中の [Docker for AWS](https://beta.docker.com/docs/aws/)。
Docker 社にブログ書くよアピールをしたら招待されたのでこれ書いてます。

# 目次

* Docker for AWS 概要
* CloudFormation で起動するリソース・構成
* EC2 インスタンスとそのプロファイル（IAM ロール）
* 続編について

# Docker for AWS

## とは

Docker 社の提供する
**AWS のマネージドサービスとうまく統合された、いい感じの Swarm クラスタ**を
**「CloudFormation テンプレート + 専用 AMI」**で構成するツール群。
AWS への Docker クラスタデプロイツール。
 
ただの Swarm クラスタではなく、AWS ならこう構成するといいよね！なクラスタが起動します。

## 制約・前提

2016/07/15 現在プライベート β で、招待制試験中[^1]。
管理用 KVS に DynamoDB、フロントのロードバランサに ELB を使うなどするため
相応の権限をもつ IAM ユーザか AWS ルートアカウントで CloudFormation を実行。
Docker v1.12 の [Swarm モード](http://docs.docker.jp/engine/swarm/index.html) 前提のクラスタを生成します。
東京リージョンにも対応済。


# CloudFormation

β プログラムに招待されると、以下 2 つが Docker 社から共有されます。

* CloudFormation テンプレート
* [アカウント指定で共有](http://docs.aws.amazon.com/ja_jp/AWSEC2/latest/UserGuide/sharingamis-explicit.html)された専用の AMI

## 起動するリソース

以下の作成権限と CloudFormation を使う権限のあるユーザでスタック生成を実行。

* VPC * 1、Public サブネット * 2、SecurityGroup * 5
* AutoScaling グループ * 2 + EC2 インスタンス
* ELB * 2
* IAM ポリシー * 6、ロール * 1、インスタンスプロファイル * 1
* DynamoDB テーブル * 1
* SQS キュー * 2

## 構成

![Docker-for-AWS-_swarm_cluster_.png](https://qiita-image-store.s3.amazonaws.com/0/66457/d06530be-3b12-81c2-e419-37c400754ca5.png)

バージョン `Docker for AWS Beta 2 (docker 1.12.0-rc4)` 時点。

manager と worker、それぞれの AutoScaling (AS) グループが作られ
Docker 社から共有された AMI ベースで EC2 インスタンスが起動します。
また AS のライフサイクルフックで EC2 破棄時に SQS キューと連携、
各インスタンスの管理用コンテナがそれを受け取ってお掃除など遂行。

DynamoDB の用途ははっきりとはわかりませんが
テーブルの中をのぞくと、リーダーノードを保持している模様。


# EC2 インスタンス

Docker ホストである EC2 インスタンスの状況について。

## Docker コンテナ

UserData で起動する各ノードの docker コンテナはこんな感じです。

| | node | restart | DynamoDB | SQS | 特徴 |
|:--|:--:|:--:|:--:|:--:|:--:|
| [docker4x/init-aws](https://hub.docker.com/r/docker4x/init-aws/tags/) | manager/worker | no | 参照 | - | 役目を終えると exit |
| [docker4x/guide-aws](https://hub.docker.com/r/docker4x/guide-aws/tags/) | manager/worker | always | 参照 | 参照 | ？ |
| [docker4x/shell-aws](https://hub.docker.com/r/docker4x/shell-aws/tags/) | manager | always | - | - | TCP:22 を公開、sshd ぽい |
| [docker4x/controller](https://hub.docker.com/r/docker4x/controller/tags/) | manager | always | - | - | swarm 操作系？ |

というわけで、SSH で繋いだ先で `cat /etc/os-release` するとこうなります（笑

```sh:cat-os-release
$ cat /etc/os-release

NAME="Alpine Linux"
ID=alpine
VERSION_ID=3.3.3
PRETTY_NAME="Alpine Linux v3.3"
HOME_URL="http://alpinelinux.org"
BUG_REPORT_URL="http://bugs.alpinelinux.org"
```

## インスタンスプロファイル

[ECS の新しい機能](https://aws.amazon.com/jp/blogs/news/help-secure-container-enabled-applications-with-iam-roles-for-ecs-tasks/) が使えないので、最大公約数的な IAM ポリシーが割り当てられます。

* EC2: DescribeInstances, DescribeVpcAttribute
* AS: autoscaling:*
* ELB: elasticloadbalancing:*
* DynamoDB: リソース制限した上で PutItem, GetItem, UpdateItem, Query
* SQS: リソース制限した上で sqs:*

当然ながら、アプリケーション側でもしその他 AWS サービスを使うなら
このプロファイルに追加で権限を渡していくことになります。

ちなみに  Docker レジストリとして ECR を使うなら [これ](https://github.com/awslabs/amazon-ecr-credential-helper) の併用で完璧です。

## ELB

2 つの ELB が起動します。

| | Listen ポート | ヘルスチェック | SecurityGroup |
|:--|:--:|:--:|:--:|
| サービス用 | Swarm サービスに応じ動的に変化 | TCP:2375 (Docker Remote API) | 0 ~ 65535 (0.0.0.0/0) |
| SSH用 | TCP:22 | TCP:22 | 22 (0.0.0.0/0) |

ところで CloudFormation の Outputs には ELB のエンドポイントを利用した
SSH の接続コマンドが表示されますが、そのままでは繋がりません。
スタック作成時に指定したキーペア（.pem）を -i で渡す必要があります。
あたりまえですねはい・・


# 続編

[Docker for AWS 試してみた その2](http://qiita.com/pottava/items/7115a00881e35398c2d2)


[^1]: 実際に試したい方は [ここ](https://beta.docker.com/) から申請できます。