0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

ECS on GPU EC2:ECSクラスターで動かすCUDAコンテナ基盤自動構築

Posted at

はじめに

本記事の目的

本記事では、Terraformを用いてAWS上にGPU搭載のEC2インスタンスを使ったECSクラスターを自動構築し、CUDA対応コンテナを簡単に動作させる基盤を作る方法を解説します。

特に、深層学習やGPGPUによる高負荷計算処理など、GPUリソースを必要とするユースケースにおいて、インフラの構築・運用を効率化することを目的としています。

「GPU付きEC2を起動して、CUDAが動くDockerコンテナをECSで動かしたいけど、設定が多くて大変そう...」という方に向けて、構築の自動化と再現性の確保を主眼に置いています。

作成されたレポジトリーはこちらです。

使用技術スタック

技術 用途
AWS ECS GPUコンテナの実行・管理基盤(EC2ベースのクラスター)
AWS EC2 GPU搭載のg4dnインスタンス(CUDA処理の実行)
Terraform インフラ構成のコード化と自動構築
Docker CUDA対応コンテナの作成・実行
NVIDIA ドライバ + CUDA GPUによる高速処理を可能にする
PyTorch 深層学習フレームワーク(動作確認用に使用)

処理の流れ(起動~実行まで)

1. Terraformスクリプトの実行

bin/terraform_apply により、以下のリソースを自動作成:

  • VPC、サブネット、セキュリティグループ
  • ECSクラスター(EC2起動タイプ)
  • g4dn.xlargeのGPU搭載EC2インスタンス(NVIDIAドライバ付きAMI)
  • ECSタスク定義とサービス(CUDAコンテナ)

2. ECS上でコンテナ起動

GPU対応のDockerイメージ(PyTorch + CUDA)を使って、ECSタスクが起動。GPUが認識されていることをログで確認可能

3. CUDA・PyTorchの動作確認

起動したコンテナで torch.cuda.is_available() を実行し、CUDAが有効なことを検証

4. 停止・破棄

環境を不要にした場合は bin/terraform_destroy によりすべてのリソースを削除

ECSの基本概念とFargateとの違い

Amazon ECS は、AWS が提供するフルマネージドなコンテナオーケストレーションサービスです。Docker コンテナの起動・停止・スケジューリング・スケーリングなどを自動で管理できます。
ECS には主に以下の2つの実行タイプがあります:

実行タイプ 概要 適したユースケース
EC2 ユーザーがEC2インスタンスを用意し、その上でコンテナを実行 GPU・特殊ドライバが必要なケース、細かなチューニング
Fargate サーバーレスで、AWSがコンテナのインフラを自動管理 小規模アプリ、スケーラビリティ重視、手軽に試したいとき

本構成でEC2を選ぶ理由

Fargate は便利ですが、現時点(2025年4月)では GPUサポートがない ため、CUDAコンテナなどGPUを必要とするワークロードでは EC2 実行タイプ一択 となります。

このため、本記事では EC2ベースの ECS クラスターを構築し、GPUリソースを持つコンテナを直接実行します。

コンテナの構成とCUDA対応:実装方法

本セクションでは、PyTorch + CUDA で GPU 処理を行うコンテナの作成方法について、具体的な Dockerfile と Python スクリプトを交えて解説します。
このコンテナは、ECS 上で起動した際に GPU が正しく認識されているかどうかを検証するためのものです。

Dockerfile:PyTorch + CUDA対応イメージ

以下は、CUDA 11.8 + cuDNN 8 対応の PyTorch ベースイメージを使った Dockerfile です。

# ベースイメージ(CUDA11.8 + cuDNN8 対応 PyTorch)
FROM pytorch/pytorch:2.1.0-cuda11.8-cudnn8-runtime

# pip のアップグレード(依存関係のエラー回避)
RUN pip install --upgrade pip

# アプリケーションコードをコンテナ内にコピー
COPY main.py /main.py

# コンテナ起動時に main.py を実行
CMD ["python", "/main.py"]

main.py:GPUが使えるか確認するPythonコード

以下は、PyTorch で GPU(CUDA)が正しく動作しているかを確認するための Python スクリプトです。

import torch

print("CUDA Available:", torch.cuda.is_available())
print("Device Name:", torch.cuda.get_device_name(0))

x = torch.tensor([1.0, 2.0, 3.0]).cuda()
y = torch.tensor([9.0, 8.0, 7.0]).cuda()
z = x + y

print("Result:", z)

CUDA対応ECS AMIの取得

ECS GPU 対応インスタンスを立ち上げるには、Amazon が提供する ECS 対応 GPU AMIを使用します。

data "aws_ami" "app" {
  most_recent = true
  owners      = ["amazon"]

  filter {
    name   = "name"
    values = ["amzn2-ami-ecs-gpu-hvm-*-x86_64-ebs"]
  }

  filter {
    name   = "architecture"
    values = ["x86_64"]
  }

  filter {
    name   = "virtualization-type"
    values = ["hvm"]
  }

  filter {
    name   = "root-device-type"
    values = ["ebs"]
  }
}

