🎉

Lima で Intel on ARM やる

2021/09/21に公開

背景

Apple Silicon Mac が登場してしばらく経ち、Intel Mac が購入できなくなる日も遠からずになってきています。

そんな中で、Docker Desktop on Mac, Lima, Podman など複数の選択肢が出現しており、組織で可能な選択肢で乗り切るのだろうと思います。

ところで忘れられてそうですが、多くの企業では、本番環境など当分は Intel x86-64 で、CI もおそらく Intel x86-64 でしょう。でも手元は Apple Silicon Mac で、Docker Desktop on Mac, Lima, Podman などは特別に指定しなければ ARM な VM で動作します。それって結構めんどうくさい状況になりそうです。

つまり Apple Silicon Mac で、Intel x86-64 な Docker ローカル環境を整備したい。

結論

lima に渡す YAML に arch: "x86_64" を明記し limactl start hoge.yaml すると、Intel Mac でも、Apple Silicon Mac でも、 Intel x86-64 な VM が生成されます。

公式の設定ファイルのサンプルをイジるなら

Lima

VM の基盤に QEMU を利用している Lima は、README.md で力強く

ARM on Intel
Intel on ARM

を謳っています。ッシャーやるかと調べてみるも、環境変数でも入りそうにないし、CLIオプションでもなさそうだし、なんだこいつ、どうやるのか何もわからねえ。

そんな次第で調べたのが、この記事です。

準備

❯ brew install lima docker docker-compose

※ qemu の M1 パッチを入れる PR が homebrew に入ったので ↑ だけで整います

docker コマンドの向け先など ↓ を参考に整えます。

実演

手元の Apple Silicon Mac に、limaリポジトリにある default.yaml を持ってきて、arch を x86_64 に改変して実行します。

curl -o default.yaml https://raw.githubusercontent.com/lima-vm/lima/master/pkg/limayaml/default.yaml
❯ sed -i -e 's/arch: \"default\"/arch: \"x86_64\"/g' default.yaml
❯ head default.yaml
# ===================================================================== #
# BASIC CONFIGURATION
# ===================================================================== #

# Arch: "default", "x86_64", "aarch64".
# "default" corresponds to the host architecture.
arch: "x86_64"

# An image must support systemd and cloud-init.
# Ubuntu and Fedora are known to work.

準備ができたら以下。

❯ limactl start default.yaml
? Creating an instance "default" Proceed with the default configuration
INFO[0032] Downloading "https://github.com/containerd/nerdctl/releases/download/v0.11.1/nerdctl-full-0.11.1-linux-amd64.tar.gz" (sha256:ce7a6e119b03c3fb8ded3d46d929962fd17417bea1d5bbc07e0fce49494d8a09)
172.67 MiB / 172.67 MiB [----------------------------------] 100.00% 14.40 MiB/s
INFO[0045] Downloaded "nerdctl-full-0.11.1-linux-amd64.tar.gz"
()
INFO[0649] READY. Run `lima` to open the shell.

このとき出来上がったVMは x86_64 であることを、以下のように確認できます。

❯ limactl list
NAME       STATUS     SSH                ARCH      DIR
default    Running    127.0.0.1:60022    x86_64    /Users/sasasin/.lima/default

❯ lima uname -a
Linux lima-default 5.11.0-34-generic #36-Ubuntu SMP Thu Aug 26 19:22:09 UTC 2021 x86_64 x86_64 x86_64 GNU/Linux

ホストマシン側は arm64 であることを確認できます。

uname -a
Darwin mba2021.local 20.6.0 Darwin Kernel Version 20.6.0: Mon Aug 30 06:12:20 PDT 2021; root:xnu-7195.141.6~3/RELEASE_ARM64_T8101 arm64

やりました!! Intel on ARM です!!

発展

ローカル開発環境としては docker, docker-compose で使うのが多いでしょうから、 default.yaml を元にしていると若干不便です。 docker.yaml あたりを改変利用するとよさそう。

以下でイイ雰囲気になります。

curl -o docker.yaml https://raw.githubusercontent.com/lima-vm/lima/master/examples/docker.yaml
❯ echo 'arch: "x86_64"' >> docker.yaml
❯ limactl start docker.yaml

Lima が VM の arch を決めている実装

lima はYAMLでVMの設定を記述するものの、多くにデフォ値が用意されており、省略可能です。省略されたときデフォ値を埋めるのが pkg/limayaml/defaults.go です。

特に arch: が端折られたときに埋めているのが以下です。この働きにより、端折られたときは、Intel Mac で動かせば Intel VM が起動し、ARM Mac で動かせば ARM VM が起動するようになっています。

func resolveArch(s string) Arch {
	if s == "" || s == "default" {
		if runtime.GOARCH == "amd64" {
			return X8664
		} else {
			return AARCH64
		}
	}
	return s
}

参考

↑ では tap で M1 パッチ版 QEMU を入れていますが、時が進み、 brew install qemu したらもう M1 パッチ版 QEMU が入るようになりした。

https://twitter.com/tnk4on/status/1441266974844018694

Discussion