はじめに
ECS fargateについて知りたかった為、ハンズオンをしました。
備忘録として記載していきます

対象者
・コンテナ本当に何もわからない
・とにかく手を動かしたい
ハンズオン
今回実施した手順は以下の通りになります。
①VPC、サブネット、IGW、NATゲートウェイ、ルートテーブル作成
②ALB用とFargate用のセキュリティグループを作成
③ターゲットグループ作成
④ALBを作成
⑤ECSクラスター、ECRリポジトリ作成
⑥タスク定義作成
⑦ECSサービス作成
1.VPCを作成します
2.4つサブネットを作成します
「ecs-demo-public-subnet01」 : 10.0.0.0/24, 1a
「ecs-demo-public-subnet02」 : 10.0.1.0/24, 1c
「ecs-demo-private-subnet01」 : 10.0.2.0/24, 1a
「ecs-demo-private-subnet02」 : 10.0.3.0/24, 1c
3.インターネットゲートウェイ作成 & VPCにアタッチ
[名前タグ] : ecs-demo-igw
IGWを選択して [アクション] のプルダウンから [VPCにアタッチ] を選択し、先ほどのVPCにアタッチ

4.Nat Gateway作成
プライベートサブネットから外部に通信するにはNat Gatewayをパブリックサブネットに配置する必要があります
「NATゲートウェイを作成」をクリック
[名前] : ecs-demo-natgw01
[サブネット] : ecs-demo-public-subnet01 (※パブリックサブネットを選択)
[Elastic IP割り当てID] : [Elastic IPを割り当て] をクリックして割り当てる
もうひとつNATゲートウェイを作成して、もうひとつのパブリックサブネット(02)にアタッチしてください
[名前] : ecs-demo-natgw02
[サブネット] : ecs-demo-public-subnet02 (※パブリックサブネットを選択)

