🐕
AWS Fargate環境を構築してデプロイしてみる
概要
AWS Fargate 環境を構築してデプロイしてみまます。
起動モード EC2 の場合は以下を参考にしていただければと思います。
手順
ローカル環境で Docker イメージを作る
次のようなフォルダ構成で作成します。
フォルダ構成
.
├ src
│ └ index.html
└ Dockerfile
HTML ページを用意する
index.htmlファイル内容
<h1>Hello World!</h1>
Dockerfile を作成する
Dockerfileファイル内容
FROM 'nginx:latest'
RUN service nginx start
COPY src /usr/share/nginx/html
VOLUME /usr/share/nginx/html
Docker イメージを構築する
shell
docker build -t fargatetest .
Docker イメージの動作を確認する
shell
docker run --rm -p 80:80 fargatetest:latest
http://localhost/
にアクセスしてHello World!
が表示されることを確認します。
コンテナリポジトリ(ECR)を作成する
まず、コンテナイメージを格納するための ECR を作成します。
-
Elastic Container Service
-リポジトリ
を開きます。 -
リポジトリを作成
を押下し、設定を行います。- 可視性設定は
プライベート
のままとします。 - リポジトリ名に任意の名前(例:
fargatetest
)を設定します。 -
リポジトリを作成
を押下します。
- 可視性設定は
プッシュコマンドを確認する
AWS コンソールから以下の方法でプッシュコマンドを確認します。
- 作成したリポジトリを選択します。
-
プッシュコマンドの表示
を押下します。
以降、記載のコマンドに沿って操作していきます。
ECR にログインする
PC 環境から AWS CLI を用いて、以下のコマンドを実行し docker で ECR にログインします。(docker コマンド側が AWS ECR に対して、ログイン状態になります。)
shell
aws ecr get-login-password | docker login --username AWS --password-stdin https://<aws_account_id>.dkr.ecr.<region>.amazonaws.com
リポジトリにイメージをプッシュできるようタグをつける
shell
docker tag fargatetest:latest <aws_account_id>.dkr.ecr.ap-northeast-1.amazonaws.com/fargatetest:latest
プッシュを実行する
shell
docker push <aws_account_id>.dkr.ecr.ap-northeast-1.amazonaws.com/fargatetest:latest
VPC を作成する(新規に作成する場合)
- AWS コンソールから
VPC
を選択します。 -
名前タグ
に任意の名前を設定します。(例:fargatetest
) -
IPv4 CIDRブロック
に任意のアドレス帯を設定します。(例:192.168.20.0/24
) -
作成
を押下します。
サブネットを作成する(新規に作成する場合)
- AWS コンソールから
サブネット
を選択します。 -
サブネットを作成
を押下します。 -
VPC ID
は先ほど作成した VPC(fargatetest
)を選択します。 -
サブネット1
を以下の内容で作成します。-
サブネット名
に任意のサブネット名を設定します。(例:fargatetest-public-1a
) -
アベイラビリティゾーン
を選択します。(例:ap-northeast-1a
) -
IPv4 CIDRブロック
に VPC 内の割り当てるネットワークを設定します。(例:192.168.20.0/25
)
-
-
サブネット2
を以下の内容で作成します。-
サブネット名
に任意のサブネット名を設定します。(例:fargatetest-public-1c
) -
アベイラビリティゾーン
を選択します。(例:ap-northeast-1c
) -
IPv4 CIDRブロック
に VPC 内の割り当てるネットワークを設定します。(例:192.168.20.128/25
)
-
-
サブネットを作成
を押下します。
インターネットゲートウェイを作成する(新規に作成する場合)
- AWS コンソールから
インターネットゲートウェイ
を選択します。 -
インターネットゲートウェイの作成
を押下します。 -
名前タグ
に任意の名前を設定します。(例:fargatetest-igw
) -
インターネットゲートウェイの作成
を押下します。 -
アクション
でVPCにアタッチ
を押下します。 - 先ほど作成した VPC(例:
fargatetest
)を選択して、インターネットゲートウェイのアタッチ
を押下します。
ルートテーブルを作成する(新規に作成する場合)
- AWS コンソールから
ルートテーブル
を選択します。 -
ルートテーブルの作成
を押下します。 -
名前タグ
に任意の名前を設定します。(例:fargatetest-public-rt
) -
VPC
は先ほど作成した VPC(fargatetest
)を選択します。 -
キー
をName
とし、任意の値を(例:fargatetest-public-rt
)として設定しておきます。 -
作成
を押下します。 - 作成したルートテーブルで
ルートの編集
を押下します。 -
ルートの追加
を押下します。 -
送信先
を0.0.0.0/0
を設定します。 -
ターゲット
をInternet Gateway
で、先ほど作成したゲートウェイ(例:fargatetest-igw
)を選択します。 -
サブネットの関連付け
タブを押下します。 -
サブネットの関連付けを編集
を押下します。 - 作成したサブネット(
fargatetest-public-1a
、fargatetest-public-1c
)を選択して、関連付けを保存
を押下します。
ロードバランサの作成
- AWS コンソールから
ロードバランサ
を選択します。 -
ロードバランサの作成
を押下します。 -
Application Load Balancer
を選択してCreate
を押下します。 -
Load balancer name
に任意の名前を設定します。(例:fargatetest-alb
) -
Network mapping
で、作成した VPC(fargatetest
)及び作成したサブネット(fargatetest-public-1a
、fargatetest-public-1c
)を選択します。 -
Security groups
設定で、Create new security group
を押下し、新しくセキュリティグループを作成します。-
セキュリティグループ名
に任意の名前を設定します(例:fargatetest-alb-sg
) -
説明
に任意の説明文を設定します。 -
VPC
で、作成した VPC(fargatetest
)を選択します。 -
インバウンドルール
でポート80
でソース0.0.0.0/0
を許可します。 -
セキュリティグループを作成
を押下します。
-
- 親画面に戻り、作成したセキュリティグループを選択します。(例:
fargatetest-alb-sg
) -
Listeners and routing
設定で、Create target group
を押下し、新しくターゲットグループを作成します。ECS 側からサービスに紐づくターゲットグループを作成するので、このターゲットグループは最終的には使用されることのない設定になります。- ターゲットタイプは
instances
のままで、80
ポートが解放されていることを確認します。 - ターゲットグループ名(
Target group name
)に任意の名称を設定します(例:fargatetest-default-tg
) -
VPC
が作成した VPC であることを確認します。 -
Protocol version
はHTTP1
とします。 -
Health checks
はデフォルトのままとします。 - 次へ(
Next
)を押下します。 - ターゲットインスタンスは指定せずそのまま作成します。
- 作成したターゲットグループを、ロードバランサ作成画面側から紐づけます。
- ターゲットタイプは
-
Create load balancer
を押下します。
クラスターの作成
- AWS コンソールから
Elastic Container Service
を選択します。 - AWS コンソールから
クラスター
を選択します。 -
クラスターの作成
を押下します。 - クラスターテンプレートは
ネットワーキングのみ
を選択して、次のステップ
を押下します。 -
クラスター名
に任意の名前を設定します。(例:fargatetest-cluster
) -
Tags
に、Name
:fargatetest-cluster
を設定します。 -
作成
を押下します。
タスク定義の作成
- AWS コンソールから
タスク定義
を選択します。 -
タスク定義の作成
を押下します。 - 起動タイプの互換性の選択で
FARGATE
を選択します。 -
次のステップ
を押下します。 -
タスク定義名
に任意の名前を設定します。(例:fargatetest-task-definition
) -
タスクロール
は無しのままにします。 -
オペレーティングシステムファミリー
はLinux
を選択します。 -
タスクサイズ
でタスクに割り当てるタスクメモリ
、タスクCPU
を選択します。今回は最小サイズを選択します。 -
コンテナの定義
でコンテナの追加
を押下します。-
コンテナ名
に任意の名前を設定します。(例:fargatetest-nginx
) -
イメージ
に ECR のイメージ URL をコピーしてきて貼り付けます。 -
ポートマッピング
でコンテナポート
を設定します。(例:80
) ※Fargate はコンテナポートと公開ポートをそろえる必要があります。 -
追加
を押下します。
-
-
Tags
に、Name
:fargatetest-task-definition
を設定します。 -
作成
を押下します。
サービスの作成(ローリングアップデートの場合)※Blue/Green は諸々設定が必要になるので、別途記載します。
- 対象のクラスタを選択し
サービス
-作成
を押下します。 -
起動タイプ
-Fargate
を選択します。 -
タスク定義
について作成したタスク定義を選択し、リビジョン(latest
)を選択します。 -
サービス名
に任意の名前を設定します。(例:fargatetest-service
) -
タスクの数
を設定します。(例:1
) -
デプロイメントタイプ
は、ローリングアップデート
を選択します。 -
次のステップ
を押下します。 -
クラスターVPC
で作成した VPC を選択します。 -
サブネット
で作成したサブネットを選択します。 -
セキュリティグループ名
を任意の名前を設定します。(例:fargatetest-sg
) -
インバウンドルール
でポート80
でソース0.0.0.0/0
を許可します。 -
ロードバランシング
でApplication Load Balancer
を選択します。 -
ロードバランサ名
で作成した ALB(fargatetest-alb
)を選択します。 -
ロードバランス用のコンテナ
-コンテナ名: ポート
で、作成したコンテナのポート(例:fargatetest-nginx:80:80
)を選択し、ロードバランサに追加
を押下します。-
プロダクションリスナーポート
を80:HTTP
に設定します。 -
ターゲットグループ名
に任意の名前を設定します。(例:fargatetest-ecs-tg
) -
パスパターン
を/*
とし、評価順
を1
に設定します。 -
ヘルスチェックパス
を/
に設定します。
-
-
次のステップ
を押下します。 -
AutoScalling
は設定せず、次のステップ
を押下します。 -
サービスの作成
を押下します。
補足:パスパターンについて
ALB を作成した際に、デフォルトのターゲットグループを合わせて作成しており、その際 ALB リスナールールのパスパターンが/
となっています。
その後、ECS 側から、サービスの作成時にパスパターン/*
で評価順1
で作成し、その設定は ALB 側のリスナールールに登録され以下のようになります。
- パスパターン
/*
:ECS 側のサービスにルーティング - パスパターン
/
:ルーティングされないデフォルトのターゲットグループ
ECS 側で複数サービスを動かす場合、例えばですが下記のような構成が考えられます。
- パスパターン
/admin*
:ECS 側で動作するadmin
サービスにルーティング - パスパターン
/member*
:ECS 側で動作するmember
サービスにルーティング - パスパターン
/*
:ECS 側で上位のルールに該当しない場合の処理を受け付けるtop
サービスにルーティング - パスパターン
/
:ルーティングされないデフォルトのターゲットグループ →Sorry へ
AutoScalling について
負荷状況によって、動的にタスク数を変化させたいときは、サービスを作成・更新する際に、AutoScalling の設定を行います。
- サービス作成・更新時に、
Auto Scaling (オプション)
でService Auto Scaling の設定を変更することで、サービスの必要数を調整する
を選択します。 -
タスクの最小数
で負荷最小の場合に、最低いくつのタスクを残すかを設定します。(例:2
) -
タスクの必要数
で AutoScalling がいくつから始まるかを設定します。自動的に調整されるので、スモールスタートであれば、最小数と同じでもよいかと思います。 -
タスクの最大数
で負荷が大きくなった場合に、最大いくつまでタスクを増やすかを設定します。(例:10
) -
自動タスクスケーリングポリシー
でスケーリングポリシーの追加
を押下します。 -
スケーリングポリシータイプ
を選択します。ターゲットの追跡
の場合、ECSサービスの平均CPU使用率
、ECSサービスの平均メモリ使用率
、ECSサービスに紐づくALBのリクエスト数
から基準とするメトリクスを選択できます。ステップスケーリング
の場合、メトリクスに基づくアラームを設定します。ここではターゲットの追跡
でECSサービスの平均CPU使用率
を使用してみます。-
ポリシー名
に任意の名前を設定します。(例:fargatetest-scalling-policy
) -
ECS サービスメトリクス
をECSServiceAverageCPUUtilization
を選択します。 -
ターゲット値
に基準とする値を設定します。CPU 使用率が設定した値に近づくように自動でスケーリングされます。ここでは50
を設定します。 -
スケールアウトクールダウン期間
にスケールアウトしていく際の間隔の時間を設定します。素早くスケールアウトしたい場合、小さい数字を設定しますが、不要なスケールアウトをしてしまう可能性もあるので、最適値を検討します。1 分おきに 1 タスク増やす場合、60
を設定します。ここでは60
を設定します。 -
スケールインクールダウン期間
にスケールインしていく際の間隔の時間を設定します。負荷が落ちた時に素早くスケールインしたい場合小さい値に設定し、すぐにスケールインしたくない場合は、大きな値を設定します。ゆっくりスケールイン(15 分おき)するよう、900
を設定します。
-
参考:GitHub からの自動デプロイ(CodeBuild + CodePipeline)
所感
EC2 版での構築に比べると、EC2 インスタンスを意識せずにタスクのみを意識すればよくなった点が、かなり楽になったように感じました。
制約はありますが、その制約が許容できるのであれば、運用手間を削減したい場合は、Fargate は良い選択肢かと思います。
Discussion