🐥

Docker マルチCPUアーキテクチャで Fargate Graviton2 を試してみた

2021/11/24に公開1

Fargate で Graviton2 サポートが発表されたのでやってみた。
https://aws.amazon.com/jp/blogs/aws/announcing-aws-graviton2-support-for-aws-fargate-get-up-to-40-better-price-performance-for-your-serverless-containers/

golang や rust みたいにもともとクロスコンパイルできる言語でやってもアレなので rails で試す。

適当に rails new する。

rails new \
  --skip-action-mailer \
  ... 中略 ...
  --skip-webpack-install \
  rails-multi-cpu
cd rails-multi-cpu

Gemfile の ruby バージョン指定や webpacker は削除しておく

config.hosts.clear 入れておかないと ALB のホスト名でアクセスできないので入れておく。

config/environments/development.rb
Rails.application.configure do
  config.hosts.clear
Dockerfile
FROM ruby:3.0.2 as builder

ENV RAILS_ENV=development
WORKDIR /app

COPY Gemfile* /app/
RUN bundle install

FROM ruby:3.0.2-slim

ENV \
    RAILS_ENV=development \
    RAILS_LOG_TO_STDOUT=1 \
    RAILS_SERVE_STATIC_FILES=1

WORKDIR /app
CMD ["bundle", "exec", "rails", "s", "-b", "0.0.0.0"]

COPY --from=builder /usr/local/bundle /usr/local/bundle
COPY . /app
RUN bundle install && mkdir -p tmp/pids

とりあえず動けばいいのでテキトー

いったんローカルでビルド・実行してみてエラーが出たら調整

docker build -t rails-multi-cpu .
docker run -it --rm rails-multi-cpu

自分が試したときは master.key がないとか .bundle がないとかのエラーが出たけど割愛

動く状態になったら ECR リポジトリを作成してログインしておく

export AWS_ACCSESS_KEY_ID=xxxxx
export AWS_SECRET_ACCSESS_KEY=xxxxx

ECR_REPO_URI=$( \
  aws ecr create-repository --repository-name rails-multi-cpu \
  --query repository.repositoryUri --output text \
)

aws ecr get-login-password --region ap-northeast-1 | \
  docker login --username AWS --password-stdin ${ECR_REPO_URI}

イメージを buildx コマンドでビルドし、ECR に直接 push する

# builder インスタンスを作成 (作成しないとエラーになる)
docker buildx create --use --name multi-platform
# build & push
docker buildx build \
  --platform linux/amd64,linux/arm64 \
  -t ${ECR_REPO_URI}:latest \
  --push .

ビルド中。 linux/amd64linux/arm64 が並列でビルドされているのが見て取れる。
ビルド中

ものすごく時間がかかる (Intel Mac で 18 分くらいかかった)

Fargate の作成に copilot 使いたいけど諸々対応してなくて使えないので、 面倒だけど手作業で頑張る。

追記:
v1.13.0 の copilot-cli でメチャクチャ簡単にデプロイできたのでそちらの方がおすすめ。
以下の手順は自前で頑張る場合。


まずはタスク定義の登録。これは cli よりコンソールで作った方が楽。

次の画面で Linux/ARM64 を選択すること。

あとは VPC, ECS Service, ALB などを作っていけば OK。とても長くなるので割愛。

ALB の Public DNS にアクセスしてみると、アーキテクチャが aarch64-linux になってる。

所感

ビルドに時間がかかりすぎる(会社で指摘されたけど、H/Wアクセラレーションが効かないから?)ので、arm64 のマシン上でビルドしないと実用的な CI/CD にはならなそう。

copilot とかのエコシステムで簡単に指定できるといい。(今だと taskdef_overrides じゃなきゃ指定できなさそう)

追記

でも https://www.youtube.com/watch?v=_OPKij0fNCY これ見る限り copilot でもできてるな。後で試す。

参考

https://dev.classmethod.jp/articles/docker-multi-architecture-image-build

Discussion

sonodarsonodar

copilot cli v1.13.0 を使ったらもっと遥かに簡単にデプロイできた。