AWS Hands-on for Beginners　Amazon Elastic Container Service 入門 コンテナイメージを作って動かしてみよう：学習メモ

## はじめに

AWSハンズオン for Beginnersシリーズとして提供されている「[AWS Hands-on for Beginners Amazon Elastic Container Service 入門　コンテナイメージを作って動かしてみよう](https://pages.awscloud.com/JAPAN-event-OE-Hands-on-for-Beginners-ECS-2022-reg-event.html)」を実施した際のメモです。
近年変化の激しいビジネス市場で結果を出していくためには、ビジネスニーズを満たすアプリケーションを迅速に開発することが必要です。
昨今コンテナ技術を使用することでこのような課題を解決することが可能となりました。
本ハンズオンでは、AWSのコンテナオーケストレーションサービスであるAmazon ECSおよびコンテナイメージを保存するサービスAmazon ECRを使用してスケーラブルなWebサービスを作成します。

## アジェンダ

1. コンテナが、どのような課題に役に立つのか
2. コンテナイメージを作成するための、Cloud9 環境を構築する
3. コンテナイメージを作成して動かす その1
4. コンテナイメージを作成して動かす その2
5. コンテナイメージを、ECR にアップロードする
6. VPC の作成
7. ECS クラスターの作成、タスク定義の作成
8. サービスの作成
9. コンテナの自動復旧、スケールアウトをやってみる
10. 本シリーズのまとめ、リソースの削除

## メモ

### 本ハンズオンのゴール

- コンテナによってどんな課題を解決できるか理解する
- コンテナオーケストレーションサービスAmazon ECSの使い所を理解し、実際に使用する
- 実施の業務で利用するシーンを考える

### ビジネス上の課題

昨今ビジネス市場は環境の変化が激しく、迅速にビジネスニーズを満たすアプリケーションのリリースが必要です。
迅速にアプリをリリースするためには、アプリケーションにフォーカスした開発、要件に沿ったインフラ管理、迅速なスケーリング、セキュリティの確保が必要となります。
これらはコンテナ技術を使用することで満たすことができます。

### 解決策としてのコンテナ技術

コンテナとは、アプリケーションのランタイム、コード、設定、依存ライブラリを1つにパッケージングしたものです。
パッケージをそのまま環境にデプロイすることで、環境差異に起因した障害などを防ぐことができ、結果として開発を加速させることができます。
また、スケーリング時も従来の仮想マシンより高速であるため、急なビジネス需要の増加に耐えることができ、機会損失を防止できます。

### コンテナを使用する際の課題とECS

コンテナは開発を加速させることができますが、課題もあります。
1つのコンテナのみ管理する場合、その管理工数はそれほどかかりません。しかし、複数のコンテナ、それも大量に管理する必要がある場合、管理作業が煩雑になる可能性があります。
これを解決する技術がコンテナオーケストレーションです。コンテナオーケストレーションは複数のコンテナのステータス（起動しているか、異常終了しているかなど）を管理したり、コンテナの負荷にしたがってコンテナの起動数を増減させる機能などを持ちます。Amazon ECSはフルマネージドなコンテナオーケストレーションサービスです。

### Docker Imageの作成からコンテナ実行までの流れ

- Dockerfileを作成し、ベースとなるイメージとミドルウェアをインストールするコマンドや解放するポートなどの設定を記述します。
- **docker buildコマンド**でDockerfileの内容を元にイメージをビルドします。
  - `docker build -t <イメージタグ名> <Dockerfileがあるパス>`
- **docker imagesコマンド**でベースとなるイメージとDockerfileで作成されたイメージが表示されることを確認します。
- **docker psコマンド**で現在実行されているコンテナプロセスを確認します。
- **docker runコマンド**で指定したイメージからコンテナを実行します。
  - `docker run -d -p 8080:80 --name h4b-local-run hello-world`
    - nameオプションにコンテナプロセス名を指定します。上記では**h4b-local-run**を指定しています。
    - コンテナの生成元であるイメージのタグ名をコマンド末尾に指定します。上記では**hello-world**を指定しています。
    - **pオプション**にコンテナが解放するポートとローカルからアクセスできるポートを指定します。上記ではローカルのポート**8080**をコンテナのポート**80**に関連付けしています。
- **docker execコマンド**で指定したコンテナに対してコマンドを実行します。
  - `docker exec -i -t h4b-local-run bash`
    - **tオプション**にイメージのタグ名を指定します。上記では**h4b-local-run**を指定しています。
    - 末尾に実行するコマンドを指定します。上記ではbashコマンドを指定しています。

### Docker ImageをAmazon ECRにプッシュするまでの流れ

- Amazon ECRコンソールからプライベートリポジトリを作成します。
- タグに作成したECRリポジトリのURLおよびタグを指定し、**docker buildコマンド**を実行します。
- ECRにイメージをプッシュする前に、以下のコマンドでECRにログインします。
  - `aws ecr get-login-password | docker login --username AWS --password-stdin xxxxxxxxxxxx.dkr.ecr.ap-northeast-1.amazonaws.com`
- **docker pushコマンド**で作成したイメージをECRにプッシュします
  - `docker push xxxxxxxxxxxx.dkr.ecr.ap-northeast-1.amazonaws.com/<リポジトリ名>:<タグ>`

### ECSの4つの主要な構成要素

#### クラスター

コンテナを実行するための論理的なグループを表し、サービス、タスク（後述）を配下に持ちます。
ECSコンソールから作成できます。作成の際、サービス、タスクを実行するVPCおよびサブネットを指定します。

#### タスク定義

タスクを構成するコンテナの定義群です。イメージの格納場所やメモリ、CPU量、IAMロールなどを定義します。

#### サービス

タスクを何個起動しておくかやELBと連携させる設定、起動タイプ(EC2、Fargate)を定義します。
サービスは指定したタスク数を維持するように動作します。例えば、タスクを手動で1つ停止した際は新しいタスクが1つ実行され、定義したタスク起動数を維持します。また、サービスの設定である起動タスク数を増やすとタスクが新たに実行され、設定した数を維持します（スケールアウト）。

#### タスク

タスク定義によって起動されるコンテナ群を表します。タスク内のコンテナは同一ホスト上で実行されます。

### ECSクラスター作成時のエラーについて

クラスター作成時、以下のエラーが出る可能性があります。これはアカウントで初めてクラスターを作成した際発生するもので、AWS側のバグのようです。クラスター作成を再実施すれば作成できるので特に気にしなくて良いと考えます。

```
Resource handler returned message: "Error occurred during operation 'CreateCluster SDK error: Service Unavailable. Please try again later. (Service: AmazonECS; Status Code: 500; Error Code: ServerException; Request ID: 35cd44a6-7ec2-478b-99bd-5c6ce88cc97c; Proxy: null)'." (RequestToken: d92bf5b9-e968-6def-c4ef-f0a67284b713,
HandlerErrorCode: GeneralServiceException)
```

### 雑記

本ハンズオンではCloud9からDockerコマンドを実行します。Cloud9にはDockerがインストール済みです。

## ハンズオンの感想

私が過去担当していたプロジェクトでもコンテナを使用していましたが、当時それをどんな目的で採用し、採用することでどのような課題を解決するか曖昧でした。
今回のハンズオンでそれらを整理でき、AWSのコンテナサービスであるECS、ECRの基本的な使用方法を理解できました。