AWS ECS・Fargateでコンテナアプリを本番運用するための設計手順|タスク定義・ALB連携・マルチAZ配置の構成パターン入門

宮崎智広 この記事の監修:宮崎智広(Linux実務・教育歴20年以上・受講者3,100名超)
HOMELinux技術 リナックスマスター.JP(Linuxマスター.JP)AWS(Amazon Linux) > AWS ECS・Fargateでコンテナアプリを本番運用するための設計手順|タスク定義・ALB連携・マルチAZ配置の構成パターン入門
「Dockerでアプリをコンテナ化したはいいが、AWSで本番運用する構成をどう設計すればいいかわからない」
「ECSとFargateの違いは?ALBとの連携方法や、マルチAZ設計のポイントが整理できていない」

こうした悩みを持つLinuxエンジニアは少なくありません。コンテナ技術そのものはDockerで学べても、AWSで"止まらない本番構成"を組み立てるには、ECS固有の設計ルールを体系的に把握する必要があります。

この記事では、AWS ECS・Fargateを使ったコンテナ本番環境の設計手順を、タスク定義・ALBとの連携・マルチAZ分散配置・Auto Scaling・IAMロール設計まで順を追って解説します。動作確認済みのAWS CLIコマンドと設定例を交えながら進めるので、設計の全体像を掴みながら読み進めてください。

動作確認環境: Amazon Linux 2023 / AWS CLI 2.x

この記事のポイント

・FargateはサーバーレスでEC2管理が不要。本番用途では最初の選択肢になる
・タスク定義でCPU・メモリ・コンテナ定義・ログ設定を一元管理する
・ECSサービス+ALBでマルチAZに分散配置してヘルスチェックを自動化する
・Auto ScalingはCPU使用率70%をトリガーにするターゲットトラッキングが基本


「このままじゃマズい」と感じていませんか?
参考書を開く気力もない、同年代に取り残される不安——
でも安心してください。プロのエンジニアはコマンドを暗記していません。
「現場で使える型」を効率よく使いこなしているだけです。
図解60P/登録10秒/解除も3秒 / 詳細はこちら

ECSとFargateとは?起動タイプの違いと選び方

ECS(Elastic Container Service)はAWSのコンテナオーケストレーションサービスです。
DockerコンテナをAWS上で管理・実行するための基盤として機能します。

ECSには起動タイプが2つあります。

EC2起動タイプ: コンテナを実行するEC2インスタンスを自分で管理する
Fargate起動タイプ: コンテナの実行基盤をAWSがすべて管理するサーバーレス

ほとんどの新規構築ではFargateを選ぶのが正解です。EC2起動タイプは、コンテナホストのOSパッチ管理・ECSエージェントの更新・スケール時のインスタンス管理が必要になります。FargateであればこれらをすべてAWSに任せられます。

EC2起動タイプが適しているのは、GPUを使う機械学習コンテナや、ARM64など特定のアーキテクチャが必要な場合に限られます。

ECSの主要コンポーネントの整理

ECSを設計する前に、主要コンポーネントの役割を整理しておきます。

クラスター: ECSリソースの論理的なグループ。Fargateタスクが実行される空間
タスク定義: コンテナの設定テンプレート(CPU・メモリ・イメージ・環境変数・ログ設定)
タスク: タスク定義を元に実際に起動したコンテナのインスタンス
サービス: 指定した数のタスクを常時稼働させ、ALBと連携する管理エンティティ

「タスク定義=設計図」「タスク=インスタンス」「サービス=台数管理と外部公開」というイメージで捉えると整理しやすいです。

タスク定義の設計ポイント

タスク定義はECS設計の核心部分です。以下の3点を押さえておけば、現場レベルの設計ができます。

1. CPUとメモリの割り当て基準

Fargateでは、タスク全体のCPUとメモリを事前に決める必要があります。
使えるサイズの組み合わせは固定されています。代表的なパターンは次のとおりです。

