MacでLimaを使ってDockerを動かしてみた

カイポケの SRE 担当の有賀です。

社内では Mac で Docker Desktop を使うのが標準的になっている中、 Docker Desktop 以外の選択肢も試してみようと思い、 Docker Desktop や、社内で使っている人のいた Rancher Desktop を調べはじめました。その仕組みを調べている中で Rancher Desktop が採用している Lima がGUIを利用しない用途だと必要十分と感じたため、 Lima を使うことにしました。

Macを使って検証・構築しているため、Macでの仕組み・動作が前提になっています。

Docker を動かす仕組み(前提)

Docker Desktop と Rancher Desktop の仕組みを見ていきます。 基本的には Docker を Mac 上で動かすためには仮想環境上にLinuxを建ててその上で dockerd を動かしているため、どちらも似たような構成になっています。

Docker Desktop

Docker Desktop を動かす場合には、現在だと Apple の Virtualization framework を使って Linux 仮想マシンを動かしています。 その上で dockerd, containerd が動いており、この dockerd, containerd 上で Docker コンテナ を作って我々は Docker を利用できるようになっています。

参考程度にですが、以下のコマンドを実行すると、図で書いた Linux マシンに入れるので、 ps コマンドなどで dockerd が動いているのが確認できます。

docker run -it --rm --privileged --pid=host alpine:edge nsenter -t 1 -m -u -n -i sh
/ # ps aux | grep dockerd
    2 root      0:00 dockerd --host-gateway-ip=198.19.248.254

余談ですが、一昔前までは Hypervisor が使われており、Mac上でDockerを動かすと遅いと言われる一因となっていたようです。また、現在でも Docker Desktop の設定から切り替えることが出来ます。

Rancher Desktop

Rancher Desktop を動かす場合には、公式ページ に載っている以下の図のように、Lima/QEMUを使ってLinux仮想マシンを動かしています。 こちらもDocker Desktop同様、そのLinux上で containerd/dockerd を動かしています。

図は https://rancherdesktop.io/ より引用

Rancher Desktop が提供しているのはこの仕組みと、図の通りDocker CLIを始めとするいくつかのCLIツールや、Lima などの OSS とGUIのインターフェースをまとめて提供するものになっています。

つまり、GUI を必要としない場合、 Docker CLI や Lima を各々インストールすれば、Docker を動かすことが可能になりそうだということが、Rancher Desktop を調べていてわかりました。

Lima を使ってみる

Limaは先述した Rancher Desktop や Finch などの一部で使われている Mac 上で Linux 仮想マシンを動かすためのOSSです。 今回、筆者はGUIを必要としておらず、Linux仮想マシンへのアクセスが容易な点もあり Lima で Docker を動かすことにしました。

Lima は基本的には QEMU での仮想マシンの立ち上げを行いますが、Docker Desktopが利用している Virtualization を使った仮想化も対応しているため、速度の比較も行いました。

検証したマシンは Apple M2 Max で メモリ 64GB です。

インストール

brew を使って簡単にインストール出来ます。

$ brew install lima

起動

dockerd が入った仮想マシンを動かすためのテンプレートが Lima には用意されています。 そのテンプレートを使って仮想マシンを起動していきます。

以下のコマンドを打つことで、 テンプレート にある dockerd が入った仮想マシンを起動することが出来ます。

$ limactl start --name=default template://docker

選択肢が出てくるので「Proceed with the current configuration」を選択します。 しばらく待っていると、仮想マシンの立ち上げが完了するので、以下のコマンドで仮想マシンの list を見ると、 qemu を使って起動されていることがわかります。

$ limactl list
NAME        STATUS     SSH                VMTYPE    ARCH       CPUS    MEMORY    DISK      DIR
default     Running    127.0.0.1:60022    qemu      aarch64    4       4GiB      100GiB    ~/.lima/default

また、lima の仮想マシン上で実際 Linux が動いていることを以下のコマンドなどで確認することが出来ます。

$ lima uname -a
Linux lima-default 5.15.0-72-generic #79-Ubuntu SMP Tue Apr 18 16:53:43 UTC 2023 aarch64 aarch64 aarch64 GNU/Linux

Docker CLI をインストールする

Docker CLI のインストールは Dockerの公式 に書いてあるのでそれを参考に実施します。

$ curl -O https://download.docker.com/mac/static/stable/aarch64/docker-24.0.2.tgz
$ tar xzvf docker-24.0.2.tgz
$ sudo xattr -rc docker
$ sudo cp docker/docker /usr/local/bin/ # 当然 /usr/local/bin に置かなくても使えるので、必要なければこれは実施しなくても良い

