はじめに
AWSでコンテナワークロードを構築する際、サービスの選択と設計パターンの理解は成功の鍵を握ります。ECS、Fargate、App Runner、EKSといった選択肢がある中で、プロジェクト要件に最適なサービスを選び、適切なアーキテクチャパターンを適用することが重要です。
本記事では、AWSコンテナサービスの選択基準を明確化し、実際のユースケースに応じた設計パターンとベストプラクティスを解説します。この記事を読むことで、以下のことが理解できるようになります。
- ワークロード特性に基づいたサービス選択の判断基準
- マイクロサービス、バッチ処理、イベント駆動など代表的な設計パターン
- 本番環境を見据えたアーキテクチャ設計のベストプラクティス
- コスト最適化とセキュリティを両立する設計指針
サービス選択の判断フレームワーク
選択を左右する4つの軸
AWSコンテナサービスを選択する際、以下の4つの軸で要件を整理することが有効です。
quadrantChart
title サービス選択の判断軸
x-axis 運用負荷を許容 --> 運用負荷を最小化
y-axis カスタマイズ性重視 --> シンプルさ重視
quadrant-1 App Runner
quadrant-2 ECS on Fargate
quadrant-3 ECS on EC2
quadrant-4 EKS| 判断軸 | 検討項目 |
|---|---|
| 運用負荷 | インフラ管理にリソースを割けるか、サーバーレスを優先するか |
| カスタマイズ性 | 細かな制御が必要か、抽象化されたサービスで十分か |
| チームスキル | Kubernetes経験があるか、AWS固有サービスで進めるか |
| コスト感度 | 初期コストを抑えたいか、長期的な最適化を優先するか |
ワークロード別サービス選択マトリクス
ワークロードの特性に応じた推奨サービスを以下にまとめます。
| ワークロード | 推奨サービス | 選定理由 |
|---|---|---|
| シンプルなWebアプリ | App Runner | インフラ設定不要で即座にデプロイ可能 |
| マイクロサービス | ECS on Fargate | サービス間通信の制御とスケーラビリティ |
| バッチ処理 | ECS on Fargate(スタンドアロンタスク) | タスク単位での従量課金、完了後に自動終了 |
| GPU/機械学習 | ECS on EC2 | GPUインスタンスの利用が必須 |
| 大規模分散システム | EKS | Kubernetesエコシステムの活用 |
| マルチクラウド | EKS | Kubernetes互換性による移植性 |
意思決定フローチャート
サービス選択を体系的に判断するためのフローチャートを示します。
flowchart TD
Start([コンテナワークロード]) --> Q1{Kubernetesの<br/>経験・要件あり?}
Q1 -->|Yes| EKS[Amazon EKS]
Q1 -->|No| Q2{インフラ管理を<br/>最小化したい?}
Q2 -->|No| Q3{GPUや特殊な<br/>インスタンスが必要?}
Q3 -->|Yes| EC2[ECS on EC2]
Q3 -->|No| Q4{コスト最適化を<br/>優先したい?}
Q4 -->|Yes| EC2
Q4 -->|No| Fargate[ECS on Fargate]
Q2 -->|Yes| Q5{シンプルなWebアプリ/<br/>APIのみ?}
Q5 -->|Yes| AppRunner[App Runner]
Q5 -->|No| Q6{細かなネットワーク<br/>制御が必要?}
Q6 -->|Yes| Fargate
Q6 -->|No| AppRunner代表的な設計パターン
パターン1: 単一サービス構成(モノリス)
最もシンプルな構成で、1つのコンテナでアプリケーション全体を実行します。
flowchart LR
subgraph Internet["インターネット"]
User((ユーザー))
end
subgraph AWS["AWS"]
ALB["Application<br/>Load Balancer"]
subgraph ECS["ECS Service"]
Task1["タスク<br/>Web + API + 業務ロジック"]
Task2["タスク<br/>Web + API + 業務ロジック"]
end
RDS[(Amazon RDS)]
end
User --> ALB
ALB --> Task1
ALB --> Task2
Task1 --> RDS
Task2 --> RDS適用場面
- 小〜中規模のアプリケーション
- 開発初期のプロトタイプ
- チームが小さく、シンプルな運用を優先する場合
設計ポイント
| 項目 | 推奨設定 |
|---|---|
| サービス数 | 1つ |
| タスク数 | 2以上(可用性確保) |
| スケーリング | CPU/メモリ使用率ベース |
| デプロイ | ローリングアップデート |
パターン2: マイクロサービス構成
機能ごとに独立したサービスに分割し、それぞれを個別にデプロイ・スケールします。
flowchart TB
subgraph Internet["インターネット"]
User((ユーザー))
end
subgraph AWS["AWS"]
ALB["Application<br/>Load Balancer"]
subgraph ECS["ECS Cluster"]
subgraph Frontend["Frontend Service"]
FE1["Web UI"]
FE2["Web UI"]
end
subgraph UserService["User Service"]
US1["User API"]
end
subgraph OrderService["Order Service"]
OS1["Order API"]
OS2["Order API"]
end
subgraph ProductService["Product Service"]
PS1["Product API"]
end
end
subgraph Data["データ層"]
UserDB[(User DB)]
OrderDB[(Order DB)]
ProductDB[(Product DB)]
end
end
User --> ALB
ALB --> FE1 & FE2
FE1 & FE2 --> US1
FE1 & FE2 --> OS1 & OS2
FE1 & FE2 --> PS1
US1 --> UserDB
OS1 & OS2 --> OrderDB
PS1 --> ProductDB適用場面
- 大規模なシステムで、機能ごとに異なるスケーリング要件がある
- 複数チームが並行して開発・デプロイを行う
- 障害の影響範囲を局所化したい
設計ポイント
| 項目 | 推奨設定 |
|---|---|
| サービス間通信 | 内部ALBまたはService Connect |
| サービスディスカバリ | Cloud Map(AWS Service Discovery) |
| データベース | サービスごとに分離(Database per Service) |
| 認証・認可 | API Gatewayまたはサービスメッシュ |
パターン3: イベント駆動構成
サービス間を非同期メッセージングで接続し、疎結合なアーキテクチャを実現します。
flowchart LR
subgraph Producers["プロデューサー"]
API["API Service"]
end
subgraph Messaging["メッセージング"]
SQS["Amazon SQS"]
SNS["Amazon SNS"]
end
subgraph Consumers["コンシューマー"]
Worker1["Worker Service A"]
Worker2["Worker Service B"]
Worker3["Worker Service C"]
end
subgraph Storage["ストレージ"]
S3[(S3)]
DynamoDB[(DynamoDB)]
end
API --> SNS
SNS --> SQS
SQS --> Worker1
SQS --> Worker2
SNS --> Worker3
Worker1 --> S3
Worker2 --> DynamoDB
Worker3 --> DynamoDB適用場面
- 処理時間が長いタスクをバックグラウンドで実行
- サービス間の依存を減らし、障害耐性を高めたい
- スパイク的なリクエストを平準化したい
設計ポイント
| 項目 | 推奨設定 |
|---|---|
| メッセージキュー | SQS(標準キューまたはFIFO) |
| ファンアウト | SNS + SQSの組み合わせ |
| デッドレターキュー | 必須(再処理のため) |
| スケーリング | キューの深さに基づくターゲット追跡 |
パターン4: バッチ処理構成
定期的または条件に基づいて起動するバッチワークロードの構成です。
flowchart TB
subgraph Trigger["トリガー"]
EventBridge["Amazon<br/>EventBridge"]
S3Event["S3イベント"]
end
subgraph Compute["コンピューティング"]
subgraph ECS["ECS Cluster"]
BatchTask["バッチタスク<br/>(スタンドアロン)"]
end
end
subgraph Storage["ストレージ"]
InputS3[(入力データ<br/>S3)]
OutputS3[(出力データ<br/>S3)]
RDS[(RDS)]
end
EventBridge -->|スケジュール実行| BatchTask
S3Event -->|ファイル到着| BatchTask
InputS3 --> BatchTask
BatchTask --> OutputS3
BatchTask --> RDS適用場面
- 日次・月次の集計処理
- ファイル到着をトリガーにしたETL処理
- 大量データの一括処理
設計ポイント
| 項目 | 推奨設定 |
|---|---|
| 起動方式 | EventBridge(スケジュール/イベント) |
| タスク種別 | スタンドアロンタスク(サービスではない) |
| タイムアウト | タスク定義でstopTimeoutを設定 |
| 重複実行防止 | EventBridgeのルールで冪等性を確保 |
パターン5: サイドカーパターン
メインコンテナの機能を補完するサイドカーコンテナを配置する構成です。
flowchart TB
subgraph Task["ECSタスク"]
subgraph Containers["コンテナ"]
App["アプリケーション<br/>コンテナ"]
Envoy["Envoyプロキシ<br/>(サイドカー)"]
FluentBit["Fluent Bit<br/>(サイドカー)"]
end
SharedVolume["共有ボリューム"]
end
subgraph External["外部サービス"]
OtherService["他サービス"]
CloudWatch["CloudWatch<br/>Logs"]
XRay["X-Ray"]
end
App <-->|ローカル通信| Envoy
Envoy <-->|mTLS| OtherService
App --> SharedVolume
FluentBit --> SharedVolume
FluentBit --> CloudWatch
Envoy --> XRayサイドカーの代表的な用途
| サイドカー | 用途 | 実装例 |
|---|---|---|
| プロキシ | サービスメッシュ、mTLS | Envoy、AWS App Mesh |
| ログ収集 | ログの転送と加工 | Fluent Bit、Firelens |
| モニタリング | メトリクス収集 | CloudWatch Agent、Datadog Agent |
| セキュリティ | シークレット注入 | Vault Agent |
設計ポイント
| 項目 | 推奨設定 |
|---|---|
| コンテナ間通信 | localhostまたは共有ボリューム |
| 依存関係 | dependsOnでサイドカーを先に起動 |
| ヘルスチェック | メインコンテナのみに設定 |
| リソース | サイドカー用のCPU/メモリを加算 |
アーキテクチャ設計のベストプラクティス
ネットワーク設計
本番環境でのコンテナワークロードには、セキュアなネットワーク構成が不可欠です。
推奨構成: プライベートサブネット + VPCエンドポイント
flowchart TB
subgraph VPC["VPC"]
IGW["Internet<br/>Gateway"]
subgraph Public["パブリックサブネット"]
ALB["ALB"]
NAT["NAT Gateway"]
end
subgraph Private["プライベートサブネット"]
ECS["ECSタスク"]
end
subgraph Endpoints["VPCエンドポイント"]
ECREndpoint["ECR Endpoint"]
LogsEndpoint["CloudWatch<br/>Logs Endpoint"]
S3Endpoint["S3 Gateway<br/>Endpoint"]
end
end
Internet((Internet)) --> IGW --> ALB --> ECS
ECS -.->|イメージ取得| ECREndpoint
ECS -.->|ログ送信| LogsEndpoint
ECS -.->|外部通信| NAT --> IGWVPCエンドポイント設定の推奨
| エンドポイント | 種類 | 用途 |
|---|---|---|
| com.amazonaws.region.ecr.api | Interface | ECR API呼び出し |
| com.amazonaws.region.ecr.dkr | Interface | イメージのプル |
| com.amazonaws.region.s3 | Gateway | ECRイメージレイヤー取得 |
| com.amazonaws.region.logs | Interface | CloudWatch Logsへの送信 |
| com.amazonaws.region.secretsmanager | Interface | シークレット取得 |
セキュリティ設計
コンテナワークロードのセキュリティは多層防御で実現します。
IAMロールの最小権限設計
flowchart TB
subgraph IAM["IAMロール"]
TaskExecRole["タスク実行ロール<br/>(ECS Agent用)"]
TaskRole["タスクロール<br/>(アプリケーション用)"]
end
subgraph Permissions["権限"]
ECRPull["ECRからのイメージ取得"]
SecretsRead["Secrets Manager読み取り"]
LogsWrite["CloudWatch Logs書き込み"]
S3Access["S3バケットアクセス"]
DDBAccess["DynamoDBアクセス"]
end
TaskExecRole --> ECRPull
TaskExecRole --> SecretsRead
TaskExecRole --> LogsWrite
TaskRole --> S3Access
TaskRole --> DDBAccess| ロール種別 | 設定対象 | 付与する権限 |
|---|---|---|
| タスク実行ロール | ECSエージェント | ECRプル、ログ書き込み、シークレット取得 |
| タスクロール | アプリケーション | 業務に必要なAWSリソースへのアクセスのみ |
セキュリティグループの設計原則
| 対象 | インバウンド | アウトバウンド |
|---|---|---|
| ALB | 0.0.0.0/0:443 | ECSセキュリティグループ:コンテナポート |
| ECSタスク | ALBセキュリティグループ:コンテナポート | VPCエンドポイント:443、NAT経由で外部 |
| RDS | ECSセキュリティグループ:3306/5432 | なし |
可用性設計
コンテナワークロードの可用性を高めるための設計ポイントです。
マルチAZ配置
flowchart TB
subgraph VPC["VPC"]
subgraph AZa["AZ-a"]
ALBa["ALB ENI"]
Taska["タスク"]
end
subgraph AZc["AZ-c"]
ALBc["ALB ENI"]
Taskc["タスク"]
end
subgraph AZd["AZ-d"]
ALBd["ALB ENI"]
Taskd["タスク"]
end
end
ALB["ALB"] --> ALBa & ALBc & ALBd
ALBa --> Taska
ALBc --> Taskc
ALBd --> Taskd可用性確保のチェックリスト
| 項目 | 推奨設定 |
|---|---|
| 最小タスク数 | 2以上(desiredCount) |
| AZ分散 | 2AZ以上にサブネットを配置 |
| ヘルスチェック | ALBのターゲットグループで設定 |
| デプロイ設定 | minimumHealthyPercent: 100、maximumPercent: 200 |
| 自動復旧 | ECSサービスによる自動タスク再起動 |
コスト最適化
コンテナワークロードのコストを最適化するための指針です。
起動タイプ別コスト特性
| 起動タイプ | コスト特性 | 最適化手法 |
|---|---|---|
| Fargate | 使用時間×リソース量 | 適切なサイジング、Savings Plans |
| Fargate Spot | 最大70%割引 | 中断耐性のあるワークロード |
| EC2 | インスタンス料金 | Reserved Instance、Spot |
| App Runner | リクエスト + プロビジョンドインスタンス | トラフィックが少ない場合に有利 |
コスト最適化のチェックリスト
| 項目 | 推奨アクション |
|---|---|
| リソースサイジング | Container Insightsでメトリクスを分析し、過剰なCPU/メモリを削減 |
| 自動スケーリング | ターゲット追跡ポリシーで需要に応じたスケーリング |
| Savings Plans | 予測可能なワークロードには Compute Savings Plans を適用 |
| Fargate Spot | バッチ処理や開発環境で活用 |
| ログ保持期間 | CloudWatch Logsの保持期間を適切に設定 |
設計パターン選択のまとめ
要件に応じた設計パターンの選択ガイドを以下にまとめます。
| 要件 | 推奨パターン | 推奨サービス |
|---|---|---|
| 小規模Webアプリを素早くデプロイ | 単一サービス | App Runner |
| 複数チームでの開発、独立したスケーリング | マイクロサービス | ECS on Fargate |
| 処理時間が長い非同期タスク | イベント駆動 | ECS + SQS |
| 定期的なデータ処理 | バッチ処理 | ECS(スタンドアロンタスク) |
| サービスメッシュ、高度な可観測性 | サイドカー | ECS + App Mesh |
| Kubernetes経験を活かしたい | マイクロサービス | EKS |
まとめ
AWSコンテナサービスの選択と設計パターンについて解説しました。重要なポイントを振り返ります。
サービス選択のポイント
- 運用負荷、カスタマイズ性、チームスキル、コスト感度の4軸で判断する
- シンプルなWebアプリにはApp Runner、本格的なワークロードにはECS on Fargateを検討する
- Kubernetes経験やマルチクラウド要件がある場合はEKSを選択する
設計パターンの適用
- 小規模から始める場合は単一サービス構成で十分
- 規模拡大に伴い、マイクロサービスやイベント駆動構成へ移行を検討する
- サイドカーパターンは可観測性やセキュリティの強化に有効
ベストプラクティス
- プライベートサブネット + VPCエンドポイントでセキュアなネットワークを構築する
- IAMロールは最小権限の原則に従い、タスク実行ロールとタスクロールを分離する
- マルチAZ配置と適切なヘルスチェックで高可用性を確保する
- Container Insightsでメトリクスを分析し、リソースサイジングを最適化する
コンテナアーキテクチャは、プロジェクトの成長に合わせて進化させることが重要です。最初から複雑な構成を目指すのではなく、要件に応じて段階的に設計を洗練させていきましょう。