5.ルートテーブル作成&サブネットに紐付け
サブネットの通信制御にルートテーブルを利用します
ルートテーブルを選択し、ひとつだけあるルートテーブルをパブリックサブネット用に編集します。
ルートを [0.0.0.0/0] → 「igw-XXXX」 を追加して保存します
保存ができたら、 [アクション] → [サブネットとの関連付けを編集] でパブリックサブネット2つ紐付けしてください
これにより、パブリックサブネットの通信は外に出ることができます
[
後、2つルートテーブルを新規で作成していきます。これはそれぞれのプライベートサブネットがそれぞれ同じAZのNATゲートウェイへ通信を流せるようにします
route-for-private-subnet01


route-for-private-subnet02


6.Application Load Balancer 作成
次に、Application Load Balancer (ALB)の作成を行います
IGWからのリクエストを受けて、後ろのターゲットグループに流していきます。
EC2のロードバランサーから「ロードバランサーの作成」をクリック
[Application Load Balancer] を選択
[ロードバランサー名] : ecs-demo-alb
[スキーム] : インターネット向け
[IP アドレスタイプ] : IPv4

ネットワークマッピング
[VPC] : ecs-demo-vpc (今回作成したもの)
[マッピング] : パブリックサブネットを2つ選ぶ

基本的な設定
[ターゲットタイプの設定] : IPアドレス
[ターゲットグループ名] : ecs-demo-tg
[ポート] : 5000
[IP アドレスタイプ] : IPv4
※ ALBの設定画面から [ターゲットグループの作成] をクリックして新規で作成します
ターゲットの登録
[ネットワーク] : ecs-demo-vpc
[Ipv4 アドレス] : こちらは「削除」して消してください。(Fargateで起動しているタスクが自動で登録されていきます)
[ポート] : 5000 (タスクが5000ポートで受け付けるのでこちらも5000ポートに設定します)

リスナーとルーティング
[ポート] : 80
[デフォルトアクション] : ecs-demo-tg

7.ECSクラスター作成
8.ECRリポジトリ作成
9.タスク定義作成
次にタスク定義を行います。
まずは、参考にした記事と同じくFlaskでアプリを作成します。
今回はローカル上ではなくCloudshellを使用して行いました。
ディレクトリ作成
mkdir flask-demo
作成したディレクトリに移動
cd flask-demo
app.pyの作成
nano app.py
app.pyの内容(以下を保存)
from flask import Flask
app = Flask(__name__)
@app.route("/")
def hello():
return "Hello World"
if __name__ == "__main__":
app.run(host='0.0.0.0', port=5000, debug=True)
Dockerfileの作成
nano Dockerfile
Dockerfile の内容(以下を保存)
FROM python:3.8
# 作業ディレクトリを指定
WORKDIR /src
# 現在のディレクトリのファイルを /srcディレクトリ(コンテナ上)に追加
ADD app.py .
# flaskをインストール
RUN pip install flask
# 実行
CMD ["python", "app.py"]
CodeBuild用の設定ファイルを作成
nano buildspec.yml
CodeBuild用の設定ファイルの内容(以下を保存)
※YOUR_ACCOUNT_IDとYOUR_REGIONの箇所は自身のAWSアカウントIDとリージョン(例: ap-northeast-1)に置き換える。
version: 0.2
# ビルド環境変数を定義(ECRのURIを設定)
phases:
pre_build:
commands:
# AWSアカウントIDとリージョンを環境に合わせて変更してください
- IMAGE_URI=YOUR_ACCOUNT_ID.dkr.ecr.YOUR_REGION.amazonaws.com/flask-demo-app:latest
# CodeBuildにECRへのプッシュ権限を付与(認証不要でプッシュできる)
- aws ecr get-login-password --region $AWS_DEFAULT_REGION | docker login --username AWS --password-stdin $IMAGE_URI
build:
commands:
# Dockerイメージのビルド
- docker build -t flask-demo-app .
# ECR URIでタグ付け
- docker tag flask-demo-app:latest $IMAGE_URI
post_build:
commands:
# ECRへのプッシュ
- docker push $IMAGE_URI
・S3バケットを作成
・上記で作成したファイルを保存
aws s3 sync . s3://{S3バケット名}/
10.CodeBuildプロジェクトの作成
名前:demo-dev-fargate-codebuild
ソースプロバイダー:AmazonS3(必要に応じて新規作成し、Cloudshellで作成したファイルを保存)
S3バケット:作成したS3バケットを選択
S3オブジェクトキー:/
環境イメージ:マネージド型イメージ
OS:AmazonLinux
ランタイム:Standard
イメージ:aws/codebuild/amazonlinux2-x86_64:5.0
特権モード:有効化
サービスロール:新しいサービスロールを作成
Buildspec:buildspec.yml





※新しく作成したロールにポリシー「AmazonEC2ContainerRegistryPowerUser」を手動で追加する

11.CodeBuildでイメージをビルド・プッシュ
ECRの「Create repository」を選択し、プッシュコマンドを上から順にCloudshel上で実行します。


12.タスク定義の作成
タスク定義名:flask-app-task-definition
タスクロール:なし
OS:Linux
タスクサイズ:タスクCPU 0.25vCPU タスクメモリ 0.5GB
タスク実行ロール:ecsTaskExecutionRole
コンテナ名:flask-demo-app
イメージ:ECRにPUSHしたDockerイメージを選択
ポート:5000





13.ECSサービスの作成
ここまで来たら、いよいよサービスの作成を行っていきます。
ここでは作成したALBを紐づけていきます。
起動タイプ:Fargate
OS:Linux
タスク定義:flask-app-task-definition
クラスター:作成したクラスターを選択
名前:demo-dev-ecs-service
デプロイメントタイプ:ローリングアップデート
希望タスク数:2
クラスターVPC:作成したVPCを選択
サブネット:プライベートサブネットを2つ選択 (パブリックサブネットを選ばないように!)
パブリックIPの自動割り当て:なし
セキュリティグループ:作成したFargate用SGを選択
ロードバランサーの種類:ALB
ロードバランサー:作成したALBを選択
リスナーポート:既存を選択 80:HTTP
ターゲットグループ:既存を選択 作成したターゲットグループを選択








14.動作確認
タスクが起動していること、ターゲットグループのヘルスチェックが正常になっていることを確認します。


次に、ALBのエンドポイント(DNS名)をコピーし、ブラウザからアクセスをしてみます。
※HTTPのみ許可しているため、http://エンドポイント名に変更してください。
以下のよう表示されれば無事完成です!

最後に
今回は、ローカルではなくAWS上でCloudshellを使用して、
Fargateを使用したコンテナのデプロイをやってみた手順をブログにまとめました。
コンテナはとっつきにくいイメージでしたが、今回のハンズオンで学びになることが多かったです。
参考









