
【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
{
"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 Scaling | ECSサービスのキャパシティプロバイダーによるスケーリング |
| VPC | タスクのネットワーク設定(ENI作成/削除) |
ログ・監視
| ログ出力先 | ログの種類 |
|---|---|
| CloudWatch Logs | コンテナログ |
標準メトリクス
| メトリクス名 | 説明 |
|---|---|
| CPUReservation | CPU予約量 |
| CPUUtilization | CPU使用率 |
| MemoryReservation | メモリ予約量 |
| MemoryUtilization | メモリ使用率 |
| DeploymentCount | デプロイ件数 |
| PendingTaskCount | Pendingタスク数 |
| RunningTaskCount | Runningタスク数 |
| ServiceCount | サービス数 |
制限値(固定値/ハードリミット/ソフトリミット)
| 固定値 | 制限値 |
|---|---|
| タスク定義のサイズ | 64 KiB |
| ハードリミット | 制限値 |
|---|---|
| コンテナ数/タスク定義 | 10 |
| ソフトリミット | 制限値 |
|---|---|
| クラスター数/リージョン | 10,000 |
| インスタンス数/クラスター | 5,000 |
| タスク数/サービス | 5,000 |
| サービス数/クラスター | 5,000 |
| PROVISIONINGステートのタスク数 | 500 |
| RunTask API | 20呼び出し/秒(バースト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】targetGroupArn | ALBのターゲットグループのARN |
| 【load-balancers】containerName | ECSタスク定義内で定義されているコンテナ名 |
| 【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に課金 |