タスクCPU(vCPU) 選択できるメモリ(GB) 用途の目安
0.25 vCPU 0.5 ~ 2 GB 軽量なAPIやバッチ処理
0.5 vCPU 1 ~ 4 GB 標準的なWebアプリ(小規模)
1 vCPU 2 ~ 8 GB 中規模Webアプリ・マイクロサービス
2 vCPU 4 ~ 16 GB 高トラフィックAPI・画像処理
4 vCPU 8 ~ 30 GB 大規模バッチ・データ処理
最初は小さめのサイズから始め、CloudWatch MetricsのCPUUtilization・MemoryUtilizationを見ながら調整するのが現場の鉄則です。最初から大きいサイズを確保しても、コストが増えるだけです。

2. コンテナ定義と環境変数・シークレットの設計

タスク定義のコンテナ定義で重要なのは、環境変数とシークレットの扱い方です。

一般的な設定値(非機密): environmentに直接指定
パスワード・APIキー(機密情報): AWS Secrets ManagerまたはParameter StoreをsecretsセクションでARN参照する

以下はAWS CLIでタスク定義を登録するJSON例です(抜粋)。

# タスク定義のJSON(コンテナ定義部分の抜粋) { "family": "myapp-task", "networkMode": "awsvpc", "requiresCompatibilities": ["FARGATE"], "cpu": "512", "memory": "1024", "containerDefinitions": [ { "name": "myapp", "image": "123456789012.dkr.ecr.ap-northeast-1.amazonaws.com/myapp:latest", "portMappings": [ { "containerPort": 8080, "protocol": "tcp" } ], "environment": [ {"name": "APP_ENV", "value": "production"}, {"name": "LOG_LEVEL", "value": "info"} ], "secrets": [ { "name": "DB_PASSWORD", "valueFrom": "arn:aws:secretsmanager:ap-northeast-1:123456789012:secret:myapp/db-password" } ], "logConfiguration": { "logDriver": "awslogs", "options": { "awslogs-group": "/ecs/myapp", "awslogs-region": "ap-northeast-1", "awslogs-stream-prefix": "ecs" } } } ] }

機密情報をSecretsManagerで管理するポイントは2点あります。
コンテナ側には環境変数として渡されるため、アプリケーションのコードを変更する必要がないこと。そしてタスク定義のJSONにパスワードが平文で残らないことです。

3. awslogsでCloudWatch Logsにログを転送する

Fargateではコンテナの標準出力・標準エラー出力を、awslogsドライバー経由でCloudWatch Logsに転送します。
タスクが終了してもログが残るため、障害調査に不可欠な設定です。

ロググループは事前に作成しておく必要があります。

# CloudWatch Logsのロググループを作成する aws logs create-log-group --log-group-name /ecs/myapp --region ap-northeast-1 # ロググループの保持期間を30日に設定する aws logs put-retention-policy --log-group-name /ecs/myapp --retention-in-days 30

ロググループの保持期間を設定しないとログが永続的に積み上がり、予想外のコストが発生します。本番環境では30日や90日などの保持期間を必ず設定してください。

ECSサービスとALBの連携設定

ECSサービスはタスクの台数を管理し、ALBと組み合わせることで外部からのHTTPリクエストを各Fargateタスクに分散します。

1. ターゲットグループの作成

ALBとECSサービスを接続するために、まずターゲットグループを作成します。
Fargateの場合はターゲットタイプを「ip」に設定することが必要です(EC2タイプではなく)。

# ターゲットグループを作成する(FargateはIPターゲット) aws elbv2 create-target-group --name myapp-tg --protocol HTTP --port 8080 --vpc-id vpc-0123456789abcdef0 --target-type ip --health-check-path /health --health-check-interval-seconds 30 --healthy-threshold-count 2 --unhealthy-threshold-count 3 # 出力例 { "TargetGroups": [ { "TargetGroupArn": "arn:aws:elasticloadbalancing:ap-northeast-1:123456789012:targetgroup/myapp-tg/abc123def456", "TargetGroupName": "myapp-tg", "Protocol": "HTTP", "Port": 8080, "HealthCheckPath": "/health", ... } ] }

