掲題通り。解決までの道筋を備忘録として残そうと思う。
前提
t3.medium
で稼働しているEC2インスタンスのタイプをr7g.medium
に変更してほしいという依頼を受けた- Auto Scaring GroupなどはじめAWS構成をTerraformで管理しているので、.tfファイルの修正 -> apply を伴う
- アプリ自体は GithubActionでイメージをECRにプッシュし、該当イメージをECSでデプロイする流れ
x86ベース → ARM への移行という障壁
今回の肝はここ。
t3.medium
→ r7g.medium
に変更するということは、アーキテクチャがx86ベース → ARMベースに変更されるというポイントがある。
x86
- パソコンやサーバーで主に使用
- 高性能だけど、電気をたくさん使う
- 複雑な計算が得意
- IntelやAMDが作っている
ARM
- スマートフォンやタブレットで生まれた CPU
- 軽くて省エネ・省電力
- バッテリーが長持ちする
- Amazonが作ったGraviton2/3ベース
簡単に言えば、x86は「パワフルだけど電気を食う」、ARMは「少ない電気で効率的に動く」タイプのCPU、と理解した。
アーキテクチャが変わることによる影響範囲を当時はあまり理解できていなかった。
切り替え自体は楽だが使用するイメージに注意
アーキテクチャが変わるとはいえ、instance_type = "r7g.medium"
としてやればいいだけだと考えていた。
が、インスタンスタイプが切り替わったあと、元々動いていたサービス上でタスクが起動しなくなっていることに気づいた。
resource "aws_launch_template" "lt" { name_prefix = "${local.app_name}-lt-" image_id = "ami-0dba57a21a03d3f66" # Arm対応ECS-Optimized AMI instance_type = "r7g.medium" key_name = var.ssh_key_name
原因は image_id
だった。
上記修正を行うまで、 単にARM64に対応している最新のimage_idを指定していたが、Arm用の ECS-Optimized AMI
を指定してやらないと、DockerやECSエージェントがプリインストールされないため、サービス上でタスクがいつまでも起動しない(ECSとECRが紐づかない)状態となってしまった。(これ気づくの時間かかった…)
こちらを適用後、インスタンスとサービスを再起動することでタスクは動き出した。
Github Actionでエラー
GithubAction実行時に以下のエラー
8 0.190 exec /bin/sh: exec format error
これは Docker ビルド時にコンテナが ベースイメージのアーキテクチャ と 実行環境のアーキテクチャ が一致していなかったために発生するものらしい。
ベースイメージはDockerFile内で node:18-slim
を指定していた。これはマルチアーキテクチャに対応してくれることを事前調査済みだったので安心していたが、問題は実行環境のアーキテクチャ。
Github Actionはデフォルトで x86ベース で動作するため、これが不一致の原因だった。
Github Actionでアーキテクチャが異なる環境でプログラムを動作可能にするには、QEMU
とBuildx
というツールを使うのが一般的だと知った。
- name: Setup QEMU uses: docker/setup-qemu-action@v2 with: platforms: linux/arm64 - name: Setup Docker Buildx uses: docker/setup-buildx-action@v2
- QEMU: 異なるアーキテクチャをエミュレートのするためのツール
- Buildx: いろんな環境用に効率よくアプリを作るためのツール
らしい。
これらを導入することでbuildも通った。
build時間がめちゃくちゃ長くなった (5分程度 → 30分程度) のが微妙過ぎるが、これはまた別の課題とする。