AmazonECRとEC2を使って手元でビルドしたDockerイメージをAWS上でサクッと動かす


ECR(EC2 Container Registry)に登録したDockerイメージをEC2上でコンテナとして起動するまでの一通りの流れを書いてみた
ECSも一通り検証終わっていて、サービスではそちらを使う予定だが、基礎を振り返るという意味でのまとめ。

##Docker

ここ一ヶ月ひたすらdockerを触っているが、やはり手元の開発環境で動いたものが、別の環境でそのまま動くというのは他にないメリット。
これまでだと、開発環境でOK→STでまた一から作る→本番でも同じくみたいなことしてたけど、ホスト側にDockerエンジン入れるだけで、実際のプロセスは開発環境のものをそのまま移植出来るというところはかなり熱い。といった印象。

## やること

- [x] ECRを使う準備
- [x] ECRへのDockerイメージの登録
- [x] EC2作成
- [x] EC2上にECRからpullしたDockerコンテナを立てる

## ECRとは

正式名称 EC2 Container Registry
Amazonが提供するフルマネージドのDockerコンテナレジストリ。
Dockerイメージを管理して、ECS(EC2 Container Service)やEB(Elastic Beanstalk)に簡単にデプロイすることが出来るソリューション

## ECR使うと何がうれしい

- EC2インスタンスにIAMroleを付与するだけ、EC2側で面倒な認証をせずにdockerイメージを使える
- S3がバックエンドなので、可用性高い
- 自動的に暗号化されたり、https通信されるのでセキュリティも安心


## ECRを使う準備(ローカルマシンで実施)

