Amazon ECS(Amazon Elastic Container Service)は完全マネージド型のコンテナオーケストレーションサービス(Container Orchestration Service)です。
ECS の他に代表的なオーケストレーションツールに以下ツールがあります。

  • docker compose
  • Kubernetes

目次

  • 構成要素
  • 流れ
    • スケジュールされたタスク
  • ALBとターゲットグループ
    • ルール(AWS::Events::Rule
  • AWS CLIで実行
  • Fargate
  • ブルー/グリーンデプロイ・ローリングデプロイ
  • TIPS
  • Ref

構成要素

  • ECR:イメージリポジトリ
  • クラスター:ECS 実行環境
  • タスク定義: コンテナの情報を記載したもの(使用イメージや CPU など)
  • タスク:タスク定義に基づいて起動されたタスク群
    • サービス
    • スケジュールタスク
  • コントロールプレーン:コンテナオーケストレーションを提供
    • ECS
    • EKS(Amazon Elastic Kubernetes Service)
  • データプレーン:コンテナを稼働する環境を提供
    • Fargate
    • EC2

流れ

  1. クラスターを作成
  2. タスク定義を作成
  3. サービス / スケジュールタスクを作成 

注意事項:

  • ECS は サービス や スケジュールタスク の他に 1 回限りの タスク も作成できる
  • タスク(サービス / スケジュール)を実行する VPC は インターネットゲートウェイ が必要

タスク定義

タスク定義名

タスク定義名を英語では Family と呼びます。

タスクロールとタスク実行ロール

  • タスククロール
    • コンテナ(アプリケーション)が他サービスを使用するためのロール
  • タスク実行ロール
    • 言葉どおりタスク(コンテナ)を実行するためのロール

タスクの実行

Amazon ECS 基礎 1

タスク実行時のコマンドの上書き

Dockerfile の CMD コマンドを上書きします。
コマンドをカンマ , で区切ります。

Amazon ECS 基礎 2

  • php,Receiver.phpのように上書きすると ["php","Receiver.php"] として上書きされる
  • php Receiver.phpのように上書きすると["php Receiver.php"]として上書きされてエラーになる

AssignPublicIp:ENABLED

ECS サービス AWS::ECS::Service、スケジュールタスク AWS::Events::Rule ともに AssignPublicIp: ENABLED でないとエラーが発生します。 具体的には、イメージを取得できずにコンテナを起動できません。

停止理由 ResourceInitializationError: unable to pull secrets or registry auth: execution resource retrieval failed: unable to retrieve secrets from ssm: service call has been retried 5 time(s): RequestCanceled: request context canceled caused by: context deadli...

unable to retrieve secrets from ssm という記載もありますが、コンテナイメージを ECR(registry auth)から取得できずに起動できないのが理由です。

スケジュールされたタスク

スケジュールタスクの詳細は スケジュールされたタスク を参照してください。

スケジュールされたタスク を作成すると CloudWatch(EventBridge) > ルール が作成されます。
スケジュールされたタスク は パターン に スケジュール、ターゲット に ECSタスク を指定したルールと等価です。

Web マネジメントコンソールからルールを作成する場合は、ルール名が必須です。
CloudFormation のAWS::Events::Rule は Properties.Name がオプションです。

  • CloudFormation の AWS::Events::Rule の Properties.Name(ルール名)はオプション
  • ルール名が重複した場合は上書きされる
  • Target の id が重複した場合は上書きされる

Target.id:

The ID of the target. We recommend using a memorable and unique string.

https://docs.aws.amazon.com/ja_jp/AWSCloudFormation/latest/UserGuide/aws-properties-events-rule-target.html#cfn-events-rule-target-id

パブリックIPの自動割当を ENABELED でないと ECR からのイメージ pull でエラーが発生します。

ResourceInitializationError: unable to pull secrets or registry auth: pull command failed: : signal: killed

ref. https://forums.aws.amazon.com/thread.jspa?threadID=339634&tstart=0

エラーは クラスター > タスク > Stopped で STOPPED したタスクを調べます。

https://docs.aws.amazon.com/AmazonECS/latest/developerguide/stopped-task-errors.html

Amazon ECS 基礎 3

ALB とターゲットグループ

ALBを使用して AWS::ECS::Service を稼働している場合は、ALBの ターゲットグループ にサービスを追加します。
ALBの リスナー > ルール でターゲットグループを指定指定します。

FooSebService:
  Type: AWS::ECS::Service
  Properties:
    #...
    LoadBalancers:
      - TargetGroupArn: 

ルール(AWS::Events::Rule)

スケジュールされたタスク を作成すると CloudWatch > ルールにルール(AWS::Events::Rule)が作成されます。 CloudWoatch Events / EventBridge によって ScheduleExpression に指定した日時に クラスター と id で指定したルールが実行される。

FooSchedule:
    Type: AWS::Events::Rule
    Properties:
      Description: "For Schedule Task"
      ScheduleExpression: "cron(*/15 * * * ? *)" # 15分ごと
      #...
      Targets:
        - Arn: 
          Id: "foo-schedule"

AWS CLI で実行

前提

以下のリソースを Web マネジメントコンソールや CloudFormation で作成済みと仮定します。

  • コンテナイメージ
  • タスク定義
  • クラスター
    • サブネット
    • セキュリティグループ

containerOverrides なし

aws ecs run-task \
    --cluster hello-world-cluster \
    --launch-type FARGATE \
    --network-configuration awsvpcConfiguration="{subnets=subnet-xxxxxxxxxx,securityGroups=sg-xxxxxxxxxx,assignPublicIp=ENABLED}" \
    --propagate-tags TASK_DEFINITION \
    --task-definition hello-world-task-definition

containerOverrides あり

containerOverrides の command で、コンテナイメージの CMD を上書きします。 ENTRYPOINTを上書きできるかは要調査。

aws ecs run-task \
    --cluster hello-world-cluster \
    --launch-type FARGATE \
    --network-configuration awsvpcConfiguration="{subnets=subnet-xxxxxxxxxx,securityGroups=sg-xxxxxxxxxx,assignPublicIp=ENABLED}" \
    --propagate-tags TASK_DEFINITION \
    --task-definition hello-world-task-definition \
    --overrides '{"containerOverrides":[{"name":"HelloWorld","command":["echo", "Hello AWS ECS"]}]}'

Dockerfile:

ROM alpine

CMD ["echo", "Hello World!"] # これを↑の"command":["echo", "AWS ECS"]で上書き

Fargate

ECS のサーバレスな実行環境(データプレーン)です。
ECSの実行環境は EC2 と Fargate があります。

EC2 の場合はコンテナを実行するための OS もユーザーが管理する必要があります。 Fargate はマネージドサービスなので AWS に管理を任せることができます。

Fargateはコンテナが稼動している間のみ課金されます(サーバレス)。

ECSでFargate起動タイプを使用する場合は、awsvpcモード を利用することとなる。

  • タスク毎にENIが自動的に割り当てられる。

    https://qiita.com/leomaro7/items/a3edb49d9929dd42cc0d

ref.

  • https://business.ntt-east.co.jp/content/cloudsolution/column-171.html#section-01
  • https://qiita.com/leomaro7/items/a3edb49d9929dd42cc0d

ブルー/グリーンデプロイ・ローリングデプロイ

ref. https://garafu.blogspot.com/2018/11/release-strategy.html#blue-green

SSM パラメータ

  • Secrets に記載した SSM パラメータはコンテナ内で環境変数として使用できる
  • Environment との違いは、 Secrets は SSM パラメータなどのセキュアなサービスに格納した値を渡せること。

実務におけるデプロイフロー

  1. Web マネジメントコンソールから SSM パラメータを登録
  2. インフラコード(CloudFormation、CDK)に SSM パラメータを追加
  3. インフラをデプロイ
  4. インフラをデプロイ後にアプリをデプロイ
  5. インフラのデプロイからアプリのデプロイまでに時間差があったとしても(アプリに)使用しない環境変数が渡されるだけなので問題はない

TIPS

AWS::ECS::TaskDefinition ContainerDefinition の Environment と Secrets の違いは以下のとおりです。

  • Environment 通常の環境変数

    The environment variables to pass to a container. This parameter maps to Env in the Create a container section of the Docker Remote API and the –env option to docker run.

    https://docs.aws.amazon.com/ja_jp/AWSCloudFormation/latest/UserGuide/aws-properties-ecs-taskdefinition-containerdefinitions.html#cfn-ecs-taskdefinition-containerdefinition-environment

  • Secrets 環境変数と渡される Environment とおなじだが Secrets Manager や SSM パラメータ の値を渡せる

    The secrets to pass to the container. For more information, see Specifying Sensitive Data in the Amazon Elastic Container Service Developer Guide.

    https://docs.aws.amazon.com/ja_jp/AWSCloudFormation/latest/UserGuide/aws-properties-ecs-taskdefinition-containerdefinitions.html#cfn-ecs-taskdefinition-containerdefinition-secrets

Ref.