ヘルスチェックパス(/health)はアプリケーション側で必ず実装してください。200 OKを返すだけの軽量なエンドポイントで十分です。

2. ECSサービスでロードバランサーを設定する

ECSサービスを作成する際にALBのターゲットグループを紐付けます。

# ECSサービスを作成する(ALBと連携・マルチAZ) aws ecs create-service --cluster myapp-cluster --service-name myapp-service --task-definition myapp-task:1 --desired-count 2 --launch-type FARGATE --network-configuration "awsvpcConfiguration={ subnets=[subnet-0a1b2c3d4e,subnet-0f1e2d3c4b], securityGroups=[sg-0123456789abcdef0], assignPublicIp=DISABLED }" --load-balancers "targetGroupArn=arn:aws:elasticloadbalancing:ap-northeast-1:123456789012:targetgroup/myapp-tg/abc123,containerName=myapp,containerPort=8080"

subnetsには2つの異なるAZのサブネットを指定することで、自動的にマルチAZ分散配置されます。

3. マルチAZでFargateタスクを分散する

ECSサービスはデフォルトでAZ均等分散(SPREAD)のタスク配置戦略を取りますが、明示的に設定することが推奨されます。

# タスク配置戦略を確認する aws ecs describe-services --cluster myapp-cluster --services myapp-service --query 'services[0].placementStrategy' # AZ均等分散の配置戦略を設定する(update-service) aws ecs update-service --cluster myapp-cluster --service myapp-service --placement-strategy "[{"type":"spread","field":"attribute:ecs.availability-zone"}]"

desired-countを2以上にしたうえでAZ均等分散を設定することで、1つのAZで障害が発生しても残りのAZで処理を継続できます。desired-countを1にした場合は意味がないため、必ず2以上に設定してください。

AWSのインフラ設計をLinuxエンジニアとして体系的に学びたい方は、
AWSをLinuxエンジニアが学ぶためのロードマップもあわせてご覧ください。

Auto ScalingでFargateを自動スケールさせる

ECSサービスのAuto Scalingを設定することで、トラフィックの増減に応じてFargateタスクの台数を自動調整できます。

1. Application Auto Scalingの設定

ECSのAuto ScalingはApplication Auto Scalingを通じて設定します。

# ECSサービスをAuto Scalingのターゲットとして登録する aws application-autoscaling register-scalable-target --service-namespace ecs --scalable-dimension ecs:service:DesiredCount --resource-id service/myapp-cluster/myapp-service --min-capacity 2 --max-capacity 10

min-capacityは本番環境では最低2にしてください。1にすると単一タスクが落ちた瞬間に全サービスが停止します。max-capacityはトラフィックのピーク時に必要な最大タスク数を設定します。

2. スケールアウト・スケールインのポリシー設定

CPU使用率をトリガーにするターゲットトラッキングポリシーが、最もシンプルで安定した設定です。

# CPU使用率70%を目標にするターゲットトラッキングポリシーを設定する aws application-autoscaling put-scaling-policy --service-namespace ecs --scalable-dimension ecs:service:DesiredCount --resource-id service/myapp-cluster/myapp-service --policy-name myapp-cpu-scaling --policy-type TargetTrackingScaling --target-tracking-scaling-policy-configuration '{ "TargetValue": 70.0, "PredefinedMetricSpecification": { "PredefinedMetricType": "ECSServiceAverageCPUUtilization" }, "ScaleOutCooldown": 60, "ScaleInCooldown": 300 }'

ScaleOutCooldown(スケールアウト後のクールダウン)は60秒程度にしてトラフィック急増に素早く対応できるようにします。ScaleInCooldown(スケールイン後のクールダウン)は300秒以上に設定して、過剰なスケールイン(タスク削減)による不安定な状態を防ぎます。

