FargateでARM64向けDockerイメージは使えなかった

目次
  1. やりたかったこと
  2. 結果
  3. 結論
  4. DockerfileのFROMに指定したイメージはビルド端末のプラットフォームが適用される
  5. ARM64でAMD64向けイメージをビルドしたが.NET SDKが動かず
  6. 諦めてCodeBuildでAMD64向けイメージをビルドした
  7. AWSの動向

今回は意図せず開発環境の見直しを迫られた話になります。

やりたかったこと

  • 開発マシンであるApple M1でDockerイメージをビルドし、ECRにpushする。
  • FargateでECSタスクを実行する。

結果

M1でビルドしたイメージがECRタスク実行時に動作しませんでした。CloudWatchでECSタスクのログを見たところ、exec format errorと出力されていました。

このエラーはホストのCPUアーキテクチャとベースイメージのCPUアーキテクチャが異なる時に発生するようです。

https://stackoverflow.com/a/64215125

結論

ECSで稼働中のコンテナ側からuname -aを実行したところ、Fargateのホストはx86_64で、ベースイメージのCPUアーキテクチャと異なる為にエラーが出ていたと思われます。

ARM64で動作させる設定は残念ながら見当たらず。

ARM64のEC2インスタンスでコンテナを立ち上げれば動くとは思いますが、今回は保守人員の関係上どうしてもFargateで動かしたかったのでCodeBuildでビルドすることになりました。

DockerfileのFROMに指定したイメージはビルド端末のプラットフォームが適用される

The optional –platform flag can be used to specify the platform of the image in case FROM references a multi-platform image. For example, linux/amd64, linux/arm64, or windows/amd64. By default, the target platform of the build request is used.

https://docs.docker.com/engine/reference/builder/#from

Docker公式にちゃんと書いてある仕様でしたが、これを知らず最初はApple M1(ARM64)でビルドしていた為、ARM向けイメージがpullされていたようです。 ビルド端末のCPUは意識しないといけませんね。

ARM64でAMD64向けイメージをビルドしたが.NET SDKが動かず

DockerfileのFROMにAMD64を指定して改めてイメージのビルドをしたところ、ECSタスクでコンテナ起動自体は成功しましたが、今度はコンテナ起動直後に実行するdotnet runの処理でエラーが発生。

.NET SDK側で発生したエラーと思われます。 ARM64でAMD64向けイメージをビルドしたことが関係していると思うのですが、結局明確な原因は特定できず納期のこともあった為、ARM64でのビルドを断念することに…。

諦めてCodeBuildでAMD64向けイメージをビルドした

最終的にCodeBuild上のAMD64の端末からAMD64向けイメージをビルドしECRへpushしました。 ECSタスクを実行し、無事コンテナの動作確認もできた為、一件落着となりました。

AWSの動向

githubでは私と同じくFargateのホストをARMで動かしたいという要望が出ていました。 そのうち対応してくれるかもしれません。是非宜しくお願いします!

https://github.com/aws/containers-roadmap/issues/793