HelloWorldをしてみる

Lima の中の dockerdにアクセスできるようにして、上記でインストールした Docker CLI を使って hello world をしてみます。

DOCKER_HOST を Lima に向けてから、hello-world を動かします。

$ export DOCKER_HOST=unix://$HOME/.lima/default/sock/docker.sock
$ docker run hello-world
~ 省略 ~
Hello from Docker!
~ 省略 ~

無事、動作が確認できました。

Virtualization を使った仮想マシンで Dockerd を動かして比較する

QEMU よりも Virtualization framework を使った仮想化のほうが実行速度が早いとのことなので、実際に試してみます。

Virtualization を使った仮想マシンで Dockerd を動かす

Virtualization を使った仮想マシンを起動するには以下のコマンドで起動できますが、dockerd は入っていないので、https://github.com/lima-vm/lima/blob/master/examples/experimental/vz.yaml を元に docker をインストールするように修正したものを指定する必要があります。

$ limactl start --name=vz template://experimental/vz

以下のように用意した vz-custom.yml テンプレートを使うようにコマンドを打って、仮想マシンを立ち上げると、Virtualization を使った仮想マシンでDockerd を動かすことが出来ます。

vz-custom.yml

vmType: "vz"
rosetta:
  enabled: true
  binfmt: true

images:
- location: "https://cloud-images.ubuntu.com/releases/22.04/release/ubuntu-22.04-server-cloudimg-amd64.img"
  arch: "x86_64"
- location: "https://cloud-images.ubuntu.com/releases/22.04/release/ubuntu-22.04-server-cloudimg-arm64.img"
  arch: "aarch64"

mounts:
- location: "~"
- location: "/tmp/lima"
  writable: true
mountType: "virtiofs"

networks:
- vzNAT: true

containerd:
  system: false
  user: false

provision:
- mode: system
  script: |
    #!/bin/sh
    sed -i 's/host.lima.internal.*/host.lima.internal host.docker.internal/' /etc/hosts
- mode: system
  script: |
    #!/bin/bash
    set -eux -o pipefail
    command -v docker >/dev/null 2>&1 && exit 0
    export DEBIAN_FRONTEND=noninteractive
    curl -fsSL https://get.docker.com | shrootless
    systemctl disable --now docker
    apt-get install -y uidmap dbus-user-session
- mode: user
  script: |
    #!/bin/bash
    set -eux -o pipefail
    systemctl --user start dbus
    dockerd-rootless-setuptool.sh install
    docker context use rootless
probes:
- script: |
    #!/bin/bash
    set -eux -o pipefail
    if ! timeout 30s bash -c "until command -v docker >/dev/null 2>&1; do sleep 3; done"; then
      echo >&2 "docker is not installed yet"
      exit 1
    fi
    if ! timeout 30s bash -c "until pgrep rootlesskit; do sleep 3; done"; then
      echo >&2 "rootlesskit (used by rootless docker) is not running"
      exit 1
    fi
  hint: See "/var/log/cloud-init-output.log". in the guest
hostResolver:
  hosts:
    host.docker.internal: host.lima.internal
portForwards:
- guestSocket: "/run/user/{{.UID}}/docker.sock"
  hostSocket: "{{.Dir}}/sock/docker.sock"
message: |
  To run `docker` on the host (assumes docker-cli is installed), run the following commands:
  ------
  docker context create lima-{{.Name}} --docker "host=unix://{{.Dir}}/sock/docker.sock"
  docker context use lima-{{.Name}}
  docker run hello-world
  ------

limactl start --name=vz vz-custom.yml

速度を比較する

速度の比較には、flyway を使った MySQL の DB のマイグレートを行うものがあったのでそれでの比較をしました。

やり方は割愛しますが、以下のような結果になり Lima で Virtualization を使った仮想マシンを利用すれば、今回の利用用途だと、 Docker Desktop と同じ速度で利用できることがわかりました。

Dockerdを動かしているアプリ マイグレートにかかった時間
Lima (QEMU) 61秒
Lima (Virtualization) 45秒
Docker Desktop 46秒

最後に

以上、「Limaを使ってDockerを動かしてみた」について書きました。

そこまで難しいことをしないのであれば Lima (Virtualization) でも十分使えるという結果になりました。 また、Virtualization を使った Colima という Lima で動いているOSS もあるのでこちらを Docker を無料で使いたいことがあれば使うのも良いかと思います。

記載している内容に誤りなどがあれば、 https://twitter.com/BM_SMS_Tech までご連絡ください。