#
ドキュメント

Document

自分のための備忘録です。

Amazon Elastic Container Service (Amazon ECS)

完全マネージド型のコンテナオーケストレーションサービス(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. サービス/スケジュールタスクを作成

 

注意事項。

タスク定義

タスク定義名

タスク定義名を英語ではFamilyを呼ぶ。

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

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

タスクの実行

146904883-0524db82-08f0-413a-b795-076ca81ee0aa

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

DockerfileのCMDコマンドを上書きする。 コマンドをカンマ,で区切る必要がある。

Amazon_ECS
  • 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)から取得できずに起動できないのが理由。

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

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

スケジュールされたタスクを作成するとCloudWatchEventBridge) > ルールにルールが作成される。
つまりスケジュールされたタスクパターンスケジュールターゲットECSタスクを指定したルールと等価。

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

  • CloudFormationのAWS::Events::RuleProperties.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

エラーはクラスター>タスク>StoppedSTOPPEDしたタスクを調べればわかる。

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

Amazon_ECS

ALBとターゲットグループ

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

FooSebService:
  Type: AWS::ECS::Service
  Properties:
    #...
    LoadBalancers:
      - TargetGroupArn: {{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:{{クラスター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あり

containerOverridescommandで、コンテナイメージの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

AWS ECSのサーバレスな実行環境(データプレーン)。

AWS ECSの実行環境としてEC2とFargateがある。

EC2の場合はコンテナを実行するためのOSレベルの面倒を見る必要がある。
Fargateはマネージドサービスなので面倒を見る必要がない

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

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

ref.

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

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

SSMパラメータ

  • Secretsに渡すSSMパラメータはコンテナ内では環境変数として受け取られる(これが基本)
  • Environmentとの違いは、 SecretsはSSMパラメータなどのセキュアなサービスに格納した値を渡せること。

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

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

TIPS

AWS::ECS::TaskDefinition ContainerDefinitionEnvironmentSecretsの違い。

Ref.