この記事では、AWS EKSクラスタでArmアーキテクチャのコンテナを動かす方法について説明します。Armコンテナは、特にコスト効率が求められるワークロードに適しています。ここでは、Terraformを使用してEKSクラスタをセットアップし、Javaアプリケーション(Spring Boot)をArmコンテナでデプロイする手順を紹介します。
EKSクラスタのセットアップ
VPNとEKSクラスタの定義
まず、Terraformを使用してEKSクラスタをセットアップします。以下は、基本的なTerraform構成の例です。ここでのポイントは、instance_typeにt4g.mediumのようにArmのインスタンスタイプを指定し、Armインスタンスを使用するためにami_typeをAL2_ARM_64に設定することです。
main.tf
terraform { required_providers { aws = { source = "hashicorp/aws" version = "~> 5.0" } } } provider "aws" { region = "us-west-2" } data "aws_availability_zones" "available" { filter { name = "opt-in-status" values = ["opt-in-not-required"] } } module "vpc" { source = "terraform-aws-modules/vpc/aws" version = "~> 5.0" name = "eks-vpc" cidr = "10.0.0.0/16" azs = slice(data.aws_availability_zones.available.names, 0, 3) private_subnets = ["10.0.1.0/24", "10.0.2.0/24", "10.0.3.0/24"] public_subnets = ["10.0.101.0/24", "10.0.102.0/24", "10.0.103.0/24"] enable_nat_gateway = true enable_vpn_gateway = true public_subnet_tags = { "kubernetes.io/role/elb" = 1 } private_subnet_tags = { "kubernetes.io/role/internal-elb" = 1 } } module "eks" { source = "terraform-aws-modules/eks/aws" version = "~> 19.0" cluster_name = "awesome-service-cluster" cluster_version = "1.28" vpc_id = module.vpc.vpc_id subnet_ids = module.vpc.private_subnets cluster_endpoint_public_access = true eks_managed_node_groups = { main = { name = "main-node-group" instance_types = ["t4g.medium"] capacity_type = "SPOT" min_size = 1 max_size = 3 desired_size = 2 ami_type = "AL2_ARM_64" } } }
ECRリポジトリの定義
次に、以下のようにECRリポジトリを作成します。ここは通常のECRリポジトリの設定と同じです。
ecr.tf
resource "aws_ecr_repository" "backend" { name = "awesome-service-backend" image_tag_mutability = "MUTABLE" image_scanning_configuration { scan_on_push = true } encryption_configuration { encryption_type = "AES256" } tags = { Name = "awesome-service-backend" Environment = "production" } } resource "aws_ecr_lifecycle_policy" "backend" { repository = aws_ecr_repository.backend.name policy = jsonencode({ rules = [ { rulePriority = 1 description = "Keep last 10 images" selection = { tagStatus = "tagged" tagPrefixList = ["v"] countType = "imageCountMoreThan" countNumber = 10 } action = { type = "expire" } }, { rulePriority = 2 description = "Remove untagged images after 7 days" selection = { tagStatus = "untagged" countType = "sinceImagePushed" countUnit = "days" countNumber = 7 } action = { type = "expire" } } ] }) }
上記のファイルを作成したら、tfファイルのあるディレクトリで以下のコマンドを実行してKubernetesクラスタを構築します。
terraform init terraform apply
ArmコンテナのビルドとECRへのプッシュ
Dockerファイルの作成
Armコンテナをビルドするには、Dockerfileで適切なベースイメージを指定します。以下は、Spring Bootアプリケーションの例です。(Spring Bootのプロジェクトの作成やアプリケーションの作成は省略します。)
Dockerfile
# ビルドステージ FROM maven:3.9-eclipse-temurin-17 AS build WORKDIR /app # pom.xmlをコピーして、依存ファイルを先にダウンロードする。(キャッシュ活用のため) COPY pom.xml . RUN mvn dependency:go-offline -B # ソースコードをコピーしてビルド COPY src ./src RUN mvn clean package -DskipTests -B # 実行ステージ FROM eclipse-temurin:17-jre-jammy WORKDIR /app COPY --from=build /app/target/*.jar app.jar EXPOSE 8080 ENTRYPOINT ["java", "-jar", "app.jar"]
DockerイメージのビルドとECRへのプッシュ
以下のコマンドを使用して、Armコンテナイメージをビルドし、ECRにプッシュします。ここでは、Docker Buildxを使用してマルチプラットフォームビルドを行います。
# ECRにログイン
aws ecr get-login-password --region us-west-2 | docker login --username AWS --password-stdin <your_account_id>.dkr.ecr.us-west-2.amazonaws.com
# Dockerイメージのビルドとプッシュ
if ! docker buildx inspect multiplatform-builder > /dev/null 2>&1; then
docker buildx create --name multiplatform-builder --use --platform linux/amd64,linux/arm64
else
docker buildx use multiplatform-builder
fi
docker buildx inspect --bootstrap
docker buildx build --platform linux/arm64 -t <your_account_id>.dkr.ecr.us-west-2.amazonaws.com/awesome-service-backend:latest --push .
Kubernetesマニフェストの作成とデプロイ
最後に、Kubernetesマニフェストを作成して、EKSクラスタにデプロイします。以下は、Deploymentの例です。(ServiceやIngressの設定も必要に応じて追加してください。)
backend-deployment.yaml
apiVersion: apps/v1 kind: Deployment metadata: name: backend-deployment spec: replicas: 2 selector: matchLabels: app: backend template: metadata: labels: app: backend spec: containers: - name: backend image: <your_account_id>.dkr.ecr.us-west-2.amazonaws.com/awesome-service-backend:latest ports: - containerPort: 8080
このマニフェストを適用して、EKSクラスタにデプロイします。
kubectl apply -f backend-deployment.yaml
Armインスタンスを使用する上での注意点
Armインスタンスを使用する場合、以下の点に注意してください。
- Armアーキテクチャに対応したコンテナイメージを使用する必要があります。
- 一部のライブラリやツールがArmで動作しない場合があります。事前に確認してください。
- パフォーマンスや互換性の問題が発生する可能性があるため、十分なテストを行ってください。
特にパフォーマンスについては、resource requests と limits を設定する方法は、x86インスタンスと同様ですが、CPUのクロックは公開されていないため、実際のパフォーマンスを測定しながら適切な値を設定することをお勧めします。まずは、24/7で稼働する必要はあるが、高いパフォーマンスは求められないワークロードから始めると良いでしょう。
まとめ
この記事では、AWS EKSクラスタでArmコンテナを動かす方法について説明しました。Terraformを使用してEKSクラスタをセットアップし、Armインスタンスを利用することで、コスト効率の高い環境を構築できます。さらに、Docker Buildxを活用してArmコンテナイメージをビルドし、ECRにプッシュする手順も紹介しました。これにより、Spring BootアプリケーションをArmアーキテクチャで実行できるようになります。ぜひ試してみてください。