Mac(M1)でLimaを使ってx86_64のDockerイメージを動かす(2022年1月版)

目次

はじめに

Docker Desktopにおいて、M1 Mac上でx86_64イメージをpullしても、動作しない場合があります。そこで、以下の手順で、Docker Desktopの代わりにLima-VM上にDockerをインストールして動作するようにします。

流れ

  1. Docker Desktop for Macをアンインストールする。
  2. HomebrewでLimaとDocker CLIをインストールする。
  3. Limaを設定し起動する。(執筆時点では、v0.8.1)
  4. docker compose v2を導入する。

概要図

f:id:YusukeOno:20220129080135p:plain
architecture

引用:https://docs.docker.com/get-started/overview/#docker-architecture

手順

基本的には、Host側(macOS)にて作業します。

Docker Desktopをアンインストールする。

Docker Desktop の Mac へのインストール | Docker ドキュメント

  1. Docker メニューから Troubleshoot (トラブルシュート)を選択し、 Uninstall (アンインストール)を選択します。
  2. 確認画面で、Uninstall をクリックします。

さらに、Finderよりアプリケーション>Docker.appをゴミ箱に入れる。

HomebrewでLimaとDocker CLIをインストールする。

> brew install lima docker

確認結果。Docker ClientはARM版であることが確認できる。

> limactl -v
limactl version 0.8.1

> docker version
Client: Docker Engine - Community
 Version:           20.10.12
 API version:       1.41
 Go version:        go1.17.5
 Git commit:        e91ed5707e
 Built:             Sun Dec 12 06:28:24 2021
 OS/Arch:           darwin/arm64
 Context:           default
 Experimental:      true
Cannot connect to the Docker daemon at unix:///var/run/docker.sock. Is the docker daemon running?

Limaを設定し起動する。

LimaのDocker初期セットアップする設定ファイルをGitHubより取得し、Intel版(x86_64)として動作するように記述を加える。

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

docker.yamlファイルを元にVMを起動する。
設定を変更する必要がなければ、"Proceed with the default configuration"を選択する。

> limactl start ~/docker.yaml
? Creating an instance "docker"  [Use arrows to move, type to filter]
> Proceed with the default configuration
  Open an editor to override the configuration
  Exit

選択後、初期セットアップが開始する。(初回は完了まで十分程度かかる)

? Creating an instance "docker" Proceed with the default configuration
INFO[0029] Attempting to download the image from "https://cloud-images.ubuntu.com/impish/current/impish-server-cloudimg-amd64.img"  digest=
:
:
INFO[0352] READY. Run `limactl shell docker` to open the shell.
INFO[0352] To run `docker` on the host (assumes docker-cli is installed), run the following commands:
INFO[0352] ------
INFO[0352] docker context create lima --docker "host=unix:///Users/yusuke.ono/.lima/docker/sock/docker.sock"
INFO[0352] docker context use lima
INFO[0352] docker run hello-world
INFO[0352] ------

続いて、docker context create lima〜docker context use limaを実行する。
(本手順では、環境変数DOCKER_HOSTを使用しない。)

> docker context create lima --docker "host=unix://${HOME}/.lima/docker/sock/docker.sock"
lima
Successfully created context "lima"

> docker context use lima
lima
Current context is now "lima"

確認結果。Hello from Docker!と出力される。

> docker run hello-world
Unable to find image 'hello-world:latest' locally
latest: Pulling from library/hello-world
2db29710123e: Pull complete
Digest: sha256:507ecde44b8eb741278274653120c2bf793b174c06ff4eaa672b713b3263477b
Status: Downloaded newer image for hello-world:latest

Hello from Docker!
This message shows that your installation appears to be working correctly.
:

> docker context ls
NAME      DESCRIPTION                               DOCKER ENDPOINT                                          KUBERNETES ENDPOINT   ORCHESTRATOR
default   Current DOCKER_HOST based configuration   unix:///var/run/docker.sock                                                    swarm
lima *                                              unix:///Users/yusuke.ono/.lima/docker/sock/docker.sock

