🐕

AWS Fargate環境を構築してデプロイしてみる

2022/02/21に公開

概要

AWS Fargate 環境を構築してデプロイしてみまます。
起動モード EC2 の場合は以下を参考にしていただければと思います。

https://zenn.dev/ttani/articles/aws-ecs-setup

手順

ローカル環境で 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 を作成します。

  1. Elastic Container Service-リポジトリを開きます。
  2. リポジトリを作成を押下し、設定を行います。
    1. 可視性設定はプライベートのままとします。
    2. リポジトリ名に任意の名前(例:fargatetest)を設定します。
    3. リポジトリを作成を押下します。

プッシュコマンドを確認する

AWS コンソールから以下の方法でプッシュコマンドを確認します。

  1. 作成したリポジトリを選択します。
  2. プッシュコマンドの表示を押下します。

以降、記載のコマンドに沿って操作していきます。

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 を作成する(新規に作成する場合)

  1. AWS コンソールからVPCを選択します。
  2. 名前タグに任意の名前を設定します。(例:fargatetest
  3. IPv4 CIDRブロックに任意のアドレス帯を設定します。(例:192.168.20.0/24
  4. 作成を押下します。

サブネットを作成する(新規に作成する場合)

  1. AWS コンソールからサブネットを選択します。
  2. サブネットを作成を押下します。
  3. VPC IDは先ほど作成した VPC(fargatetest)を選択します。
  4. サブネット1を以下の内容で作成します。
    1. サブネット名に任意のサブネット名を設定します。(例:fargatetest-public-1a
    2. アベイラビリティゾーンを選択します。(例:ap-northeast-1a
    3. IPv4 CIDRブロックに VPC 内の割り当てるネットワークを設定します。(例:192.168.20.0/25
  5. サブネット2を以下の内容で作成します。
    1. サブネット名に任意のサブネット名を設定します。(例:fargatetest-public-1c
    2. アベイラビリティゾーンを選択します。(例:ap-northeast-1c
    3. IPv4 CIDRブロックに VPC 内の割り当てるネットワークを設定します。(例:192.168.20.128/25
  6. サブネットを作成を押下します。

インターネットゲートウェイを作成する(新規に作成する場合)

  1. AWS コンソールからインターネットゲートウェイを選択します。
  2. インターネットゲートウェイの作成を押下します。
  3. 名前タグに任意の名前を設定します。(例:fargatetest-igw
  4. インターネットゲートウェイの作成を押下します。
  5. アクションVPCにアタッチを押下します。
  6. 先ほど作成した VPC(例:fargatetest)を選択して、インターネットゲートウェイのアタッチを押下します。

ルートテーブルを作成する(新規に作成する場合)

  1. AWS コンソールからルートテーブルを選択します。
  2. ルートテーブルの作成を押下します。
  3. 名前タグに任意の名前を設定します。(例:fargatetest-public-rt
  4. VPCは先ほど作成した VPC(fargatetest)を選択します。
  5. キーNameとし、任意の値を(例:fargatetest-public-rt)として設定しておきます。
  6. 作成を押下します。
  7. 作成したルートテーブルでルートの編集を押下します。
  8. ルートの追加を押下します。
  9. 送信先0.0.0.0/0を設定します。
  10. ターゲットInternet Gatewayで、先ほど作成したゲートウェイ(例:fargatetest-igw)を選択します。
  11. サブネットの関連付けタブを押下します。
  12. サブネットの関連付けを編集を押下します。
  13. 作成したサブネット(fargatetest-public-1afargatetest-public-1c)を選択して、関連付けを保存を押下します。

ロードバランサの作成

  1. AWS コンソールからロードバランサを選択します。
  2. ロードバランサの作成を押下します。
  3. Application Load Balancerを選択してCreateを押下します。
  4. Load balancer nameに任意の名前を設定します。(例:fargatetest-alb
  5. Network mappingで、作成した VPC(fargatetest)及び作成したサブネット(fargatetest-public-1afargatetest-public-1c)を選択します。
  6. Security groups設定で、Create new security groupを押下し、新しくセキュリティグループを作成します。
    1. セキュリティグループ名に任意の名前を設定します(例:fargatetest-alb-sg
    2. 説明に任意の説明文を設定します。
    3. VPCで、作成した VPC(fargatetest)を選択します。
    4. インバウンドルールでポート80でソース0.0.0.0/0を許可します。
    5. セキュリティグループを作成を押下します。
  7. 親画面に戻り、作成したセキュリティグループを選択します。(例:fargatetest-alb-sg
  8. Listeners and routing設定で、Create target groupを押下し、新しくターゲットグループを作成します。ECS 側からサービスに紐づくターゲットグループを作成するので、このターゲットグループは最終的には使用されることのない設定になります。
    1. ターゲットタイプはinstancesのままで、80ポートが解放されていることを確認します。
    2. ターゲットグループ名(Target group name)に任意の名称を設定します(例:fargatetest-default-tg)
    3. VPCが作成した VPC であることを確認します。
    4. Protocol versionHTTP1とします。
    5. Health checksはデフォルトのままとします。
    6. 次へ(Next)を押下します。
    7. ターゲットインスタンスは指定せずそのまま作成します。
    8. 作成したターゲットグループを、ロードバランサ作成画面側から紐づけます。
  9. Create load balancerを押下します。

クラスターの作成

  1. AWS コンソールからElastic Container Serviceを選択します。
  2. AWS コンソールからクラスターを選択します。
  3. クラスターの作成を押下します。
  4. クラスターテンプレートはネットワーキングのみを選択して、次のステップを押下します。
  5. クラスター名に任意の名前を設定します。(例:fargatetest-cluster
  6. Tagsに、Name:fargatetest-clusterを設定します。
  7. 作成を押下します。

タスク定義の作成

  1. AWS コンソールからタスク定義を選択します。
  2. タスク定義の作成を押下します。
  3. 起動タイプの互換性の選択でFARGATEを選択します。
  4. 次のステップを押下します。
  5. タスク定義名に任意の名前を設定します。(例:fargatetest-task-definition
  6. タスクロールは無しのままにします。
  7. オペレーティングシステムファミリーLinuxを選択します。
  8. タスクサイズでタスクに割り当てるタスクメモリタスクCPUを選択します。今回は最小サイズを選択します。
  9. コンテナの定義コンテナの追加を押下します。
    1. コンテナ名に任意の名前を設定します。(例:fargatetest-nginx
    2. イメージに ECR のイメージ URL をコピーしてきて貼り付けます。
    3. ポートマッピングコンテナポートを設定します。(例:80) ※Fargate はコンテナポートと公開ポートをそろえる必要があります。
    4. 追加を押下します。
  10. Tagsに、Name:fargatetest-task-definitionを設定します。
  11. 作成を押下します。

サービスの作成(ローリングアップデートの場合)※Blue/Green は諸々設定が必要になるので、別途記載します。

  1. 対象のクラスタを選択しサービス-作成を押下します。
  2. 起動タイプ-Fargateを選択します。
  3. タスク定義について作成したタスク定義を選択し、リビジョン(latest)を選択します。
  4. サービス名に任意の名前を設定します。(例:fargatetest-service
  5. タスクの数を設定します。(例:1
  6. デプロイメントタイプは、ローリングアップデートを選択します。
  7. 次のステップを押下します。
  8. クラスターVPCで作成した VPC を選択します。
  9. サブネットで作成したサブネットを選択します。
  10. セキュリティグループ名を任意の名前を設定します。(例:fargatetest-sg
  11. インバウンドルールでポート80でソース0.0.0.0/0を許可します。
  12. ロードバランシングApplication Load Balancerを選択します。
  13. ロードバランサ名で作成した ALB(fargatetest-alb)を選択します。
  14. ロードバランス用のコンテナ-コンテナ名: ポートで、作成したコンテナのポート(例:fargatetest-nginx:80:80)を選択し、ロードバランサに追加を押下します。
    1. プロダクションリスナーポート80:HTTPに設定します。
    2. ターゲットグループ名に任意の名前を設定します。(例:fargatetest-ecs-tg
    3. パスパターン/*とし、評価順1に設定します。
    4. ヘルスチェックパス/に設定します。
  15. 次のステップを押下します。
  16. AutoScallingは設定せず、次のステップを押下します。
  17. サービスの作成を押下します。

補足:パスパターンについて

ALB を作成した際に、デフォルトのターゲットグループを合わせて作成しており、その際 ALB リスナールールのパスパターンが/となっています。
その後、ECS 側から、サービスの作成時にパスパターン/*で評価順1で作成し、その設定は ALB 側のリスナールールに登録され以下のようになります。

  1. パスパターン/*:ECS 側のサービスにルーティング
  2. パスパターン/:ルーティングされないデフォルトのターゲットグループ

ECS 側で複数サービスを動かす場合、例えばですが下記のような構成が考えられます。

  1. パスパターン/admin*:ECS 側で動作するadminサービスにルーティング
  2. パスパターン/member*:ECS 側で動作するmemberサービスにルーティング
  3. パスパターン/*:ECS 側で上位のルールに該当しない場合の処理を受け付けるtopサービスにルーティング
  4. パスパターン/:ルーティングされないデフォルトのターゲットグループ →Sorry へ

AutoScalling について

負荷状況によって、動的にタスク数を変化させたいときは、サービスを作成・更新する際に、AutoScalling の設定を行います。

  1. サービス作成・更新時に、Auto Scaling (オプション)Service Auto Scaling の設定を変更することで、サービスの必要数を調整するを選択します。
  2. タスクの最小数で負荷最小の場合に、最低いくつのタスクを残すかを設定します。(例:2
  3. タスクの必要数で AutoScalling がいくつから始まるかを設定します。自動的に調整されるので、スモールスタートであれば、最小数と同じでもよいかと思います。
  4. タスクの最大数で負荷が大きくなった場合に、最大いくつまでタスクを増やすかを設定します。(例:10
  5. 自動タスクスケーリングポリシースケーリングポリシーの追加を押下します。
  6. スケーリングポリシータイプを選択します。ターゲットの追跡の場合、ECSサービスの平均CPU使用率ECSサービスの平均メモリ使用率ECSサービスに紐づくALBのリクエスト数から基準とするメトリクスを選択できます。ステップスケーリングの場合、メトリクスに基づくアラームを設定します。ここではターゲットの追跡ECSサービスの平均CPU使用率を使用してみます。
    1. ポリシー名に任意の名前を設定します。(例:fargatetest-scalling-policy
    2. ECS サービスメトリクスECSServiceAverageCPUUtilizationを選択します。
    3. ターゲット値に基準とする値を設定します。CPU 使用率が設定した値に近づくように自動でスケーリングされます。ここでは50を設定します。
    4. スケールアウトクールダウン期間にスケールアウトしていく際の間隔の時間を設定します。素早くスケールアウトしたい場合、小さい数字を設定しますが、不要なスケールアウトをしてしまう可能性もあるので、最適値を検討します。1 分おきに 1 タスク増やす場合、60を設定します。ここでは60を設定します。
    5. スケールインクールダウン期間にスケールインしていく際の間隔の時間を設定します。負荷が落ちた時に素早くスケールインしたい場合小さい値に設定し、すぐにスケールインしたくない場合は、大きな値を設定します。ゆっくりスケールイン(15 分おき)するよう、900を設定します。

参考:GitHub からの自動デプロイ(CodeBuild + CodePipeline)

https://zenn.dev/ttani/articles/aws-ecs-autodeploy

所感

EC2 版での構築に比べると、EC2 インスタンスを意識せずにタスクのみを意識すればよくなった点が、かなり楽になったように感じました。
制約はありますが、その制約が許容できるのであれば、運用手間を削減したい場合は、Fargate は良い選択肢かと思います。

株式会社トッカシステムズ

Discussion