基礎
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
流れ
- クラスターを作成
- タスク定義を作成
- サービス / スケジュールタスクを作成
注意事項:
ECSはサービスやスケジュールタスクの他に 1 回限りのタスクも作成できるタスク(サービス/スケジュール)を実行するVPCはインターネットゲートウェイが必要
タスク定義
タスク定義名
タスク定義名を英語では Family と呼びます。
タスクロールとタスク実行ロール
- タスククロール
- コンテナ(アプリケーション)が他サービスを使用するためのロール
- タスク実行ロール
- 言葉どおりタスク(コンテナ)を実行するためのロール
タスクの実行

タスク実行時のコマンドの上書き
Dockerfile の CMD コマンドを上書きします。
コマンドをカンマ , で区切ります。

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

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 パラメータなどのセキュアなサービスに格納した値を渡せること。
実務におけるデプロイフロー
- Web マネジメントコンソールから SSM パラメータを登録
- インフラコード(CloudFormation、CDK)に SSM パラメータを追加
- インフラをデプロイ
- インフラをデプロイ後にアプリをデプロイ
- インフラのデプロイからアプリのデプロイまでに時間差があったとしても(アプリに)使用しない環境変数が渡されるだけなので問題はない
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