Docker マルチCPUアーキテクチャで Fargate Graviton2 を試してみた
Fargate で Graviton2 サポートが発表されたのでやってみた。
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 のホスト名でアクセスできないので入れておく。
Rails.application.configure do
config.hosts.clear
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 /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/amd64
と linux/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 でもできてるな。後で試す。
参考
Discussion
copilot cli v1.13.0 を使ったらもっと遥かに簡単にデプロイできた。