はじめに

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 --> IGW

VPCエンドポイント設定の推奨

エンドポイント 種類 用途
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でメトリクスを分析し、リソースサイジングを最適化する

コンテナアーキテクチャは、プロジェクトの成長に合わせて進化させることが重要です。最初から複雑な構成を目指すのではなく、要件に応じて段階的に設計を洗練させていきましょう。

参考リンク