ARM Mac の Docker 対応について
発表当初は「M1 Mac では Docker が動かないらしい」と言われていましたが、少し前に対応されました。
( 実際は Go の ARM 対応に依存していたとかなんとか? )
Rosetta の章で紹介した確認サイト でも M1 optimized ✅ になっています。
インストールしてコンテナの挙動を確認してみます。
イメージとコンテナについて
コンテナのアーキテクチャ
適当なコンテナでアーキテクチャを確認してみます。
$ docker run -it alpine:latest uname -m
x86_64
$ docker run -it alpine:latest uname -m
aarch64
同じコマンドを実行したのに、コンテナのアーキテクチャが異なっています。
イメージを確認すると、ID が違います。
$ docker image ls
REPOSITORY TAG IMAGE ID CREATED SIZE
alpine latest d4ff818577bc 5 weeks ago 5.6MB
$ docker image ls
REPOSITORY TAG IMAGE ID CREATED SIZE
alpine latest b0e47758dc53 5 weeks ago 5.6MB
イメージを詳しく調べると、Architecture
が違うことが確認できます。
$ docker inspect d4ff818577bc | jq -r '.[] | .Architecture'
amd64
$ docker inspect b0e47758dc53 | jq -r '.[] | .Architecture'
arm64
コンテナのアーキテクチャが異なれば、違うイメージということですね。
使うイメージの決まり方
ARM Mac の x86_64 ターミナル の x86_64 シェルで同じコマンドを実行してみると、ARM コンテナが動きました。
$ uname -m
x86_64
$ docker run -it alpine:latest uname -m
aarch64
コンテナのアーキテクチャの自動選択は、ホストマシンのアーキテクチャに依存していると考えて良さそうです。 ( つまり常に ARM64 が選ばれます。)
イメージのアーキテクチャを指定する
docker pull
や docker run
には --platform
というオプションがあります。
これを利用すれば ARM Mac で x86_64 のコンテナを使うことも可能です。
$ uname -m
arm64
$ docker run -it --platform linux/x86_64 alpine:latest uname -m
x86_64
イメージ ID も Intel Mac と同じものになりました。
$ docker image ls
REPOSITORY TAG IMAGE ID CREATED SIZE
alpine latest d4ff818577bc 5 weeks ago 5.6MB
$ docker inspect d4ff818577bc | jq -r '.[] | .Architecture'
amd64
こういうことですね。
イメージのアーキテクチャ一覧を確認する方法
方法の 1 つめは Docker Hub で確認する方法です。
イメージごとの OS/ARCH
の項目で確認できます。
2 つめは docker manifest inspect
を実行する方法です。
$ DOCKER_CLI_EXPERIMENTAL=enabled
$ docker manifest inspect alpine:latest
出力が少し多いので適当に整形します。
$ docker manifest inspect alpine:latest | jq -r '.manifests[].platform | if .variant == null then .os + "/" + .architecture else .os + "/" + .architecture + "/" + .variant end' | sort
linux/386
linux/amd64
linux/arm/v6
linux/arm/v7
linux/arm64/v8
linux/ppc64le
linux/s390x
同じ結果ですね。
ARM Mac で Docker を使う際の課題
Docker Desktop の ARM 対応が完了し、x86_64 コンテナも ARM64 コンテナも使い分けることが確認できました。
ARM Mac で Docker という仕組みを利用することの課題はあまり感じられません。
が、コンテナ 1 つ 1 つに注目した場合はかなり印象が変わります。
ARM64 イメージが必ず用意されているとは限らない
例えば Haskell のコンテナを使おうと思って docker pull
をすると、ARM64 イメージが見つからないと言われました。
$ docker pull haskell:latest
no matching manifest for linux/arm64/v8 in the manifest list entries
確かに提供されていないみたいです。
$ docker manifest inspect haskell:latest | jq -r '.manifests[].platform | if .variant == null then .os + "/" + .architecture else .os + "/" + .architecture + "/" + .variant end' | sort
linux/amd64
ARM Mac に x86_64 イメージを持ってきても動くとは限らない
それならと x86_64 イメージを指定すると、期待した通りイメージは取得できます。
$ docker pull haskell:latest --platform linux/x86_64
$ docker image ls
REPOSITORY TAG IMAGE ID CREATED SIZE
haskell latest 02006a905c71 12 days ago 1.5GB
$ docker inspect 02006a905c71 | jq -r '.[] | .Architecture'
amd64
が、このコンテナを起動しても Haskell のビルドツール stack
は動きませんでした。
( ホストマシンのアーキテクチャとイメージのアーキテクチャが違うという警告も出ています。)
$ docker run -it haskell:latest bash
WARNING: The requested image's platform (linux/amd64) does not match the detected host platform (linux/arm64/v8) and no specific platform was requested
> uname -m
x86_64
> stack -h
Killed
ARM コンテナに x86_64 と同じ構築をしても動くとは限らない
ARM コンテナの上で自分でインストールしても、いろいろ動きません。
$ docker run -it ubuntu:latest /bin/bash
> uname -m
aarch64
> apt install haskell-stack
bla bla bla
> stack upgrade --binary-only
Control.Exception.Safe.throwString called with:
Binary upgrade not yet supported on arch: AArch64
一度コンテナを破棄して別の方法で入れ直そうとしてもインストールに失敗します。
> curl -sSL https://get.haskellstack.org/ | sh
Detected Linux distribution: ubuntu
Sorry, currently only 64-bit (x86_64) Linux binary is available.
Haskell の ARM64 対応が進むのを待たなければならないようです。
( Haskell は Intel Mac を使っていた頃から Mac 自体にインストールしていたので、とりあえずは ARM Mac に x86_64 Haskell をインストールしました。)
整理
ARM Mac の上で動かす全ての x86_64 コンテナがうまく動かないのかはわかりません。
現に uname -m
程度なら動くことは先ほど確認できています。
$ docker run -it --platform linux/x86_64 alpine:latest uname -m
x86_64
とはいえ、ARM64 向けのイメージが提供されていない場合は、それなりの茨の道を覚悟する必要がありそうです。
まとめ
- Docker という仕組み自体は問題なく動く
- ターミナルやシェルに関わらず、イメージは ARM64 のものが選ばれる
- 明示的に x86_64 イメージを使う場合のみ
--platform
を使う
- 明示的に x86_64 イメージを使う場合のみ
- ARM64 のイメージがない場合は、困る
参考にした記事