AWSでDockerを使う方法(ECSとEKSの違い)

コンテナ技術の普及に伴い、AWSではDockerコンテナを実行するための複数のサービスが提供されています。特に主要なサービスである「Amazon ECS(Elastic Container Service)」と「Amazon EKS(Elastic Kubernetes Service)」は、多くの開発者やインフラエンジニアが選択を迷うポイントです。この記事では、AWSでDockerを効率的に運用するための方法と、ECSとEKSの違いについて詳しく解説します。

AWSにおけるコンテナサービスの概要

AWSではDockerコンテナを実行するために主に以下のサービスが提供されています:

  • Amazon ECS (Elastic Container Service) – AWSのネイティブコンテナオーケストレーションサービス
  • Amazon EKS (Elastic Kubernetes Service) – マネージドKubernetesサービス
  • AWS Fargate – サーバーレスコンテナ実行環境(ECSとEKSの両方で利用可能)
  • Amazon ECR (Elastic Container Registry) – Dockerイメージを保存するプライベートリポジトリ

それでは、主要なサービスであるECSとEKSについて、詳細を見ていきましょう。

Amazon ECS (Elastic Container Service)

ECSの基本

Amazon ECSはAWSが独自に開発したコンテナオーケストレーションサービスです。シンプルな構成でコンテナを実行でき、他のAWSサービスとの統合も優れています。

ECSの主要コンポーネント

  1. クラスター: コンテナを実行するサーバーの論理的なグループ
  2. タスク定義: アプリケーションを構成するコンテナの設計図(Dockerイメージ、CPU/メモリ制限、ネットワーク設定など)
  3. タスク: タスク定義のインスタンス。実際に実行されるコンテナの集合
  4. サービス: タスクの実行と管理を行う高レベルの機能(自動スケーリング、ロードバランシング、更新戦略など)

ECSの実行タイプ

ECSには主に2つの実行タイプがあります:

  1. EC2起動タイプ: 自分で管理するEC2インスタンス上でコンテナを実行
    • 高いカスタマイズ性
    • インスタンスの選択や設定を自由に行える
    • 容量管理が必要
  2. Fargate起動タイプ: サーバーレスでコンテナを実行
    • インフラ管理が不要
    • コンテナごとに正確なリソース割り当て
    • 必要な時に必要なだけ実行できる

ECSの利用例

# ECSクラスターの作成
aws ecs create-cluster --cluster-name my-cluster

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

# サービスの作成
aws ecs create-service \
  --cluster my-cluster \
  --service-name my-service \
  --task-definition my-task:1 \
  --desired-count 3 \
  --launch-type FARGATE \
  --network-configuration "awsvpcConfiguration={subnets=[subnet-12345678],securityGroups=[sg-12345678],assignPublicIp=ENABLED}"

Amazon EKS (Elastic Kubernetes Service)

EKSの基本

Amazon EKSは、AWSが提供するマネージドKubernetesサービスです。Kubernetesはオープンソースのコンテナオーケストレーションプラットフォームで、複雑なマイクロサービスアーキテクチャの管理に適しています。

EKSの主要コンポーネント

  1. コントロールプレーン: Kubernetesのマスターノードを管理(AWSが管理)
  2. ワーカーノード: アプリケーションコンテナを実行するEC2インスタンス
  3. ポッド: Kubernetesの最小デプロイ単位(1つ以上のコンテナ)
  4. デプロイメント: ポッドのレプリカセットを管理
  5. サービス: ポッドへのネットワークアクセスを提供

EKSの実行タイプ

EKSもECSと同様に2つの実行タイプをサポートしています:

  1. マネージドノードグループ: AWSが管理するEC2インスタンス
    • 自動スケーリングのサポート
    • インスタンスの更新と管理を自動化
  2. Fargate: サーバーレスでKubernetesポッドを実行
    • ノード管理が不要
    • ポッドレベルでの分離
    • スケジューリングの簡素化

EKSの利用例

# EKSクラスターの作成
eksctl create cluster \
  --name my-cluster \
  --version 1.24 \
  --region ap-northeast-1 \
  --nodegroup-name standard-workers \
  --node-type t3.medium \
  --nodes 3 \
  --nodes-min 1 \
  --nodes-max 4

# アプリケーションのデプロイ
kubectl apply -f deployment.yaml

# サービスの公開
kubectl apply -f service.yaml

ECSとEKSの詳細比較

1. 学習曲線と複雑性

ECS:

  • AWSネイティブのサービス
  • シンプルな概念と管理インターフェース
  • 他のAWSサービスとの統合が容易
  • 初心者にも比較的取り組みやすい

EKS:

  • Kubernetesの知識が必要
  • 概念や用語が多い
  • 高度なカスタマイズが可能だが、学習コストが高い
  • クラウド間の移行やハイブリッド環境に適している

2. スケーラビリティとパフォーマンス

ECS:

  • AWSのオートスケーリング機能を活用
  • 比較的シンプルなスケーリング設定
  • 高速なデプロイと起動時間

EKS:

  • 高度なスケーリング機能(Horizontal Pod Autoscaler, Cluster Autoscaler)
  • 大規模なクラスターと複雑なワークロードに対応
  • リソースクォータと優先度ベースのスケジューリング

3. 料金体系

ECS:

  • EC2起動タイプ: 使用するEC2インスタンスの料金のみ
  • Fargate: CPUとメモリの使用量に応じた料金

EKS:

  • クラスター管理費用: $0.10/時間(約$73/月)
  • EC2起動タイプ: 使用するEC2インスタンスの料金
  • Fargate: CPUとメモリの使用量に応じた料金

4. 機能比較表