現場では「スケールアウトは素早く、スケールインは慎重に」が鉄則です。

IAMロール設計|タスクロールと実行ロールの違い

FargateのIAM設計で最も混乱しやすいのが、タスクロールと実行ロールの違いです。

実行ロール(Task Execution Role): ECSがタスクを起動・管理するために必要な権限。ECRからイメージをpullする、SecretsManagerからシークレットを取得する、CloudWatch Logsにログを書き込む権限が含まれる。タスクの「起動作業」を行うECSエージェントが使うロール。
タスクロール(Task Role): コンテナの中で動くアプリケーションが他のAWSサービスを呼び出すための権限。S3にファイルをアップロードする、DynamoDBを参照する等の権限をここで設定する。

混同しやすいですが、実行ロールはタスクを「起動する」ための権限、タスクロールはコンテナが「実際に使う」権限と覚えてください。

# 実行ロールに必要な最低限のポリシー(AWSマネージドポリシー) # AmazonECSTaskExecutionRolePolicy に以下が含まれる # - ecr:GetAuthorizationToken # - ecr:BatchGetImage # - logs:CreateLogStream # - logs:PutLogEvents # SecretsManagerを使う場合は追加で以下が必要 # - secretsmanager:GetSecretValue # - kms:Decrypt(KMSで暗号化している場合) # タスクロールの例(S3とDynamoDBを使うアプリケーション用) aws iam create-role --role-name myapp-task-role --assume-role-policy-document '{ "Version": "2012-10-17", "Statement": [{ "Effect": "Allow", "Principal": {"Service": "ecs-tasks.amazonaws.com"}, "Action": "sts:AssumeRole" }] }'

タスクロールは最小権限の原則で設計してください。S3のPUTだけが必要ならPutObjectのみを許可し、バケット全体への全権限は付けません。アプリケーションが侵害された場合の被害範囲を最小化できます。

本番でよくあるトラブルシュート

タスクが起動直後にSTOPPEDになる

ECSサービスでタスクが起動してもすぐにSTOPPEDになる場合、原因の大半は以下の3つです。

・ECRへのアクセス権限不足(実行ロールの権限漏れ)
・コンテナの起動コマンドが即時終了している(プロセスがフォアグラウンドで起動していない)
・SecretsManagerからシークレットが取得できない

停止理由はコンソールまたはCLIで確認できます。

# 停止したタスクの停止理由を確認する aws ecs describe-tasks --cluster myapp-cluster --tasks arn:aws:ecs:ap-northeast-1:123456789012:task/myapp-cluster/a1b2c3d4 --query 'tasks[0].{status:lastStatus,stopCode:stopCode,reason:stoppedReason}' # 出力例(実行ロールの権限不足の場合) { "status": "STOPPED", "stopCode": "TaskFailedToStart", "reason": "CannotPullContainerError: pull image manifest has been retried 5 time(s): ..." } # CloudWatch Logsでコンテナのエラーログを確認する aws logs get-log-events --log-group-name /ecs/myapp --log-stream-name ecs/myapp/a1b2c3d4 --limit 50

ALBのヘルスチェックが通らない

ECSサービスとALBを連携させた際に、タスクが起動してもすぐにDRAININGになる場合は、ALBのヘルスチェックが失敗しています。

よくある原因と確認コマンドは次のとおりです。

・セキュリティグループでALBからコンテナポートへのアクセスが許可されていない
・ヘルスチェックパスが間違っている(/health が404を返している)
・コンテナのアプリが起動完了前にヘルスチェックが来てタイムアウトしている

# ターゲットグループのヘルスチェック状態を確認する aws elbv2 describe-target-health --target-group-arn arn:aws:elasticloadbalancing:ap-northeast-1:123456789012:targetgroup/myapp-tg/abc123 --query 'TargetHealthDescriptions[*].{id:Target.Id,port:Target.Port,state:TargetHealth.State,reason:TargetHealth.Reason}' # 出力例(unhealthyの場合) [ { "id": "10.0.1.45", "port": 8080, "state": "unhealthy", "reason": "Target.ResponseCodeMismatch" } ]

