🐳 ECS vs EKS、どちらを選ぶべきか? — AWSコンテナオーケストレーション完全比較

“コンテナは起動したけど、どうやって管理すればいいんだろう?”

— AWSを初めて使う開発者なら誰もが抱える悩み

🎯 この記事で扱うこと

  • ECSとEKSの主要な概念とアーキテクチャの違い
  • 各サービスの長所、短所、およびコスト構造
  • 実際のインフラ構成例コード (タスク定義、Helmチャート)
  • チーム規模・ワークロード別の選択基準
  • 移行時に考慮すべき落とし穴

📌 はじめに / 背景

コンテナ技術が普及するにつれて、「複数のコンテナをいかに安定して運用するか」という問いが生まれました。1つのサーバーにDockerだけをインストールして使うのは開発環境でしか通用しない話であり、実際のプロダクションではオーケストレーション — つまり、コンテナのデプロイ、スケーリング、障害復旧を自動的に処理するツールが必要になります。

AWSでは、この役割を主に2つのサービスが担っています。

  • 🟠 Amazon ECS (Elastic Container Service): AWSが独自に開発したコンテナオーケストレーター
  • 🔵 Amazon EKS (Elastic Kubernetes Service): オープンソースのKubernetesをAWSがマネージドサービスとして提供

両サービスともに「コンテナをクラスター上で実行する」という目的は同じですが、その哲学と運用方法は全く異なります。この記事では、その違いを徹底的に掘り下げていきます。


🔍 ECSとは? — AWSの独自ソリューション

主要な構造

ECSはAWSが独自に開発したコンテナプラットフォームです。Kubernetesを全く知らなくても利用できるように設計されており、AWSコンソールだけでほとんどの作業が可能です。

ECSの主要な構成要素は以下の通りです:

構成要素 説明
タスク定義 (Task Definition) コンテナ実行の仕様書。イメージ、CPU/メモリ、環境変数などを定義
タスク (Task) タスク定義に基づいて実際に実行されたコンテナインスタンス
サービス (Service) 指定された数のタスクを維持し、自動復旧/スケーリングを担当
クラスター (Cluster) タスクとサービスが実行される論理的な分離単位

2つの実行モード

ECSは、コンテナがどこで実行されるかによって2つのモードをサポートしています。

1️⃣ EC2モード: EC2インスタンスを直接プロビジョニングし、その上でコンテナを実行します。ノード管理の責任はユーザーにあります。

2️⃣ Fargateモード: サーバーレス。EC2をプロビジョニングする必要なく、コンテナを定義するだけでAWSが自動的に実行します。最もECSらしい使い方です。

ECSタスク定義の例

{
  "family": "web-app",
  "networkMode": "awsvpc",
  "requiresCompatibilities": ["FARGATE"],
  "cpu": "512",
  "memory": "1024",
  "containerDefinitions": [
    {
      "name": "web",
      "image": "123456789.dkr.ecr.ap-northeast-2.amazonaws.com/web:latest",
      "portMappings": [
        {
          "containerPort": 80,
          "protocol": "tcp"
        }
      ],
      "environment": [
        {
          "name": "APP_ENV",
          "value": "production"
        }
      ],
      "logConfiguration": {
        "logDriver": "awslogs",
        "options": {
          "awslogs-group": "/ecs/web-app",
          "awslogs-region": "ap-northeast-2",
          "awslogs-stream-prefix": "ecs"
        }
      }
    }
  ]
}

💡 awsvpcネットワークモードを使用すると、各タスクにENI (Elastic Network Interface) が割り当てられ、VPC内で独立したIPを持つことができます。セキュリティグループをタスク単位で適用できるため、セキュリティ面で有利です。


🔍 EKSとは? — AWS上のKubernetes

Kubernetesはなぜこんなに有名なのか?

Kubernetes (K8s) は、Googleの内部システムBorgから着想を得て作られたオープンソースのオーケストレーターです。2014年にオープンソースとして公開されて以来、現在はCNCF (Cloud Native Computing Foundation) が管理しており、クラウドネイティブの事実上の標準となっています。

EKSは、このKubernetesをAWSがマネージドサービスとして提供するものです。コントロールプレーン (マスターノード) はAWSが管理し、ワーカーノード (EC2またはFargate) はユーザーが運用します。

EKS主要構成要素

