ECS

【VPC内リージョンサービス】

ECS(Elastic Container Service)は、AWSが提供するマネージド型のコンテナオーケストレーションサービスです。

シンプルなタスク/サービスモデルで構成されており、ALB(Application Load Balancer)、Service Auto Scaling(サービスオートスケーリング)、および Code 系サービス(CodePipeline/CodeBuild/CodeDeploy/CodeCommit) と統合して動作します。

ECSの起動タイプには EC2 と Fargate があり、用途に応じて柔軟に選択できます。コントロールプレーンはAWSがマネージドし、タスクのスケジューリングやサービス管理を自動化します。一方、データプレーンとしては、ユーザーが EC2 インスタンスまたはサーバーレスな Fargate を選択してコンテナを実行します。

ECSの構成は階層的になっており、最上位に サービスがあり、その中で複数の タスクが実行されます。各タスクは タスク定義に基づいて構成され、使用するコンテナイメージ、CPU/メモリ、環境変数、ボリューム設定などが定義されています。サービスはタスクの数や実行状態を管理し、負荷分散やスケーリングを自動的に制御します。

Service Discovery(サービスディスカバリ) を利用することで、マイクロサービス間の名前解決や通信を自動化できます。

Capacity Providers(キャパシティープロバイダー)によって、EC2およびFargateの両方を組み合わせた柔軟なリソース運用が可能です。

Circuit Breaker(サーキットブレーカー)機能を活用すれば、デプロイ時に異常が発生した場合でも自動的にロールバックされ、安全に更新を行うことができます。

App Mesh と連携することで、サービス間通信の可視化やトラフィック制御も容易になります。

重要用語

ユースケース

コンテナ化したWeb/APIアプリの運用DockerコンテナにパッケージしたWebアプリやAPIをECSサービスとして実行し、スケーリングやデプロイをマネージドに行う。
マイクロサービスアーキテクチャの実装複数の小さなコンテナサービスに機能を分割し、ECSでそれぞれ独立してスケール・更新できるマイクロサービス構成を実現する。
定期バッチジョブのコンテナ実行FargateやEC2起動タイプのECSタスクとして、定期的なデータ処理やETLジョブをコンテナで実行し、完了後はリソースを使わないようにする。

ベストプラクティス

タスクごとのIAMロールタスクロールを使ってコンテナ単位でAWSリソース権限を制御する。
サービスのヘルスチェック設定ELBと連携したヘルスチェックで不健康なタスクを自動置き換えする。
CloudWatch Logs連携アプリログをCloudWatch Logsに集約し、監視と分析を容易にする。

高可用性・バックアップ・リトライ

高可用性・バックアップ・リトライ設計のポイント
【コントロールプレーンのマルチAZ】
 【デフォルト】マルチAZ(AWS 管理)
【データプレーンのマルチAZ】
 EC2(複数 AZ のサブネットに ASGを配置し コンテナインスタンスを分散させる)
 Fargate(サービス定義で複数 AZ のサブネットを指定しその範囲でタスクをスケジューリングさせる)
【タスクの冗長化】
 サービスのdesiredCountを2 以上に設定し可能な限り別 AZ・別コンテナインスタンスに分散配置する
【ノードのオートスケーリング】
 ASG / Capacity Provider によるコンテナインスタンス数の自動増減
【タスクのオートスケーリング】
 ECS Service Auto Scaling によるタスク数の自動調整
【自動リトライ】ECSタスクが失敗しヘルスチェックに失敗
 ECS Service Schedulerが自動的に新しいタスクを起動して自動的に再試行を継続(上限なし)
【自動リトライ】コンテナインスタンス/Fargateノード障害時
 タスクを別の健全なインスタンス(またはFargate)上で再配置し再起動される
【自動リトライ】ECS デプロイ時の自動ロールバック・再実行
 ローリング更新やBlue/Greenが失敗を検出、自動で再デプロイまたは旧バージョンへロールバック

セキュリティ

関連サービス設定内容
Subnet(公開リソースと内部リソースの分離)【Webサーバ】
 Privateの専用SubnetでマルチAZ構成
【バッチサーバ】
 Privateの専用SubnetでマルチAZ構成
SG(リソース単位のアクセス制御)【Webサーバ】
 インバウンド:80(HTTP),443(HTTPS)
 アウトバウンド:すべて許可
