2
4

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

Lima で vz + rosetta を使って ARM VM 上で x86_64 バイナリを実行する

Last updated at Posted at 2023-12-01

この記事は、3-shake Advent Calendar 2023 2日目のエントリ記事です。

2023年10月に Docker Desktop for Apple silicon での Rosetta for Linux が GA となり、Apple Silicon の Mac 上で x86_64 バイナリ実行のパフォーマンスや安定性が向上したとありました。

Docker Desktop は2021年の有償化以降、Lima が代替ソフトウェアのプラットフォームとして広く使われています。Amazon の FinchRancher Desktop の内部でも使われています。

私も Apple silicon の MacBook Air で Lima を docker の実行環境として利用していました。Lima はデフォルトでは qemu で VM の仮想化を行なっていますが、vmTypevz を指定することで Apple の Virtualization Framework を使うようになっており、さらに rosetta を有効にすることで Docker Desktop のように ARM の VM 上で docker daemon を実行しつつ、x86_64 のコンテナを実行することができます。

docker daemon 用 VM の定義の作成

vz で rosetta を有効にした aarch64 の VM を定義します。

limactl create --name=default \
   --cpus=2 --memory=2 \
  --vm-type=vz --mount-type=virtiofs --rosetta \
  template://docker

~/.lima/default 配下に必要なファイルが作成されます

$ limactl ls
NAME       STATUS     SSH            VMTYPE    ARCH       CPUS    MEMORY    DISK      DIR
default    Stopped    127.0.0.1:0    vz        aarch64    2       2GiB      100GiB    ~/.lima/default

template の一覧は limactl create --list-templates で確認できます。Homebrew でインストールしている場合は ls $(brew --prefix)/opt/lima/share/lima/templates でファイルも確認できます。

docker daemon 用 VM の起動

次に limactl start NAME (NAME が default の場合は省略可能) を実行することで VM が起動されます。

docker テンプレートを使った場合、次のような出力がされるはずです、create は初回のみ実行すればよく、context use~/.docker/config.json に書き込まれるので切り替えが不要であれば1度実行しておけば良いです。(docker context)

docker context create lima-default --docker "host=unix:///Users/teraoka/.lima/default/sock/docker.sock"
docker context use lima-default

これで docker コマンドはこの VM 上の docker daemon と通信することになります。

lima コマンドの引数が VM 内で実行されます。uname -m で architecture を確認すると aarch64 で ARM であることが確認できます。

$ lima uname -m
aarch64

docker コンテナの実行

先ほどの結果からデフォルトでは arm64 のコンテナイメージをダウンロードして実行しようとします。

$ docker run --rm debian uname -m
Unable to find image 'debian:latest' locally
latest: Pulling from library/debian
df2021ddb7d6: Pull complete 
Digest: sha256:133a1f2aa9e55d1c93d0ae1aaa7b94fb141265d0ee3ea677175cdb96f5f990e5
Status: Downloaded newer image for debian:latest
aarch64

今度は --platform=linux/amd64 を指定して実行してみます。

$ docker run --rm --platform=linux/amd64 debian uname -m
Unable to find image 'debian:latest' locally
latest: Pulling from library/debian
90e5e7d8b87a: Pull complete 
Digest: sha256:133a1f2aa9e55d1c93d0ae1aaa7b94fb141265d0ee3ea677175cdb96f5f990e5
Status: Downloaded newer image for debian:latest
x86_64

指定した image 名は同じですが、platform が異なるため新たにダウンロードされました。uname -m コマンドのの出力も x86_64 となっています。

ダウンロードされている image を確認してみます。

$ docker image ls
REPOSITORY   TAG       IMAGE ID       CREATED      SIZE
debian       <none>    a588e7890234   9 days ago   139MB
debian       latest    0ce03c8a15ec   9 days ago   117MB

ls では architecture が確認できないので inspect で確認してみます。

$ docker image inspect $(docker image ls --format '{{.ID}}') | jq '.[] | {id:.Id[7:19],arch:.Architecture,tag:.RepoTags[0]}' -c     
{"id":"a588e7890234","arch":"arm64","tag":null}
{"id":"0ce03c8a15ec","arch":"amd64","tag":"debian:latest"}

パフォーマンス比較

私は今のところ手元の docker 環境でたいした処理を行わないので誰かやってみてください。
次のようにして複数の VM を作成し、切り替えて試すことができます。

aarch64 (rosetta 無し)

limactl create --name=arm64 \
  --arch=aarch64 \
  --cpus=2 --memory=2 \
  --vm-type=vz --mount-type=virtiofs \
  template://docker

この環境で --platform=linux/amd64 を指定してコンテナを実行すると次のようなエラーで実行できないはずです。

exec /usr/bin/uname: exec format error

x86_64 (qemu)

limactl create --name=amd64 \
  --arch=x86_64 \
  --cpus=2 --memory=2 \
  --vm-type=qemu --mount-type=9p \
  template://docker

qemu の場合、mountTypevirtiofs を指定することができません。(9p と virtiofs は以前簡単に比較してみました。)

$ limactl ls
NAME       STATUS     SSH            VMTYPE    ARCH       CPUS    MEMORY    DISK      DIR
amd64      Stopped    127.0.0.1:0    qemu      x86_64     2       2GiB      100GiB    ~/.lima/amd64
arm64      Stopped    127.0.0.1:0    vz        aarch64    2       2GiB      100GiB    ~/.lima/arm64
default    Stopped    127.0.0.1:0    vz        aarch64    2       2GiB      100GiB    ~/.lima/default
2
4
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
4

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?