Lima-VM(NAME:docker)が x86_64 として起動したことを確認する。(STATUS is Running.)

> limactl list
NAME      STATUS     SSH                ARCH      CPUS    MEMORY    DISK      DIR
docker    Running    127.0.0.1:62986    x86_64    4       4GiB      100GiB    /Users/yusuke.ono/.lima/docker

Lima-VM上ではDocker ClientとDocker ServerがAMD64で動作していることが確認できる。

> limactl shell docker docker version
Client: Docker Engine - Community
 Version:           20.10.12
 API version:       1.41
 Go version:        go1.16.12
 Git commit:        e91ed57
 Built:             Mon Dec 13 11:45:33 2021
 OS/Arch:           linux/amd64
 Context:           rootless
 Experimental:      true

Server: Docker Engine - Community
 Engine:
  Version:          20.10.12
  API version:      1.41 (minimum version 1.12)
  Go version:       go1.16.12
  Git commit:       459d0df
  Built:            Mon Dec 13 11:43:41 2021
  OS/Arch:          linux/amd64
  Experimental:     false
 containerd:
  Version:          1.4.12
  GitCommit:        7b11cfaabd73bb80907dd23182b9347b4245eb5d
 runc:
  Version:          1.0.2
  GitCommit:        v1.0.2-0-g52b36a2
 docker-init:
  Version:          0.19.0
  GitCommit:        de40ad0

docker compose v2を導入する。

GitHub - docker/compose: Define and run multi-container applications with Docker

macOSでも、Linuxでの導入手順でOK。

GitHubより releases ページからバイナリを手動でダウンロードし、所定のディレクトリに配置する。
なお、下記の例のバージョン番号(v2.2.3)は、適宜変更する。

> mkdir -p ~/.docker/cli-plugins/
> curl -L https://github.com/docker/compose/releases/download/v2.2.3/docker-compose-darwin-x86_64 -o ~/.docker/cli-plugins/docker-compose
> chmod +x ~/.docker/cli-plugins/docker-compose

確認結果

> docker compose version
Docker Compose version v2.2.3

もし、v1を使用したいならば、brew install docker-composeでインストールする。

トラブルシューティング

Host側(macOS)のdocker composeコマンドでエラーになる。

エラー内容

error getting credentials - err: exec: "docker-credential-desktop": executable file not found in $PATH, out: ``

上記のエラーが出た場合は、Host側(macOS)の ~/.docker/config.json にDocker Desktopでの設定が残っているので、下記コマンドでcredsStoreフィールドを削除する。なお、viエディタなどで当該行を削除しても構わない。

https://docs.docker.com/engine/reference/commandline/login/#credentials-store

> cp -p ~/.docker/config.json ~/.docker/config.json.bak
> cat   ~/.docker/config.json.bak | jq 'del(.credsStore)' > ~/.docker/config.json

確認結果

> diff ~/.docker/config.json.bak ~/.docker/config.json
3d2
<  "credsStore": "desktop",

Lima-VM上でファイルを作成できない。

デフォルトでLima-VMにマウントされたHost側(macOS)のHOMEディレクトリは、Read-onlyになっている。

touch: cannot touch 'aaa.txt': Read-only file system

~/.lima/docker/lima.yaml に mountsキーにおいて、所定のディレクトリにwritable: trueを付与し、以下のコマンドでlima-vmを立ち上げ直して、変更した設定を反映させる。なお、同yamlファイルを修正した際には、lima-vmの停止・起動が必要となる。

> limactl stop docker
> limactl start docker

最後に

limactl で VM をバックグラウンドで起動させておく必要はありますが、特にLima-VMにログインすることもなく、Host側のmacOSからdockerを利用できるので便利です。

参考

github.com