K8sリソース 役割
Pod コンテナの最小実行単位 (1つ以上のコンテナのまとまり)
Deployment Podの宣言的なデプロイと更新管理
Service Podに安定したネットワークエンドポイントを提供
Namespace クラスター内の論理的な分離単位
ConfigMap / Secret 設定値および機密情報を分離して管理
HPA 負荷に応じたPodの自動水平スケーリング

EKSデプロイメントの例

# deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: web-app
  namespace: production
spec:
  replicas: 3  # 3つのPodを維持
  selector:
    matchLabels:
      app: web
  template:
    metadata:
      labels:
        app: web
    spec:
      containers:
        - name: web
          image: 123456789.dkr.ecr.ap-northeast-2.amazonaws.com/web:latest
          ports:
            - containerPort: 80
          resources:
            requests:
              cpu: "250m"      # 0.25 vCPU
              memory: "256Mi"
            limits:
              cpu: "500m"
              memory: "512Mi"
          env:
            - name: APP_ENV
              value: "production"
---
# service.yaml
apiVersion: v1
kind: Service
metadata:
  name: web-service
  namespace: production
spec:
  selector:
    app: web
  ports:
    - port: 80
      targetPort: 80
  type: ClusterIP

HPA (水平Podオートスケーリング) 設定

apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
  name: web-hpa
  namespace: production
spec:
  scaleTargetRef:
    apiVersion: apps/v1
    kind: Deployment
    name: web-app
  minReplicas: 2
  maxReplicas: 10
  metrics:
    - type: Resource
      resource:
        name: cpu
        target:
          type: Utilization
          averageUtilization: 70  # CPUが70%を超えたらスケールアウト

⚖️ ECS vs EKS 主要比較

項目 ECS EKS
学習難易度 ⭐⭐ (低い) ⭐⭐⭐⭐ (高い)
AWS依存性 強い (AWS専用) 低い (マルチクラウド可能)
コントロールプレーン費用 無料 約 $0.10/時間 (月額約 $72)
エコシステム AWSサービス中心 CNCFオープンソースエコシステム
カスタマイズ 限定的 非常に柔軟
運用複雑度 低い 高い
Fargateサポート 完全サポート 限定的サポート
マルチクラウド
サービスメッシュ App Mesh連携 Istio、Linkerdなど自由に選択
RBAC IAMベース (単純) K8s RBAC + IAM (きめ細かい)

💡 どちらを選ぶべきか? — 実践的な選択基準

ECSが適している場合 ✅

  • AWSエコシステムを主に利用するチーム: ELB、CloudWatch、IAMと自然に統合されます。
  • 小規模チームまたはスタートアップ: Kubernetes運用専任者がいない場合。
  • 迅速なリリースが優先事項: 学習曲線なしにすぐにコンテナをデプロイしたい場合。
  • サーバーレス志向のアーキテクチャ: Fargateと組み合わせてインフラ管理を最小限に抑えたい場合。
  • AWSのみで運用: 他のクラウドへの移行計画がない場合。

EKSが適している場合 ✅

  • マルチクラウドまたはハイブリッド戦略: GKE、AKSと同じ方法で運用したい場合。
  • 複雑なマイクロサービス: 数十〜数百のサービスをきめ細かく管理する必要がある場合。
  • DevOps/SRE専任チームを保有: Kubernetesを運用する専門人材がいる場合。
  • オープンソースエコシステムの活用: Istio、ArgoCD、Prometheus、Grafanaなどを積極的に活用したい場合。
  • きめ細かいリソース管理: Pod単位のCPU/メモリ要求量と制限を精密にチューニングする必要がある場合。

💰 コスト構造を理解する

ECSの費用

ECS自体のコントロールプレーンは無料です。費用は実行するインフラから発生します。

  • EC2モード: 使用するEC2インスタンスの費用
  • Fargateモード: vCPUおよびメモリ使用量に応じて秒単位で課金
Fargate 요금 예시 (서울 리전 기준):
- vCPU: $0.04048 / vCPU-hour
- Memory: $0.004445 / GB-hour

0.5 vCPU + 1GB 메모리 Task를 한 달 실행 시:
약 $0.04048 × 0.5 × 720 + $0.004445 × 1 × 720
= $14.57 + $3.20 ≈ 월 $17.77

EKSの費用

EKSはコントロールプレーン費用が別途発生します。

EKS 클러스터 기본 요금:
- Control Plane: $0.10/시간 = 약 월 $72

