AWS で Docker アプリをデプロイ・運用する

始まりました。[Docker Advent Calendar 2016](http://qiita.com/advent-calendar/2016/docker) 1 日目です。

メトリクス収集まとめを書くつもりでしたが、re:Invent 参加中ということもありやっぱり AWS ネタで。新サービス・機能について書きたいですが、今のところ発表がないので既存サービス内で。
（以下すべて、いちユーザとしての感想です）

# デプロイ

## パターン

AWS のマネージドを中心に CI / CD パイプラインを組むなら

* ECS
* ElasticBeanstalk
* CodeDeploy
* Docker for AWS

を用途に応じて使い分けられます。

## ECS

### 用途

自分でクラスタを管理したい / しなければならないといった特別な理由がなければ、ECS がオススメです。最近 Datadog も ECS の本番利用が増加していることを記事[^1]にしています。

### メリット

* コンピュートリソースを最大限有効に利用できる
* ALB との併用で[動的ポートマッピング](https://aws.amazon.com/jp/about-aws/whats-new/2016/08/amazon-ec2-container-service-now-integrated-with-application-load-balancer-to-support-dynamic-ports-and-path-based-routing/)が有効に
* [Service Auto Scaling](docs.aws.amazon.com/AmazonECS/latest/developerguide/service-auto-scaling.html) でスケールも AWS に任せられる
* [タスク単位で IAM ロール](https://aws.amazon.com/jp/blogs/news/help-secure-container-enabled-applications-with-iam-roles-for-ecs-tasks/)を使った適切な権限管理ができる
* [Spot fleet 上での運用](http://aws.typepad.com/sajp/2016/01/powering-your-amazon-ecs-clusters-with-spot-fleet.html)でコスト最適化も
* CloudWatch で[クラスタとしてのメトリクス](http://docs.aws.amazon.com/ja_jp/AmazonECS/latest/developerguide/cloudwatch-metrics.html)も扱える

### 構成例

<img width="500" alt="ecs-arch.png" src="https://qiita-image-store.s3.amazonaws.com/0/66457/6e6ac5d4-9242-9733-f006-8730343c7af7.png">

### 継続的デプロイ例

https://github.com/supinf/containers-on-aws/blob/master/circle.yml#L58

<img width="500" alt="deploy-with-ecs" src="https://qiita-image-store.s3.amazonaws.com/0/66457/ea36346e-d4b8-ca06-fd72-76cd05118e50.png">

## ElasticBeanstalk（EB）

### 用途

もともと EB を使っていて慣れている、または EB のデプロイ戦略を利用したいとき。
コンテナだけでなく RDS / ELB / AutoScaling などのプロビジョニング（初期設定など）も AWS に任せてしまいたいとき。

### メリット

* EB の[豊富なデプロイ戦略](http://docs.aws.amazon.com/ja_jp/elasticbeanstalk/latest/dg/using-features.deploy-existing-version.html)や[環境クローン](http://docs.aws.amazon.com/ja_jp/elasticbeanstalk/latest/dg/using-features.managing.clone.html)を利用できる
* ELB や AutoScaling に不慣れでもコンテナだけに集中できる
* [.ebextensions](http://docs.aws.amazon.com/ja_jp/elasticbeanstalk/latest/dg/ebextensions.html) で環境を柔軟にカスタマイズできる
* Kubernetes の [Daemon Set](shttp://kubernetes.io/docs/admin/daemons/) 的に動くので 1 コンテナ 1 ホストなどには有用

### 継続的デプロイ例

<img width="500" alt="deploy-with-eb.png" src="https://qiita-image-store.s3.amazonaws.com/0/66457/be9c857d-7bec-8579-619d-876b8c87b8ff.png">

## CodeDeploy

### 用途

[Docker Compose](http://docs.docker.jp/compose/production.html) を使いたい、[Swarm モード](http://docs.docker.jp/engine/swarm/index.html)で動かしたい、[nvidia-docker](https://github.com/NVIDIA/nvidia-docker) を挟みたいなど、AWS 外のフレームワークでコンテナを起動したいとき。
コンテナの起動前後で特定のスクリプトを流したり、特定の挙動をもってデプロイの成否を判定したいとき。

### メリット

* docker-compose や Swarm モードなアプリがデプロイできる
* Swarm モードなら 1 台でも無停止アップデートが簡単
* Docker レジストリが必須ではない
    * DockerHub や ECR が使えなくても大丈夫
    * S3 を経由した [docker save](http://docs.docker.jp/engine/reference/commandline/save.html) / [load](http://docs.docker.jp/engine/reference/commandline/load.html)  
   （暗号化やライフサイクルポリシーなど各種メリットを享受できる）
    * Dockerfile でその場でビルドでももちろん OK
* デプロイ前後に[フックスクリプト](http://docs.aws.amazon.com/ja_jp/codedeploy/latest/userguide/app-spec-ref-hooks.html)が使える

### 継続的デプロイ例

https://github.com/supinf/containers-on-aws/blob/master/circle.yml#L43

（上のスクリプトと違って、S3 を経由する絵ですが）

<img width="500" alt="deploy-with-cd.png" src="https://qiita-image-store.s3.amazonaws.com/0/66457/48d856c0-706c-841a-ac90-a22db24a2f97.png">

## Docker for AWS

[パブリックベータ](https://beta.docker.com/docs/aws/)になりましたね！
ちょっと古いバージョンですが中身は[こんな感じ](http://qiita.com/pottava/items/06aa817e581debd150bd)。

### 用途

Swarm モードを、Docker 社の管理するフレームワークで稼働させたいとき。IAM や ELB など AWS の便利なマネージドサービスは使いつつも、クラスタ管理は自前で行いたいとき。

### メリット

* Docker の新しい機能群が使える可能性が常に最も高い
* 例えば [v1.13 リリース予定](http://files.meetup.com/14049142/KenCochrane-DockerMaine-Nov92016.pdf)の prune 機能がすでに有効化済み
* インターナルサービスディスカバリに Docker の [Ingress Load Balancing](http://docs.docker.jp/engine/swarm/key-concepts.html#swarm-concept-load-balanicng) が使える
* AutoScaling や ELB、DynamoDB、SQS による運用負荷の軽減
* IAM やネットワークがセキュア側にプリセットされた安心感


# Docker イメージの共有

## ECR 

### 用途

IAM やポリシーにより適切に権限管理することのできる Docker レジストリの管理を AWS を任せたいとき。

### メリット

* [コマンド 1 行](http://docs.aws.amazon.com/cli/latest/reference/ecr/create-repository.html)で簡単にリポジトリを作れる / 削除できる
* AWS に管理を任せることで、可用性が高くスケーラブルなインフラに
* IAM や独自のポリシー機能でアクセスを厳密に制御できる
* オンプレミスなど AWS の外からも使うことができる
* 同リージョン内の ECR と EC2 間データ[転送量は無料](https://aws.amazon.com/jp/ecr/pricing/)

### Tips

* [[公式] Automating ECR Authentication on Marathon with the Amazon ECR Credential Helper](https://aws.amazon.com/blogs/apn/automating-ecr-authentication-on-marathon-with-the-amazon-ecr-credential-helper/)
* [Amazon ECR にログインなしで接続する](http://qiita.com/pottava/items/7f3a2938a2d53b86618e)
* [特定 IAM ユーザからのみのアクセスを許可](http://qiita.com/pottava/items/2a5a2ba0d4f186c6b78f)


## 自前管理 Docker レジストリ

### 用途

[公式に公開されているレジストリ](https://docs.docker.com/registry/)を自らの手で運用したいとき。アクセス管理を IAM 以外で行ったり、データの冗長化などを独自の方法で行いたいとき。

### メリット

* S3 や CloudFront を使うことで各サービスのメリットが得られる
* 独自のホスト名を割り当てることができる
* Docker のより新しい機能を早めに使うことができる（かもしれない）

　

以上です。

明日は @netmarkjp さんの「Dockerドキュメント日本語化に参加しよう！」です :)

　

[^1]: [ECS 採用における 3 つのトレンド](https://www.datadoghq.com/blog/3-clear-trends-in-ecs-adoption/)