更新
コンソールのアップロードに伴い、新規で記事を執筆しました
こちらで学習して頂ければと思います!(2024/06/10)
はじめに
「AWSにコンテナをデプロイして稼働させたい!」 と思っている方は多いかと思います。
ただ、「理解ができん」「むずくね?」と挫折する人がいます。
ポイントを抑えれば、簡単と言うことをこの記事ではお伝えしたいと思います。
今回の記事は、AWS Fargateの 「 Hello World !」 と思っていただけたらと思います。
この記事の対象者
- Fargateを勉強したい方
- Fargateに興味ある方
※初心者向けです
本題
1. 事前知識
マネージコンソールで操作をする前に以下を理解してから始めましょう。
★コントロールプレーン & データプレーン
まずは、ここの理解が必要です。Fargateを調べていると "ECS"やら "EKS"が出てきて混乱してしまします。その部分の整理をまずはしましょう。コンテナを運用していくにあたり、「コントロールプレーン」と「データプレーン」の2つに大きくは分けることができます。コントロールプレーンとは、コンテナな管理をするところで、サッカーで言うと監督的なポジションです。このコントロールプレーンが指示を色々出してコンテナを動かしていきます。一方、データプレーンとは、実際にコンテナを動かす部分でサッカーで言うと選手になります。この監督が「ECS・EKS」で、選手が「EC2・Fargate」なのでその組み合わせ分(4つ)、パターンがあります。
-
コントロールプレーン [ECS][EKS]
- コンテナを管理する機能
- ECS/EKSの2種類
- オーケストレーションサービスと言う点でありコンテナを動かす実行基盤ではない
-
データプレーン [EC2][Fargate]
- 実際にコンテナを実行する環境
- EC2/Fargateの2種類
- これ単体だと動かない、ECS or EKSとセットで使う
- AWSがどこまで責任を負ってくれかでEC2/Fargateは違う
- EC2だと、OSやミドルウェアはユーザーが責任を負うが、Fargateはアプリのみ責任を負えば良い
★ECS (Elastic Container Service)
今回は、「ECS on Fargate」で構成を作るので 「ECS」 の理解をもう少し進めていきましょう。
- コンテナオーケストレーター
- コンテナ管理サービス (コンテナの実行、停止、管理ができます)
- EKSが持つような機能の多くはECSはない
- 秘密情報管理、時間指定での起動、起動成功保証などなど
- ただ、ECSで持っていないがAWSが持っているサービスで補えます
★AWS Fargate
ついでに、「ECS on Fargate」の「Fargate」のメリデメも確認してみたいと思います。
-
メリット
- ホストの管理が不要
- サーバーのスケーリング、パッチ適用、保護、管理にまつわる運用上のオーバーヘッドは発生しない
-
デメリット
- 価格
- 割り当てるCPU/メモリの制限やコンテナが起動するまでの時間が少し遅い
- コンテナにSSHできなかった → 2021/03 「ECS Exec」で解決された (別の章で詳しく書きます)
- GPU未対応 → 使用したいならデータプレーンをEC2へ
その他のコンテナサービス
※ Amazon ECS Anywhere
ECSのコントロールプレーンをAWSで動作させつつ、データプレーンを自身が管理するサーバー上で動作させることができる
※ AWS App Runner
インフラ周辺の構築を全てブラックボックス化しているから楽だが、色々隠蔽されているので触りにくいかも。
★ECSの主要要素
ECSがどのようなものか少しずつわかってきたと思うので、さらに深掘りしていきたいと思います。
(blackbeltから拝借)
以下の4つの名前を覚えましょう
1.タスク(Task)
- コンテナが動作するコンポーネント
- タスクは1つ以上のコンテナから構成
2.タスク定義(Task Definition)
- タスクを定義するテンプレート定義。JSONで記載
- 設定内容
- デプロイするコンテナイメージ
- タスクとコンテナに割り当てるリソース(CPU/メモリ)
- IAMロール
- CloudWatch Logsの出力先等
3.サービス(Service)
- 指定した数だけタスクを維持するスケジューラーで、オーケストレータの「コア機能」!!!
- サービス作成の際にはALBを紐付ける
- 何らかの処理でタスクが停止したら新しいタスクを起動
- 設定内容
- タスク数
- デプロイ定義
- ALB定義
- セキュリティグループ
- オートスケール設定
4.クラスター(Cluster)
- ECSサービスとタスクを実行する論理グループ
2. ECS Fargate デモ
実際に進めていきたいと思います。
流れを記載するので確認して見てください。
やることは多いですが、ひとつずつステップを踏んでいけば大丈夫です!
- VPC作成
- サブネット作成
- インターネットゲートウェイ作成 & VPCにアタッチ
- NATゲートウェイ作成
- ルートテーブル作成&サブネットに紐付け
- ALB作成
- ECSクラスター作成
- タスク定義作成
- サービス作成
- セキュリティグループ更新/確認
完成図
※後ほどupdateします
1. VPC作成
- [名前タグ] : ecs-demo-vpc
- [IPv4 CIDR] : 10.0.0.0/16
- 大体 /16 でVPCは区切ることが多いかと思います
→ << VPCを作成 >>
2. サブネット作成
-
今回は4つ作成します
- パブリックサブネット 2, プライベートサブネット 2
-
[VPC ID] : 先ほど作成したVPCを選択
-
[サブネット名] : ecs-demo-public-subnet01
-
[アベイラビリティーゾーン] : ap-northeast-1a
-
[IPv4 CIDRブロック] : 10.0.0.0/24
- ※同じ操作で以下の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
4つサブネットが作成されると以下のような表示になります
3. インターネットゲートウェイ作成 & VPCにアタッチ
インターネットゲートウェイを作成したら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 (※パブリックサブネットを選択)
NATゲートウェイが2つ作成されたのが確認できます
5. ルートテーブル作成&サブネットに紐付け
サブネットの通信制御にルートテーブルを利用します
- ルートテーブルを選択し、ひとつだけあるルートテーブルをパブリックサブネット用に編集します。
- ルートを [0.0.0.0/0] → 「igw-XXXX」 を追加して保存します。
-
保存ができたら、 [アクション] → [サブネットとの関連付けを編集] でパブリックサブネット2つ紐付けしてください
-
これにより、パブリックサブネットの通信は外に出ることができます
-
後、2つルートテーブルを新規で作成していきます。これはそれぞれのプライベートサブネットがそれぞれ同じAZのNATゲートウェイへ通信を流せるようにします
最終的に3つのルートテーブルができていればOK!
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クラスター作成
クラスター作成
「ネットワーキングのみ」を選択
- [クラスター名] : ecs-demo-cluster
- [CloudWatch Container Insights] : 有効
※ Container Insights : ECSやEKSのメトリクスやログを、CloudWatchで取得〜分析するための機能です。従来でもCloudWatchで用意されているメトリクスはあったのですが、ECSの場合はサービス単位でしかメトリクスが取得できなかったので便利になりました!
→ << 作成 >>
8. タスク定義作成
サンプルアプリの作成
- 今回はFlaskで簡単なアプリを用意していきたいと思います。
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を同じ作業ディレクトリ内で作成します
FROM python:3.8
# 作業ディレクトリを指定
WORKDIR /src
# 現在のディレクトリのファイルを /srcディレクトリ(コンテナ上)に追加
ADD app.py .
# flasknのインストール
RUN pip install flask
# 実行
CMD ["python", "app.py"]
Dockerfileを使用してイメージ作成します
※ -t : 名前をつけています
$ docker build -t flask-demo-app .
作成したDockerイメージの確認
$ docker images
コンテナを起動して接続できるか確認
$ docker run -p 5000:5000 flask-demo-app
(コンテナ内に入るとき)
$ docker run -it -p 5000:5000 flask-demo-app /bin/bash
せっかくなのでコマンドメモ
# イメージの一覧表示
$ docker images
# イメージの削除
$ docker rmi <IMAGE ID>
# 起動中のコンテナ確認
$ docker container ps
# 停止したコンテナも確認
$ docker container ps -a
ECRにイメージをPUSH
AWSのマネージドコンソールに戻ります
まずはリポジトリ作成
ターミナルに戻ります! 以下のnコマンドはECRの画面の「プッシュコマンドの表示」にありますので参考にしてください。
レジストリに対してDockerクライアントを認証
$ aws ecr-public get-login-password --region us-east-1 | docker login --username AWS --password-stdin public.ecr.aws/<XXXXX>
タグ付け
$ docker tag flask-demo-app:latest public.ecr.aws/<XXXXXX>/flask-demo-app:latest
ローカルからECRへDockerイメージをPUSH
$ docker push public.ecr.aws/<XXXXXXX>/flask-demo-app:latest
プッシュがうまくいけば、ECRの画面で確認することができます。
タスク定義設定
・新しいタスク定義を作成
-
[Fargate]を選択
-
[タスク定義名] : flask-app-task-definition
-
[タスクロール] : なし
※タスクロール : コンテナで利用されるIAMロールのことです。コンテナの中のアプリケーションからAWSのサービス(例 : S3 )を利用する場合にこのロールを設定します。
- [オペレーティングシステムファミリー] : Linux
タスク実行IAMロール
- [タスク実行ロール] : ecsTaskExecutionRole
※タスク実行ロール :
タスクサイズ (Fargate起動タイプだと必要)
- [タスクメモリ(GB)] :0.5GB
- [タスクCPU(vCPU)] : 0.25 vCPU
- [コンテナの追加]
コンテナの追加
- [コンテナ名] : flask-demo-app
- [イメージ] : ECRにPUSHしたDockerイメージを選択
- [ポートマッピング] : 5000 #今回が5000ポートを開けているため
→ << 作成 >>
9. サービス作成
-
サービスを設定していきます。ここでは、ALBとの紐付けを行っていきます
-
[起動タイプ] : FARGATE
-
[オペレーティングシステムファミリー] : Linux
-
[タスク定義] : flask-app-task-definition
-
[クラスター] : ecs-demo-cluster
-
[サービス名] : ecs-demo-service
デプロイメント
- [デプロイメントタイプ] : ローリングアップデート
ネットワーク構成
- [クラスターVPC] : vpc
- [サブネット] : プライベートサブネットを2つ選択 (パブリックサブネットを選ばないように注意!)
- [パブリックIPの自動割り当て] : DISABLED
※ Privateサブネットを選択します。
ロードバランシング
- [ロードバランシングーの種類] : Application Load Balancer
- [ロードバランサー名] : ecs-demo-alb
ロードバランス用のコンテナ
- [ターゲットグループ名] : ecs-demo-tg
Auto Scaling(オプション)
- [Service Auto Scaling] : サービスの必要数を直接調整しない
10. セキュリティグループ更新/確認
よくこの設定の確認忘れでうまくアクセスができないことがあります。
基本、NICに対してセキュリティグループは紐づくのでそこの確認をしましょう。
今回は、ALBのところとタスクのところです。
- ALB
- 全てのアドレスから80ポートへのアクセス許可
- タスク(ENI)
- ALBのセキュリティグループから80,5000ポートを許可
11. 確認
- ALBのDNS名を使用してアクセスして見ましょう。
画面 「Hello World」 が表示されれば完成!
以上でこの章は終わりです。
4. ECS Exec紹介
Fargateには今まで欠点がありました。
それは、「コンテナにSSHしてデバックできない」と言うことです
それを解決するソリューションが、「ECS Exec」です! (これは便利)
実際にこれは使えた方が良いので今回紹介したいと思います。
1.Session managere のインストール方法
インストールできたか確認
$ session-manager-plugin
2.IAMコンソールからポリシー作成(JSON)
※ ECSタスクロールに上記のIAMポリシーをアタッチ
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"ssmmessages:CreateControlChannel",
"ssmmessages:CreateDataChannel",
"ssmmessages:OpenControlChannel",
"ssmmessages:OpenDataChannel"
],
"Resource": "*"
}
]
}
3.サービスに対して有効にする
$ aws ecs update-service \
--cluster ecs-demo-cluster \
--service ecs-demo-service \
--enable-execute-command
有効かどうか確認
※有効にした後に作成されたタスクでないとtrueにならないので注意
※タスクの強制再起動をしましょう (サービスの更新でチェックをつけるところがあります)
$ aws ecs describe-tasks \
--cluster ecs-demo-cluster \
--task <TASK ID> \
| grep enableExecuteCommand
4.ログイン(SSH)
$ aws ecs execute-command --cluster my-ecs --task <TASK ID> --container flask-demo-app --interactive --command "/bin/sh"
The Session Manager plugin was installed successfully. Use the AWS CLI to start a session.
Starting session with SessionId: ecs-execute-command-02b234edb8b46dfc3
#
# ls
app.py
#
終わりに
今回網羅的にFargateについて記事を書きました。
次は、「EKS」あたりで同じような記事をまとめられたらと思ってます!
便利なサービスなので皆さんも積極的に使っていきましょう。