Launch Template の作成

ECS クラスタに参加する EC2(GPU搭載)のインスタンスを定義します。

resource "aws_launch_template" "ecs_gpu_launch_template" {
  name_prefix   = "ecs-gpu-"
  image_id      = data.aws_ami.app.id
  instance_type = "g4dn.xlarge"
  key_name      = aws_key_pair.keypair.key_name

  iam_instance_profile {
    name = var.instance_profile_name
  }

  network_interfaces {
    associate_public_ip_address = true
    security_groups             = [var.sg_ecs_id]
    subnet_id                   = var.public_subnet_1a_id
  }

  user_data = base64encode(<<-EOF
#!/bin/bash
set -euo pipefail

# ECS クラスター名と GPU サポート設定
cat <<EOT > /etc/ecs/ecs.config
ECS_CLUSTER=chatbot-cluster
ECS_ENABLE_GPU_SUPPORT=true
EOT

# ECS 再起動スクリプト
cat <<'EOT' > /usr/local/bin/start-ecs.sh
#!/bin/bash
systemctl stop ecs || true
systemctl enable ecs
systemctl start ecs
EOT

chmod +x /usr/local/bin/start-ecs.sh

# cloud-init 完了時に ECS を起動
cat <<'EOT' > /etc/cloud/cloud.final.d/99-start-ecs.cfg
#cloud-config
runcmd:
  - [ /usr/local/bin/start-ecs.sh ]
EOT
EOF
  )

  instance_market_options {
    market_type = "spot"

    spot_options {
      instance_interruption_behavior = "terminate"
      spot_instance_type             = "one-time"
    }
  }

  tag_specifications {
    resource_type = "instance"
    tags = {
      Name = "gpu-ecs-instance"
    }
  }
}

Auto Scaling Group の設定

ECS の GPU インスタンスを ASG(Auto Scaling Group)で管理します。

resource "aws_autoscaling_group" "ecs_gpu_asg" {
  name                      = "ecs-gpu-asg"
  desired_capacity          = 1
  max_size                  = 1
  min_size                  = 1
  vpc_zone_identifier       = [var.public_subnet_1a_id]
  health_check_type         = "EC2"
  health_check_grace_period = 300

  launch_template {
    id      = aws_launch_template.ecs_gpu_launch_template.id
    version = "$Latest"
  }

  tag {
    key                 = "Name"
    value               = "gpu-ecs-instance"
    propagate_at_launch = true
  }

  lifecycle {
    create_before_destroy = true
  }
}

EC2 キーペアの管理

SSHログインやトラブル時のデバッグ用にキーペアもTerraformで定義します。

resource "aws_key_pair" "keypair" {
  key_name   = "${var.app_name}-keypair"
  public_key = file("./modules/ec2/src/keypair.pub")

  tags = {
    Name = "${var.app_name}-keypair"
  }
}

CloudWatch ロググループの作成

ECS コンテナのログは CloudWatch Logs に出力させるのが定番です。

resource "aws_cloudwatch_log_group" "ecs_log" {
  name              = "/ecs/pytorch-gpu"
  retention_in_days = 7
}

ECS クラスターの作成

ECS クラスターを作成し、Container Insights を有効化することで CloudWatch でリソースの可視化が可能になります。

resource "aws_ecs_cluster" "gpu_cluster" {
  name = "${var.app_name}-cluster"

  setting {
    name  = "containerInsights"
    value = "enabled"
  }

  tags = {
    Name = "${var.app_name}-cluster"
  }
}

ECSタスク定義(GPUリソース付き)

CUDA コンテナを ECS 上で動かすには、GPUリソース要求を明示的に設定する必要があります。

resource "aws_ecs_task_definition" "pytorch_gpu_task" {
  family                   = "pytorch-gpu-task"
  network_mode             = "bridge"
  requires_compatibilities = ["EC2"]
  execution_role_arn       = var.iam_role_ecs_role_arn
  task_role_arn            = var.iam_role_ecs_role_arn

  container_definitions = jsonencode([
    {
      name      = "pytorch-gpu-container"
      image     = "${var.ai_repository_url}:latest"
      essential = true
      cpu       = 4096,
      memory    = 15000,

      resourceRequirements = [
        {
          type  = "GPU"
          value = "1"
        }
      ],
      logConfiguration = {
        logDriver = "awslogs",
        options = {
          awslogs-group         = "/ecs/pytorch-gpu",
          awslogs-region        = "ap-northeast-1",
          awslogs-stream-prefix = "ecs"
        }
      }
    }
  ])
}

ECSサービスの作成

1つのタスクを常に動作させるシンプルなサービス構成です。

resource "aws_ecs_service" "pytorch_gpu_service" {
  name            = "pytorch-gpu-service"
  cluster         = aws_ecs_cluster.gpu_cluster.id
  task_definition = aws_ecs_task_definition.pytorch_gpu_task.arn
  desired_count   = 1
  launch_type     = "EC2"

  deployment_controller {
    type = "ECS"
  }
}

実行結果

クラウドコンソール上で、以下の画面が出たら成功

aws.png

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?