Linuxのポート疎通確認の詳細はLinuxのポート確認コマンド(ss・lsof)が参考になります。コンテナが期待するポートで待ち受けているかを確認する際にも同じ考え方が使えます。

セキュリティグループの設定では、ALBのセキュリティグループをソースとして、コンテナポートへのインバウンドを許可する設定が正しい構成です。0.0.0.0/0を許可する設定は本番環境では避けてください。

本記事のまとめ

AWS ECS・Fargateを使ったコンテナ本番環境の設計手順をまとめます。
設計項目 ポイント
起動タイプの選定 新規構築はFargate一択。EC2管理が不要でコスト最適化しやすい
タスク定義のCPU・メモリ 小さく始めてCloudWatchで監視しながら調整する
シークレット管理 機密情報はSecretsManagerのARN参照。環境変数への平文埋め込みは禁止
ログ設定 awslogsドライバーでCloudWatch Logsへ転送。保持期間を必ず設定する
マルチAZ分散 サブネットを複数AZに配置しdesired-countを2以上にする
Auto Scaling CPU使用率70%でターゲットトラッキング。min=2、スケールインは慎重に
IAMロール 実行ロール(起動時の権限)とタスクロール(アプリの権限)を分離する

ECS・Fargateの設計はVPC設計と密接に連動しています。
プライベートサブネット・NATゲートウェイ・セキュリティグループの設計と組み合わせることで、より堅牢な本番環境が完成します。

AWSのインフラ設計をLinuxエンジニアとして体系的に学びたい方は、
AWSをLinuxエンジニアが学ぶためのロードマップもご覧ください。

マルチAZを含む冗長設計の実践については、
AWSの冗長設計を体系的に学ぶ上級ガイドでさらに詳しく解説しています。

AWSのコンテナ設計を「実務の型」として身につけませんか?

ECSやFargateの設定方法は調べれば分かります。でも「なぜその構成を選ぶのか」を説明できますか?
現場で通用する安全なLinuxサーバー構築の「型」を体系的に身につけたい方へ、『Linuxサーバー構築入門マニュアル(図解60P)』を完全無料でプレゼントしています。

「独学の時間がもったいない」「プロから直接、現場の技術を最短で学びたい」という本気の方には、2日で実務レベルのスキルが身につく【初心者向けハンズオンセミナー】も開催しています。

無料メルマガで学習を続ける

Linuxの実践スキルをメールで毎週お届け。
登録は1分、解除もいつでも可。

登録無料・いつでも解除できます

暗記不要・1時間後にはサーバーが動く

3,100名以上が実践した「型」を無料で公開中

プロのエンジニアはコマンドを暗記していません。
「現場で使える型」を効率よく使いこなしているだけです。
その「型」を図解60Pにまとめた入門マニュアルを、完全無料でプレゼントしています。

登録10秒/合わなければ解除3秒 / 詳細はこちら

Linux無料マニュアル(図解60P) 名前とメールで30秒登録
宮崎 智広

この記事を書いた人

宮崎 智広(みやざき ともひろ)

株式会社イーネットマーキュリー代表。現役のLinuxサーバー管理者として20年以上の実務経験を持ち、これまでに累計3,100名以上のエンジニアを指導してきたLinux教育のプロフェッショナル。「現場で本当に使える技術」を体系的に伝えることをモットーに、実践型のLinuxセミナーの開催や無料マニュアルの配布を通じてLinux人材の育成に取り組んでいる。

趣味は、キャンプにカメラ、トラウト釣り。好きな食べ物は、ラーメンにお酒。休肝日が作れない、酒量を減らせないのが悩み。最近、ドラマ「フライトエンジェル」を観て涙腺が崩壊しました。