Dockerイメージを AWS ECR に登録して AWS ECS の Fargate でコンテナ化してサービス提供

## ECS Fargate ことはじめ
* ECS Fargate は、Docker を簡単にサービス/タスク化できて、コンテナーの運用管理してくれるAWSサービス。<br />https://aws.amazon.com/jp/fargate/

* SSH サーバープロセスが可動しているコンテナーを ECS Fargate のタスクとして実行して、SSHサーバーを作ってみるテスト。

## 準備するもの

### Docker イメージ
* 次のページで作成したSSH サーバープロセスを実行する Docker イメージ。<br />
[SSH サーバープロセスを実行する DockerイメージをMacで作成](https://qiita.com/tonishy/items/373481114887b369aeba)

### AWS 環境
* VPC
 * Fargate タスクを VPC 内で実行するため
* パブリックサブネット
 * Fargate タスク作成時に ECR からイメージを取得(pull)するため

* ECS Fargate タスク用のセキュリティグループ
 * Fargate タスクを外部に公開するため、特定の接続元のIPアドレス制限を行うため

* AmazonEC2ContainerRegistryFullAccessポリシーをアタッチした IAM ユーザの アクセスキー ID と シークレットアクセスキー
 * ACR を aws cli で設定するため。
 * 参考：[Amazon ECR 管理ポリシー](https://docs.aws.amazon.com/AmazonECR/latest/userguide/ecr_managed_policies.html)
 * IAMユーザ

## 上記のIAMユーザの アクセスキー ID と シークレットアクセスキー を登録する
ここでは、プロファイル名を「ecr」としている。
<pre>
$ aws configure --profile ecr
AWS Access Key ID [None]: **********
AWS Secret Access Key [None]: **********
Default region name [None]: ap-northeast-1
Default output format [None]:
</pre>

## Dockerイメージを ECR にプッシュする
参考：[イメージの Amazon Elastic Container Registry へのプッシュ
](https://docs.aws.amazon.com/ja_jp/AmazonECR/latest/userguide/docker-basics.html#use-ecr)

* まず、ECR のリポジトリを作成する（ここでは、リポジトリ名を 「amazonlinux1」 としている）
<pre>
$ aws ecr create-repository --repository-name amazonlinux1 --profile ecr
{
        "repository": {
            "repositoryArn": "arn:aws:ecr:ap-northeast-1:＜AWSアカウントID＞:repository/amazonlinux1",
            "registryId": "＜AWSアカウントID＞",
            "repositoryName": "amazonlinux1",
            "repositoryUri": "＜AWSアカウントID＞.dkr.ecr.ap-northeast-1.amazonaws.com/amazonlinux1",
            "createdAt": 1549718900.0
        }
}
</pre>

* AWS ECR レジストリ用の docker login 認証コマンド文字列(12時間有効な認証トークン)を取得する
<pre>
$ aws ecr get-login --no-include-email --profile ecr
docker login -u AWS -p eyJwYXlsb2FkIjoiTjMrd〜mV4cGlyYXRpb24iOjE1NDk3NjIzNzB9 https://＜AWSアカウントID＞.dkr.ecr.ap-northeast-1.amazonaws.com
</pre>

* 上記で発行されたコマンドをそのまますべてをコピーして、ターミナルにペーストして実行する
<pre>
$ docker login -u AWS -p eyJwYXlsb2FkIjoiTjMrd〜mV4cGlyYXRpb24iOjE1NDk3NjIzNzB9 https://＜AWSアカウントID＞.dkr.ecr.ap-northeast-1.amazonaws.com
WARNING! Using --password via the CLI is insecure. Use --password-stdin.
Login Succeeded
</pre>

* Dockerイメージにタグを付ける
<pre>
$ docker tag amazonlinux1:latest ＜AWSアカウントID＞.dkr.ecr.ap-northeast-1.amazonaws.com/amazonlinux1:2018.03
</pre>

* Dockerイメージを ECR に プッシュする
<pre>
$ docker push ＜AWSアカウントID＞.dkr.ecr.ap-northeast-1.amazonaws.com/amazonlinux1:2018.03
The push refers to repository [＜AWSアカウントID＞.dkr.ecr.ap-northeast-1.amazonaws.com/amazonlinux1]
156949cd7e57: Pushed
38edbf17a030: Pushing [=================>                                 ]  34.86MB/98.7MB
9ea5ca8c9ce6: Pushed
491b055ee35f: Pushing [==================================================>]  3.072kB
4d63a84b29b2: Pushed
548bf2674377: Pushing [=======>                                           ]  7.677MB/53.98MB
c506a2bec3c4: Pushing [==================================================>]  6.144kB
397ae679fe1e: Pushing [==================================================>]  3.584kB
89d587a9952f: Waiting
113b89d1c445: Waiting
4f7da8d12b94: Waiting
eff187117026: Waiting
a9f84b76f91e: Waiting
4f40c5e0c687: Waiting
6ebef445e211: Waiting
fa3a495a6538: Waiting
</pre>

* ECR にプッシュしたイメージがあるか確認
<pre>
$ aws ecr list-images --repository-name amazonlinux1 --profile ecr
{
    "imageIds": [
        {
            "imageDigest": "sha256:77874fd8e83c2c2683038694eec95bab89ffe45710fbbbcd1c8f17c561010eec",
            "imageTag": "2018.03"
        }
      ]
}
</pre>

## ECS Fargate の作成概要
1. [タスク定義](https://docs.aws.amazon.com/ja_jp/AmazonECS/latest/developerguide/task_definitions.html
)を作成<br />
2. クラスターを作成
3. タスクを作成・実行

### タスク定義
* タスク定義とは、アプリケーションを構成する 1 つ以上 (最大 10 個) のコンテナを記述する JSON 形式のテキストファイルです。アプリケーションの設計図と考えることができます。<br />参照：[Amazon Elastic Container Service とは
](https://docs.aws.amazon.com/ja_jp/AmazonECS/latest/developerguide/Welcome.html)

* タスク定義で設定する主なもの
 * [起動タイプ](https://docs.aws.amazon.com/ja_jp/AmazonECS/latest/developerguide/launch_types.html) <br />EC2起動タイプ と Fargate 起動タイプ の２つあり、Fargate 起動タイプ を選ぶ。<br />
 * [タスクサイズ](https://docs.aws.amazon.com/ja_jp/AmazonECS/latest/developerguide/AWS_Fargate.html)<br />
 タスクメモリ (GB) と タスク CPU (vCPU) のサイズを選ぶ。
 * ECRリポジトリにあるDokcerイメージ

### クラスター
* Amazon ECS を使用してタスクを実行する場合、リソースの論理グループ化であるクラスターにタスクを配置します。クラスター内のタスクで Fargate 起動タイプを使用する場合、Amazon ECS がクラスターリソースを管理します。<br />
参照：[Amazon Elastic Container Service とは
](https://docs.aws.amazon.com/ja_jp/AmazonECS/latest/developerguide/Welcome.html)

### タスク実行
* Fargate 起動タイプを使用してタスクやサービスを実行する場合、アプリケーションをコンテナにパッケージ化し、CPU およびメモリ要件を指定して、ネットワーキングおよび IAM ポリシーを定義してから、アプリケーションを起動します。各 Fargate タスクは、独自の分離境界を持ち、基本となるカーネル、CPU リソース、メモリリソース、または Elastic Network Interface を別のタスクと共有しません。<br />
参照：[AWS Fargate での Amazon ECS
](https://docs.aws.amazon.com/ja_jp/AmazonECS/latest/developerguide/AWS_Fargate.html)

## ECS タスク定義の作成
* AWSマネジメントコンソール ⇒ Amazon ECS ⇒ タスク定義 ⇒ 新しいタスク定義の作成<br />
![image.png](https://qiita-image-store.s3.amazonaws.com/0/148868/75f7dead-abc7-aa46-5141-2dc0cf77d4b0.png)
* 起動タイプで FARGATE を選択
* タスクとコンテナの定義の設定
 * タスク定義名: 適当に入力（ここでは amazonlinux1 と入力）
 * タスクメモリ: 0.5GB (最小)
 * タスク CPU: 0.25 vCPU
 * コンテナの定義<br />
 ・コンテナ名: 適当に入力<br />
 ・イメージ: 上記で作成した ECR の Image URI<br />
 "＜AWSアカウントID＞.dkr.ecr.ap-northeast-1.amazonaws.com/amazonlinux1:2018.03"

* このとき、CloudWatch ロググループ 「/ecs/タスク定義名」が作成される。

## クラスターの作成
* AWSマネジメントコンソール ⇒ Amazon ECS ⇒ クラスター ⇒ クラスターの作成<br />
* クラスターテンプレートの選択
![image.png](https://qiita-image-store.s3.amazonaws.com/0/148868/66ab2ddb-9e08-5d89-56ef-670b19f2a979.png)

* クラスターの設定
 * クラスター名: 適当に入力（ここでは amazonlinux1 と入力）
 * VPCの作成: チェックしない


## タスクを作成・実行
* AWSマネジメントコンソール ⇒ Amazon ECS ⇒ クラスター ⇒ 作成したクラスターを選択<br />
* タスク ⇒ 新しいタスクの実行
![image.png](https://qiita-image-store.s3.amazonaws.com/0/148868/7500689b-ab8c-16bd-76a8-3c4163f0cbcf.png)
* タスクの実行の設定項目
 * 起動タイプ: FARGATE
 * タスク定義: 作成したタスク定義（ここでは amazonlinux1:1）
 * クラスター: 作成したクラスター（ここでは amazonlinux1）
 * クラスターVPC: 作成してあるVPC
 * サブネット: 作成してあるパブリックサブネット
 * セキュリティグループ: 作成してあるセキュリティグループ
 
* タスクの実行
![image.png](https://qiita-image-store.s3.amazonaws.com/0/148868/dd4b9316-897f-1546-57ec-b54f7d74e176.png)<br />↓<br />ステータスが PENDING ⇒ RUNNING になれば作成成功
![image.png](https://qiita-image-store.s3.amazonaws.com/0/148868/208abced-c8e8-a1fb-aaae-aaf7ac5c136e.png)
![image.png](https://qiita-image-store.s3.amazonaws.com/0/148868/6f4c15d5-73e1-0dd3-b42a-5014fc065755.png)

## インターネット経由で Fargate タスクに接続確認
* タスクの詳細ページに、タスクに割り当てららた Public IP が記載してあるので、接続元からのIPアドレスがセキュリティグループで許可されていれば次のような感じで
<pre>
$ ssh -i 秘密鍵 -l ec2-user ＜Public IP＞
　
[ec2-user@ip-172-31-0-231 ~]$ ← コンテナーのプロンプト
</pre>