【バッチサーバ】
 インバウンド:空(すべて拒否)
 アウトバウンド:443(API通信、必要範囲のみ)
KMS(データの暗号化と鍵の安全管理)-
Secrets Manager(機密情報の安全管理)シークレット(秘密情報)の作成が推奨
 コンテナタスクで使用する認証情報
SSM Parameter Store(設定情報の一元管理)パラメータ(Parameter)の作成が推奨
 アプリ設定や外部のエンドポイント情報
CloudTrail(操作履歴の記録・監査・追跡)【自動記録】
作成・更新・削除・設定変更は自動記録される。(コントロールプレーンAPI)
データ操作は追跡できない(データプレーンAPI)
Config(リソースの構成状態・設定変更を記録)【Configが有効な場合】
クラスター/サービス/タスク定義の変更履歴・IAM/ネットワーク/暗号化準拠評価
GuardDuty(脅威を自動検出)【GuardDutyが有効な場合】
コンテナENI通信の異常検知・API操作異常

【追加オプション】
ECS Runtime Monitoring 導入を推奨
ECS Fargate / EC2 コンテナの実行時動作を監視 ECS サービス単位
ECSが実行ロールを引き受ける典型的な連携パターン
実行ロールを介して連携するサービス実行ロールにアタッチするポリシー
【タスク実行ロール】
ECR(Pull)
ecr:GetAuthorizationToken
ecr:BatchGetImage
ecr:GetDownloadUrlForLayer
ecr:BatchCheckLayerAvailability
【タスク実行ロール】
CloudWatch Logs
logs:CreateLogGroup
logs:CreateLogStream
logs:PutLogEvents
【タスク実行ロール】
Secrets Manager
secretsmanager:GetSecretValue
kms:Decrypt
【タスク実行ロール】
SSM Parameter Store
ssm:GetParameter
ssm:GetParameters
ssm:GetParametersByPath
kms:Decrypt
【タスクロール】
CloudWatch(メトリクス送信)
cloudwatch:PutMetricData
【タスクロール】
RDS/Aurora(IAM認証)
rds-db:connect
【タスクロール】
RDS Data API
rds-data:ExecuteStatement rds-data:BatchExecuteStatement rds-data:BeginTransaction rds-data:CommitTransaction rds-data:RollbackTransaction
【タスクロール】
DynamoDB
dynamodb:GetItem
dynamodb:PutItem
dynamodb:UpdateItem
dynamodb:DeleteItem
dynamodb:Query
dynamodb:Scan
【タスクロール】
S3
s3:ListBucket
s3:GetObject
s3:PutObject
s3:DeleteObject
【タスクロール】
Lambda
lambda:InvokeFunction
【タスクロール】
Step Functions
states:StartExecution
【タスクロール】
EventBridge(Event Bus)
events:PutEvents
【タスクロール】
Kinesis Data Streams
kinesis:PutRecord kinesis:PutRecords
【タスクロール】
Kinesis Firehose
firehose:PutRecord firehose:PutRecordBatch
【タスクロール】
SNS
sns:Publish
【タスクロール】
SQS(ポーリング)
sqs:ReceiveMessage
sqs:DeleteMessage
sqs:GetQueueAttributes
sqs:ChangeMessageVisibility
【タスクロール】
X-Ray
xray:PutTraceSegments
xray:PutTelemetryRecords
【タスクロール】
SSM Parameter Store
ssm:GetParameter ssm:GetParameters kms:Decrypt
【タスクロール】
SSM Session Manager
ssmmessages:CreateControlChannel
ssmmessages:CreateDataChannel
ssmmessages:OpenControlChannel
ssmmessages:OpenDataChannel
ssm:UpdateInstanceInformation
【タスクロール】
Secrets Manager
secretsmanager:GetSecretValue
kms:Decrypt
タスク実行ロール(ECSサービス)、タスクロール(タスク内のアプリケーション)
※)権限設計の原則

信頼ポリシー: ECS

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Principal": {
        "Service": "ecs-tasks.amazonaws.com"
      },
      "Action": "sts:AssumeRole"
    }
  ]
}

ECS が使用する SLR の連携パターン
SLR名 : AWSServiceRoleForECS
SLR が操作するサービス用途
EC2コンテナインスタンスの管理とタスク配置
ELBタスクのターゲットグループへの登録/解除
CloudWatch Logsコンテナログの収集と保存
ECRコンテナイメージの取得
Auto ScalingECSサービスのキャパシティプロバイダーによるスケーリング
VPCタスクのネットワーク設定(ENI作成/削除)
権限設計の原則