+ 워커 노드(EC2 또는 Fargate) 비용
+ 로드밸런서, NAT Gateway 등 부가 인프라 비용

⚠️ 小規模サービスの場合、EKSのコントロールプレーン費用 (月額$72) は負担になる可能性があります。一方、大規模サービスでは、この金額はインフラ全体の費用のごく一部となります。


💻 実践的なデプロイフロー比較

ECS + Fargateデプロイ (AWS CLI)

# 1. ECRにイメージをプッシュ
aws ecr get-login-password --region ap-northeast-2 | 
  docker login --username AWS --password-stdin 
  123456789.dkr.ecr.ap-northeast-2.amazonaws.com

docker build -t web-app .
docker tag web-app:latest 123456789.dkr.ecr.ap-northeast-2.amazonaws.com/web-app:latest
docker push 123456789.dkr.ecr.ap-northeast-2.amazonaws.com/web-app:latest

# 2. タスク定義を登録
aws ecs register-task-definition 
  --cli-input-json file://task-definition.json

# 3. サービスを作成 (Fargate)
aws ecs create-service 
  --cluster my-cluster 
  --service-name web-service 
  --task-definition web-app:1 
  --desired-count 2 
  --launch-type FARGATE 
  --network-configuration "awsvpcConfiguration={subnets=[subnet-xxx],securityGroups=[sg-xxx],assignPublicIp=ENABLED}"

EKSデプロイ (kubectl)

# 1. kubeconfigを設定
aws eks update-kubeconfig 
  --region ap-northeast-2 
  --name my-eks-cluster

# 2. ECRイメージをプッシュ (ECSと同じ)

# 3. K8sリソースをデプロイ
kubectl apply -f deployment.yaml
kubectl apply -f service.yaml

# 4. デプロイ状態を確認
kubectl rollout status deployment/web-app -n production

# 5. Podリストを確認
kubectl get pods -n production -o wide

⚠️ 注意事項 / よくある間違い

ECSでよくある間違い

1. タスクロールと実行ロールの混同 🚨

Task Execution Role: ECS가 ECR에서 이미지를 pull하고 CloudWatch에 로그를 쓰는 권한
Task Role:          컨테이너 내 애플리케이션이 AWS API를 호출하는 권한

둘 다 필요하지만 목적이 다릅니다!

2. FargateのEFSマウント未設定: ステートフル (Stateful) アプリケーションをFargateにデプロイする際に永続ストレージなしでデプロイするとデータが失われます。

3. サービスディスカバリ (Service Discovery) 未設定: マイクロサービス間の通信でハードコードされたIPを使用していると、タスクが再起動した際に接続が切断されます。AWS Cloud MapまたはService Connectを使用してください。

EKSでよくある間違い

1. リソースリクエスト/リミット未設定 🚨

# ❌ これによりノードリソースを無制限に使用可能
containers:
  - name: web
    image: my-app:latest

# ✅ 必ず明記
containers:
  - name: web
    image: my-app:latest
    resources:
      requests:
        cpu: "100m"
        memory: "128Mi"
      limits:
        cpu: "500m"
        memory: "512Mi"

2. IRSA (IAM Roles for Service Accounts) 未適用: PodからAWSサービスを利用する際にノードのIAMロールをそのまま使用すると、最小権限の原則に違反します。IRSAでPodごとに独立した権限を付与してください。

3. etcd暗号化未設定: SecretリソースはデフォルトでetcdにBase64エンコード (暗号化ではありません!) で保存されます。EKSクラスター作成時にEnvelope Encryptionを有効にする必要があります。


✅ まとめ / 終わりに

ECSとEKS、結局「どちらが良い」ではなく、「私たちのチームにどちらが合っているか」の問題です。

状況 推奨
AWSに特化、小規模チーム、迅速なリリース ECS + Fargate
マルチクラウド、大規模マイクロサービス EKS
Kubernetes学習目的 EKS (実務スキルに繋がる)
運用負担の最小化 ECS + Fargate

実際の現場では、両サービスを併用するケースも少なくありません。例えば、単純なバッチ処理はECSで、複雑なマイクロサービス群はEKSで運用するといった形です。

次のステップとしては、Terraformを活用したEKSクラスターの自動化ArgoCDを利用したGitOpsデプロイKarpenterによるノードオートスケーリングなどを学習してみることをお勧めします。🚀



Comments

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です