機能ECSEKS
マネージメントレベル高(AWSが管理)中(コントロールプレーンのみAWSが管理)
オーケストレーションAWSネイティブKubernetes
カスタマイズ性中程度非常に高い
オープンソース×
ベンダーロックイン
移植性
モニタリングCloudWatch統合CloudWatchとKubernetes標準ツール
対応サービスALB, NLBALB, NLB, Ingress Controller

どちらを選ぶべきか?

ECSが適している場合

  • AWS環境のみで運用する場合: 他のAWSサービスとの統合が重要
  • シンプルなアプリケーション: 少数のコンテナで構成される比較的シンプルなアーキテクチャ
  • 学習リソースが限られている: すぐに始めたいチームやKubernetesの知識がないチーム
  • 管理オーバーヘッドを最小限にしたい: インフラの細かい制御よりも運用の簡素化を優先

EKSが適している場合

  • マルチクラウド戦略: AWSだけでなく他のクラウドプロバイダーやオンプレミスとの連携
  • 複雑なマイクロサービス: 多数のサービスと複雑な依存関係を持つアプリケーション
  • 既存のKubernetes知識: チームがすでにKubernetesを理解している
  • 高度なオーケストレーション: 詳細なリソース制御やスケジューリングが必要

AWS上でのコンテナデプロイのベストプラクティス

どちらのサービスを選んだ場合でも、以下のベストプラクティスは共通して適用できます:

  1. コンテナイメージの最適化
    • 軽量なベースイメージを使用(Alpine Linuxなど)
    • マルチステージビルドでイメージサイズを削減
    • 脆弱性スキャンを導入
  2. セキュリティの確保
    • IAMロールを適切に設定
    • コンテナの権限を最小限に
    • シークレット管理にAWS Secrets Managerを使用
  3. 監視とロギング
    • CloudWatchとの統合
    • X-Ray for トレース
    • Prometheusなどのオープンソースツールの活用(特にEKS)
  4. CI/CD統合
    • AWS CodePipelineの活用
    • GitHubActionやJenkinsとの連携
    • 自動テストとデプロイ

実装例: AWSでDockerを使ったシンプルなウェブアプリ

ECSでのデプロイ例(Terraformを使用)

# ECSクラスターの定義
resource "aws_ecs_cluster" "main" {
  name = "web-app-cluster"
}

# タスク定義
resource "aws_ecs_task_definition" "app" {
  family                   = "web-app"
  network_mode             = "awsvpc"
  requires_compatibilities = ["FARGATE"]
  cpu                      = 256
  memory                   = 512
  execution_role_arn       = aws_iam_role.ecs_execution_role.arn
  task_role_arn            = aws_iam_role.ecs_task_role.arn

  container_definitions = jsonencode([{
    name      = "web-app"
    image     = "${aws_ecr_repository.app.repository_url}:latest"
    essential = true
    portMappings = [{
      containerPort = 80
      hostPort      = 80
    }]
    logConfiguration = {
      logDriver = "awslogs"
      options = {
        "awslogs-group"         = "/ecs/web-app"
        "awslogs-region"        = "ap-northeast-1"
        "awslogs-stream-prefix" = "ecs"
      }
    }
  }])
}

# ECSサービス
resource "aws_ecs_service" "main" {
  name            = "web-app-service"
  cluster         = aws_ecs_cluster.main.id
  task_definition = aws_ecs_task_definition.app.arn
  desired_count   = 3
  launch_type     = "FARGATE"

  network_configuration {
    subnets         = aws_subnet.private.*.id
    security_groups = [aws_security_group.app.id]
  }

  load_balancer {
    target_group_arn = aws_lb_target_group.app.arn
    container_name   = "web-app"
    container_port   = 80
  }

  depends_on = [aws_lb_listener.front_end]
}

EKSでのデプロイ例(YAML定義)

# Deployment定義
apiVersion: apps/v1
kind: Deployment
metadata:
  name: web-app
spec:
  replicas: 3
  selector:
    matchLabels:
      app: web-app
  template:
    metadata:
      labels:
        app: web-app
    spec:
      containers:
      - name: web-app
        image: [ACCOUNT_ID].dkr.ecr.ap-northeast-1.amazonaws.com/web-app:latest
        ports:
        - containerPort: 80
        resources:
          limits:
            cpu: "0.5"
            memory: "512Mi"
          requests:
            cpu: "0.2"
            memory: "256Mi"
        livenessProbe:
          httpGet:
            path: /health
            port: 80
          initialDelaySeconds: 30
          periodSeconds: 10

---
# Service定義
apiVersion: v1
kind: Service
metadata:
  name: web-app-service
spec:
  selector:
    app: web-app
  ports:
  - port: 80
    targetPort: 80
  type: LoadBalancer

まとめ

AWSでDockerを使用する際、ECSとEKSはそれぞれ異なる特性と利点を持っています。

  • ECSはAWSネイティブのサービスで、シンプルさと他のAWSサービスとの統合の容易さが特徴です。小規模から中規模のアプリケーションや、AWSエコシステム内で完結するワークロードに適しています。
  • EKSはKubernetesの標準に準拠したマネージドサービスで、高度なカスタマイズや複雑なオーケストレーション、クラウド間の移植性を提供します。大規模なマイクロサービスアーキテクチャやマルチクラウド戦略に適しています。

どちらを選択するかは、チームのスキルセット、アプリケーションの要件、将来的な成長計画などを考慮して決定するべきです。また、どちらのサービスもAWS Fargateと組み合わせることで、サーバーレスコンテナ実行環境としても利用できることを覚えておきましょう。

最終的には、ビジネス要件と技術的な制約を慎重に評価し、組織に最適なソリューションを選択することが重要です。

コメント

タイトルとURLをコピーしました