ログ・監視

ログ出力先ログの種類
CloudWatch Logsコンテナログ
CloudWatch Logs優先の原則
標準メトリクス
メトリクス名説明
CPUReservationCPU予約量
CPUUtilizationCPU使用率
MemoryReservationメモリ予約量
MemoryUtilizationメモリ使用率
DeploymentCountデプロイ件数
PendingTaskCountPendingタスク数
RunningTaskCountRunningタスク数
ServiceCountサービス数

制限値(固定値/ハードリミット/ソフトリミット)

固定値制限値
タスク定義のサイズ64 KiB

ハードリミット制限値
コンテナ数/タスク定義10

ソフトリミット制限値
クラスター数/リージョン10,000
インスタンス数/クラスター5,000
タスク数/サービス5,000
サービス数/クラスター5,000
PROVISIONINGステートのタスク数500
RunTask API20呼び出し/秒(バースト100)

AWS CLIのサンプルコード

SG を作成する(VPC ID 指定)
aws ec2 create-security-group \
  --group-name sg-xxxxxxxx \
  --vpc-id vpc-xxxxxxxxx \
  --tag-specifications 'ResourceType=security-group,Tags=[{Key=Name,Value=sg-xxxxxxxx}]'
SG ID を表示する
aws ec2 describe-security-groups
アウトバウンドルールを追加する(SG ID 指定)
aws ec2 authorize-security-group-egress \
  --group-id sg-xxxxxxxxx \
  --protocol tcp \
  --port 80 \
  --cidr 0.0.0.0/0
SG を削除する(SG ID 指定)
aws ec2 delete-security-group \
  --group-id sg-xxxxxxxxx

タスク実行ロールを作成する(信頼ポリシーのファイル名 指定)
ecs-trust-policy.json
{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Principal": {
        "Service": "ecs-tasks.amazonaws.com"
      },
      "Action": "sts:AssumeRole"
    }
  ]
}
aws iam create-role \
  --role-name ecsTaskExecutionRole \
  --assume-role-policy-document file://ecs-trust-policy.json
タスク実行ロールを表示する
aws iam list-roles
タスク実行ロールを削除する(ロール名 指定)
aws iam list-attached-role-policies \
  --role-name ecsTaskExecutionRole

タスク実行ロールにAWS管理ポリシーをアタッチする(ロール名、ポリシーのARN 指定)
aws iam attach-role-policy \
  --role-name ecsTaskExecutionRole \
  --policy-arn arn:aws:iam::aws:policy/service-role/AmazonECSTaskExecutionRolePolicy
タスク実行ロールからAWS管理ポリシーをデタッチする(ロール名、ポリシーのARN 指定)
aws iam detach-role-policy \
  --role-name ecsTaskExecutionRole \
  --policy-arn arn:aws:iam::aws:policy/service-role/AmazonECSTaskExecutionRolePolicy

タスクロールを作成する(信頼ポリシーのファイル名 指定)
ecs-task-trust-policy.json
{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Principal": {
        "Service": "ecs-tasks.amazonaws.com"
      },
      "Action": "sts:AssumeRole"
    }
  ]
}
aws iam create-role \
  --role-name ECSTaskRole \
  --assume-role-policy-document file://ecs-task-trust-policy.json
タスクロールを表示する
aws iam list-roles
タスクロールを削除する(ロール名 指定)
aws iam list-attached-role-policies \
  --role-name ECSTaskRole

タスクロールにAWS管理ポリシーをアタッチする(ロール名 指定)
aws iam attach-role-policy \
  --role-name MyECSTaskRole \
  --policy-arn arn:aws:iam::aws:policy/AmazonDynamoDBFullAccess
タスクロールからAWS管理ポリシーをデタッチする(ロール名 指定)
aws iam detach-role-policy \
  --role-name MyECSTaskRole \
  --policy-arn arn:aws:iam::aws:policy/AmazonDynamoDBFullAccess

ECSクラスターを作成する
aws ecs create-cluster \
  --cluster-name MyCluster \
  --tags key=Name,value=MyCluster
ECSクラスターの一覧を表示する
aws ecs list-clusters
クラスターを表示する(クラスター名 指定)
aws ecs describe-clusters \
  --clusters MyCluster
