ECS on FargateのCPUアーキテクチャをarm64に移行し、ECSコストを約50%に削減しました
はじめに
こんにちは。ランサーズ株式会社でSREをしているtkです。
今回は、弊社のアプリケーション「ランサーズ」について、arm64移行によってECS費用を削減した際のお話をさせていただきます。
※ 記事の中で例を記載させていただいておりますが、実際に変更した内容の抜粋となっているため
あくまで参考例にしていただけますと幸いです。
前提
- インフラの構成管理にはTerraformを利用
- アプリケーションは、ECS on Fargateでホスト
- コンテナイメージは、ECRで管理
- デプロイは、GitHub Actions経由で実行
方針
デプロイフローから逆算して、下記の変更を加える方針で進めました。
- Dockerfileに記載のライブラリについて、amd64, arm64のマルチプラットフォームでビルドできるように修正
- GitHub Actionsにて、amd64, arm64のマルチプラットフォームイメージを作成するよう変更
- ECSのタスク定義にて、CPUアーキテクチャの設定をamd64->arm64に変更
手順
Dockerfileの修正
amd64でのみインストールされていたライブラリについて、arm64とマルチプラットフォームに対応した形でインストールできるように修正します。
ライブラリがマルチアーキテクチャに対応している場合、パッケージマネージャ経由でインストールする方法が良いかと思いますが
今回はuname -m
を利用して、アーキテクチャごとにインストールする方法をご紹介します。
(※ ライブラリのリリースノートを確認し、amd64, arm64のどちらにも対応していることを確認してください)
例
dd-trace-phpのライブラリをマルチアーキテクチャに対応した形でインストールする方法です。
# uname -m を利用して、実行環境のアーキテクチャを取得
RUN dnf -y install https://github.com/DataDog/dd-trace-php/releases/download/1.11.0/datadog-php-tracer-1.11.0-1.$(uname -m).rpm \
タスク定義の修正
terraformで管理している、ECSのタスク定義を修正します。
例
resource "aws_ecs_task_definition" "app" {
family = "app"
requires_compatibilities = ["FARGATE"]
network_mode = "awsvpc"
task_role_arn = "arn:aws:iam::${var.aws_account_id}:role/ecsTaskExecutionRole"
execution_role_arn = "arn:aws:iam::${var.aws_account_id}:role/ecsTaskExecutionRole"
cpu = xxxx
memory = xxxx
container_definitions = file("files/task_definitions/app.json")
# cpu_architectureをarm64に設定
runtime_platform {
operating_system_family = "LINUX"
cpu_architecture = "ARM64"
}
}
デプロイワークフローの修正
arm64対応前のデプロイワークフローですが、主に下記3ステップで構成されていました。
今回のarm64対応では、2.のDockerイメージのビルドステップを修正しました。
- Frontendのデプロイ
- Backend用Dockerイメージのビルド(amd64)
- DockerイメージをECSにデプロイ
マルチプラットフォームイメージをビルドするように、デプロイワークフローを修正します。
具体的には、下記の修正を行いました。
- matrixを利用して、amd64とarm64のイメージを並列でビルドする
-
docker buildx imagetools create
を利用して、マルチプラットフォームイメージをビルドする
例
(※ 変更箇所付近のみ抜粋しています)
docker_build:
runs-on: ${{ matrix.runner }}
# matrixを利用して、amd64とarm64のイメージを並列でビルドする
strategy:
fail-fast: true
matrix:
include:
- platform: linux/amd64
runner: ubuntu-latest
arch: amd64
- platform: linux/arm64
runner: linux-arm64
arch: arm64
steps:
- uses: actions/checkout@v4.2.1
with:
ref: ${{ inputs.branch }}
- name: Configure AWS credentials
uses: aws-actions/configure-aws-credentials@v4.0.0
with:
role-to-assume: ${{ secrets.AWS_PRE_IAM_ROLE_ARN_GITHUB_ACTION_OIDC_PROVIDER }}
aws-region: ${{ env.AWS_REGION }}
mask-aws-account-id: no
- name: Login to Amazon ECR
id: login-ecr
uses: aws-actions/amazon-ecr-login@v1
with:
mask-password: 'true'
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3.0.0
- name: Build and Push app image
id: build-push-app
uses: docker/build-push-action@v5
with:
context: .
file: docker/dev/app/Dockerfile
push: true
platforms: ${{ matrix.platform }}
tags: |
${{ steps.login-ecr.outputs.registry }}/${{ env.ECR_REPO_NAME }}:${{ inputs.branch }}-${{ matrix.arch }}
${{ steps.login-ecr.outputs.registry }}/${{ env.ECR_REPO_NAME }}:latest-${{ matrix.arch }}
cache-from: type=gha,scope=${{ github.ref }}-app-${{ matrix.arch }}
cache-to: type=gha,mode=max,scope=${{ github.ref }}-app-${{ matrix.arch }}
create_multiplatform_image:
- name: Create app manifest list and push
run: |
docker buildx imagetools create \
-t ${{ steps.login-ecr.outputs.registry }}/${{ env.ECR_REPO_NAME }}:${{ inputs.branch }} \
-t ${{ steps.login-ecr.outputs.registry }}/${{ env.ECR_REPO_NAME }}:latest \
${{ steps.login-ecr.outputs.registry }}/${{ env.ECR_REPO_NAME }}:${{ inputs.branch }}-${{ env.ARCH_AMD64 }} \
${{ steps.login-ecr.outputs.registry }}/${{ env.ECR_REPO_NAME }}:${{ inputs.branch }}-${{ env.ARCH_ARM64 }}
結果
先月(7/1~7/28)と今月(8/1~8/28)でECSの平均コストを比較したところ、54%ほどコストが削減できていることを確認しました 🥳
ECS費用のグラフ(7月から8月にかけて)
8/7にarm64対応をデプロイしたのですが、
デプロイ以降大きく費用が下がっていることが確認いただけると多います。
一般的にはarm64対応によるコスト削減効果は20%ほどと言われていますが、予想以上の効果が出ることとなりました。
(心当たりはないですが、arm64対応の要因もある可能性はあります)
課題
- アプリケーションのレイテンシーが(若干)増加傾向にあること
- マルチプラットフォームビルドによる、Github Cacheの圧迫
- amd64, arm64のビルドアーティファクトの削除方法
- ECRのLifeCycle Policyで削除していく方針を採用しましたが、GitHub Actionsにてデプロイ後すぐに削除する方法もあり、どちらがベストか決めかねています
特にGitHub Cache周りは最適化があまりできていないので、腰を据えて対応していきたいです。
終わりに
ここまでご覧いただきありがとうございました。
ECS on Fargate環境で、arm64へのアーキテクチャ変更をする際の参考になれば幸いです。
Discussion