[AWS Command Line Interface のインストール](http://docs.aws.amazon.com/ja_jp/cli/latest/userguide/installing.html) を参考にAWS CLIを手元のマシンにインストールしておく。

基本的には、AWS CLIで操作する。

### 1.リポジトリの作成&確認

```
$aws ecr create-repository --repository-name tst-shnagai
{
    "repository": {
        "registryId": "xxxxx",
        "repositoryName": "tst-shnagai",
        "repositoryArn": "arn:aws:ecr:ap-northeast-1:xxxxx:repository/tst-shnagai",
        "createdAt": 1496229520.0,
        "repositoryUri": "xxxx.dkr.ecr.ap-northeast-1.amazonaws.com/tst-shnagai"
    }
}

```

リポジトリは、GUIから見ると、ECSサービスの中の[リポジトリ]に出来る

![Amazon_EC2_Container_Service.png](https://qiita-image-store.s3.amazonaws.com/0/40850/8a15cac4-4246-ee43-8582-2b87582ba72c.png "Amazon_EC2_Container_Service.png")

###2.ecrにログイン

セッションは12時間なので、感覚的に翌日には切れてる感じ。

```
## これで一発

$ $(aws ecr get-login --region ap-northeast-1)
Flag --email has been deprecated, will be removed in 17.06.
Login Succeeded

## $()の式展開を使わない場合

$ aws ecr get-login --region ap-northeast-1
docker login -u AWS -p eyJwYXlsb2FkIjoicURLTkxCTFhobUJuSTRxSDRNSUFBOEprc0txSnVuTVgrdzRzNkl4NU5rRDUxM0N...
### 標準出力の結果を貼り付けてログイン
$ docker login -u AWS -p eyJwYXlsb2FkIjoicURLTkxCTFhobUJuSTRxSDRNSUFBOEprc0txSnVuTVgrdzRzNkl4NU5rRDUxM0N...
Login Succeeded
```

## ECRへのDockerイメージの登録(ローカルマシンで実施)

手元にある何かしらのDockerイメージをECRにpushする手順
手元で、Dockerイメージに対して、ECR用のタグづけを行ってから、ECRにpushする

### 1.docker tagコマンドでタグづけをする

今回は例として元々手元にある[apache_td]というdockerイメージに対して、ECRのルールに沿った名前でタグ付け(aliasつけるようなもの)する

```
## 元々のイメージ
$ docker image list |grep apache_td
apache_td                                                         latest              2c42dd3f5e5c        13 days ago         1.4GB

## タグ付けを実施
$ docker tag apache_td:latest  xxxxx.dkr.ecr.ap-northeast-1.amazonaws.com/tst-shnagai:latest

## imageIDは変わらないので、下記のような検索するとapache_tdがECRに対応したイメージとしてタグ付けされたことがわかる
$ docker image list |grep 2c42dd
xxxxx.dkr.ecr.ap-northeast-1.amazonaws.com/tst-shnagai     latest              2c42dd3f5e5c        13 days ago         1.4GB
apache_td                                                         latest              2c42dd3f5e5c        13 days ago         1.4GB
```

### 2. 1でタグづけしたDockerImageをECRにpushする

```
$ docker push xxxxx.dkr.ecr.ap-northeast-1.amazonaws.com/tst-shnagai:latest
The push refers to a repository [xxxxx.dkr.ecr.ap-northeast-1.amazonaws.com/tst-shnagai]
47d1cbb6b480: Layer already exists
...
latest: digest: sha256:14b7a5d491fa694c00f026bbc6c6cd09e0ddc63d0e586569a0de42a8ce7ec5d1 size: 2411

```

GUIで、タグ名とプッシュされた日時を確認して無事イメージがアップされていることを確認する

![Amazon_EC2_Container_Service.png](https://qiita-image-store.s3.amazonaws.com/0/40850/7c648af1-bef6-1d06-6603-f17666017786.png "Amazon_EC2_Container_Service.png")

ここまでで、ECRへのDockerイメージの登録は完了！！

## EC2インスタンスの作成

### 1.通常通りEC2インスタンスを作成する(OSはデフォルトでawscliが入っているamazon linuxだと楽)

ポイントは、IAMRoleに[AmazonEC2ContainerRegistryReadOnly]ポリシを付与しておくことのみ

![IAM_Management_Console.png](https://qiita-image-store.s3.amazonaws.com/0/40850/73712881-0196-478e-9b71-88d313ff4d46.png "IAM_Management_Console.png")

### 2. dockerのインストール

AWSの公式ドキュメントに沿ってやるだけなので、コマンドだけ羅列
[Docker のインストール](http://docs.aws.amazon.com/ja_jp/AmazonECR/latest/userguide/docker-basics.html)

ec2-userでdockerコマンドがsudoなしでうてるとこまでやっておく。

```
$ sudo yum update -y
$ sudo yum install -y docker
$ sudo service docker start
### ec2-userでsudoなしでdockerコマンドを打てるようにするため
$ sudo usermod -a -G docker ec2-user
###再ログイン
$ docker info
Containers: 0
 Running: 0
 Paused: 0
 Stopped: 0
Images: 0
Server Version: 17.03.1-ce
```

## EC2上にECRからpullしたDockerコンテナを立てる(EC2上で実施)

###1. ECRへのログイン

IAMRoleがついていない場合は、ログインで弾かれる

```
$ $(aws ecr get-login --region ap-northeast-1)
Login Succeeded
```

###2. ECRからDockerイメージをpullする

```
## ECRにアップロードしたイメージをpull
$ docker pull xxxxx.dkr.ecr.ap-northeast-1.amazonaws.com/tst-shnagai:latest
latest: Pulling from tst-shnagai
996fe98f55d8: Pull complete
...
e6b377ddca6e: Pull complete
Digest: sha256:14b7a5d491fa694c00f026bbc6c6cd09e0ddc63d0e586569a0de42a8ce7ec5d1
Status: Downloaded newer image for xxxxx.dkr.ecr.ap-northeast-1.amazonaws.com/tst-shnagai:latest

## 手元のイメージとして登録されたことを確認
$ docker image ls
REPOSITORY                                                      TAG                 IMAGE ID            CREATED             SIZE
xxxxx.dkr.ecr.ap-northeast-1.amazonaws.com/tst-shnagai   latest              2c42dd3f5e5c        13 days ago         1.4 GB
```

###3. dockerコンテナを起動する

pullしてきたイメージからコンテナを起動する

```
## ホストの8080ポートにマッピングするtestという名前のコンテナを起動する
$ docker run -d --name test -p 8080:80 xxxxx.dkr.ecr.ap-northeast-1.amazonaws.com/tst-shnagai:latest
dbbb74b6ebe95666d356250de8310c19403078f53e020069e9a6d10e479b2873

## -lオプションで最後に起動したコンテナを表示
$ docker ps -l
CONTAINER ID        IMAGE                                                                  COMMAND                  CREATED             STATUS              PORTS                  NAMES
dbbb74b6ebe9        xxxxx.dkr.ecr.ap-northeast-1.amazonaws.com/tst-shnagai:latest   "/bin/sh -c '/bin/..."   4 seconds ago       Up 4 seconds        0.0.0.0:8080->80/tcp   test

## 動作確認として、ホストの8080に対してcurlでリクエストしてみる
$ curl localhost:8080
version 1.2
```

##まとめ

オーソドックスな、AWSでECRを使ってdockerコンテナを起動する一通りの流れをやってみた。dockerを手元で触ってる人だったら、特に躓くことなくやれる内容だと思う。
ECSは、基本オペレーション(この投稿でいうEC2以降の話)を抽象化して、クラスタというEC2集合体の上で、ELB,AutoScaling等を付加して使えるサービスなので、ココら辺をちゃんと理解してやるとやらないでは進みがだいぶ違うという印象を受ける。
裏で何が行われてるのかなという道理を理解することは大事。