ECSクラスターを削除する(クラスター名 指定)
aws ecs delete-cluster \
  --cluster MyCluster

タスク定義を作成する(タスク定義ファイル名 指定)
task-definition.json
{
  "family": "my-task",
  "networkMode": "awsvpc",
  "requiresCompatibilities": ["FARGATE"],
  "cpu": "256",
  "memory": "512",
  "executionRoleArn": "arn:aws:iam::123456789012:role/ecsTaskExecutionRole",
  "taskRoleArn": "arn:aws:iam::123456789012:role/ecsTaskRole",
  "containerDefinitions": [
    {
      "name": "my-container",
      "image": "nginx:latest",
      "portMappings": [
        {
          "containerPort": 80,
          "protocol": "tcp"
        }
      ],
      "essential": true,
      "logConfiguration": {
        "logDriver": "awslogs",
        "options": {
          "awslogs-group": "/ecs/my-task",
          "awslogs-region": "ap-northeast-1",
          "awslogs-stream-prefix": "ecs"
        }
      }
    }
  ]
}
aws ecs register-task-definition \
  --cli-input-json file://task-definition.json \
  --tags key=Name,value=my-task
タスク定義の一覧を表示する
aws ecs list-task-definitions
タスク定義を表示する(タスク定義のファミリー名:リビジョン番号 指定)
aws ecs describe-task-definition \
  --task-definition my-task:1
タスク定義を削除する(タスク定義のファミリー名:リビジョン番号 指定)
aws ecs deregister-task-definition \
  --task-definition my-task:1

ECSサービスを作成する(マルチAZのSubnet、SG ID、ALB連携関連 指定)
ALB連携は、--load-balancersで可能(用途:Webサービス、API)
desired-countのタスク数を自動維持、完了後は停止して自動再起動する
【load-balancers】targetGroupArnALBのターゲットグループのARN
【load-balancers】containerNameECSタスク定義内で定義されているコンテナ名
【load-balancers】containerPortコンテナがリッスンしているポート番号
aws ecs create-service \
  --cluster MyCluster \
  --service-name my-service \
  --task-definition my-task:1 \
  --desired-count 2 \
  --launch-type FARGATE \
  --network-configuration "awsvpcConfiguration={
    subnets=[subnet-xxxxxxxx,subnet-yyyyyyyy],
    securityGroups=[sg-xxxxxxxx]
  }" \
  --load-balancers \
    targetGroupArn=arn:aws:elasticloadbalancing:ap-northeast-1:123456789012:targetgroup/my-targets/50dc6c495c0c9188,\
    containerName=my-container,\
    containerPort=80 \
  --tags key=Name,value=my-service
ECSサービスを手動起動する(クラスタ名 指定)
ALB連携は不可(用途:バッチ処理、マイグレーション)
指定したcountだけ実行、完了後は停止して自動再起動なし
aws ecs run-task \
  --cluster MyCluster \
  --task-definition my-task:1 \
  --count 2 \
  --launch-type FARGATE \
  --network-configuration "awsvpcConfiguration={
    subnets=[subnet-xxxxxxxx,subnet-yyyyyyyy],
    securityGroups=[sg-xxxxxxxx]
  }" \
  --tags key=Name,value=my-task-manual
ECSサービスの一覧を表示する(クラスタ名 指定)
aws ecs list-services \
  --cluster MyCluster
ECSサービスを表示する(クラスタ名、サービス名 指定)
aws ecs describe-services \
  --cluster MyCluster \
  --services my-service
ECSサービスを削除する(クラスタ名、サービス名 指定)
aws ecs delete-service \
  --cluster MyCluster \
  --service my-service

ECSタスクの一覧を表示する(クラスタ名 指定)
aws ecs list-tasks \
  --cluster MyCluster
ECSタスクを停止する(タスク ID 指定)
サービスで起動したタスクの停止ECSが自動的に新しいタスクを起動する
run-taskで起動したタスクの停止タスクは停止したまま、再起動されない
aaws ecs stop-task \
  --cluster MyCluster \
  --task arn:aws:ecs:ap-northeast-1:123456789012:task/MyCluster/abc123def456

CloudFormationのサンプルコード

Terraformのサンプルコード

料金計算

課金項目説明
ECS自体は無料EC2またはFargateに課金

公式ページ

AWSドキュメント ECS