dshimizu/blog

Something I Learned.

macOS へ Lima をインストールして Docker を動かしてみたときのメモ

はじめに

macOS 上で Docker を実行するには Docker Desktop を使うのが一番楽かと思いますが、他のやり方として Lima を使ってやってみたのでメモ書きです。

Lima

macOS で containerd を広めることを目的としたプロジェクトであるらしいです。 containerd, nerdctl が入ったLinux仮想マシンを起動できます。(Docker の機能の1つに containerd ランタイムを動かすというのもありますが先駆者的な位置付けであったのもあってか独自の仕様が利用されているらしいのに対して、共通インターフェースとなる CRI が登場し、また containerd の機能が充実してきたことで、CRI に則った nerdctl という containerd ランタイムを動かすためのソフトウェアが登場した、といった感じのようです)

ただ、Lima でも Docker も利用可能であるようです。

macOS へのセットアップ

macOS へセットアップしてみます。

Lima インストール

Lima をインストールします。

% brew install lima

2023/10/30 時点ではバージョンは下記でした。

% lima -v
limactl version 0.18.0

limactl コマンドを触ってみる

limactl というコマンドが提供されています。 ヘルプを見てみます。

% limactl help
Lima: Linux virtual machines

Usage:
  limactl [command]

Examples:
  Start the default instance:
  $ limactl start

  Open a shell:
  $ lima

  Run a container:
  $ lima nerdctl run -d --name nginx -p 8080:80 nginx:alpine

  Stop the default instance:
  $ limactl stop

  See also template YAMLs: /usr/local/share/lima/templates

Available Commands:
  completion    Generate the autocompletion script for the specified shell
  copy          Copy files between host and guest
  create        Create an instance of Lima
  delete        Delete an instance of Lima.
  disk          Lima disk management
  edit          Edit an instance of Lima
  factory-reset Factory reset an instance of Lima
  help          Help about any command
  info          Show diagnostic information
  list          List instances of Lima.
  protect       Protect an instance to prohibit accidental removal
  prune         Prune garbage objects
  shell         Execute shell in Lima
  show-ssh      Show the ssh command line (DEPRECATED; use `ssh -F` instead)
  snapshot      Manage instance snapshots
  start         Start an instance of Lima
  stop          Stop an instance
  sudoers       Generate the content of the /etc/sudoers.d/lima file
  unprotect     Unprotect an instance
  validate      Validate YAML files

Flags:
      --debug              debug mode
  -h, --help               help for limactl
      --log-level string   Set the logging level [trace, debug, info, warn, error]
      --tty                Enable TUI interactions such as opening an editor. Defaults to true when stdout is a terminal. Set to false for automation. (default true)
  -v, --version            version for limactl

Use "limactl [command] --help" for more information about a command.

Lima VM の操作

limactl start を実行すると、そのまま default という名前の VM が起動します。

% limactl start

特定の名前の VM を作成するには、start の後に名前を指定します。

% limactl start testvm

いくつか対話的なやり取りが発生しますが、とりあえずデフォルトでやります。

INFO[0000] Creating an instance "testvm" from template://default (Not from template://testvm)
WARN[0000] This form is deprecated. Use `limactl create --name=testvm template://default` instead
? Creating an instance "testvm"  [Use arrows to move, type to filter]
> Proceed with the current configuration
  Open an editor to review or modify the current configuration
  Choose another template (docker, podman, archlinux, fedora, ...)
  Exit

しばらく待つと VM が作成され、起動します。 limactl ls コマンドで作成された VM のリストを見ることができます。

% limactl ls
NAME      STATUS     SSH                VMTYPE    ARCH      CPUS    MEMORY    DISK      DIR
default    Running    127.0.0.1:60022    qemu      x86_64    4       4GiB      100GiB    ~/.lima/default
testvm     Running    127.0.0.1:50751    qemu      x86_64    4       4GiB      100GiB    ~/.lima/testvm

limactl shell で Lima VM へ接続します。

% limactl shell testvm
lima@lima-testvm:/Users/dshimizu$ id
uid=502(lima) gid=1000(lima) groups=1000(lima)

default の VM の場合は lima コマンドで limactl shell default 相当のことができます。

% lima
lima@lima-default:/Users/dshimizu$

/usr/local/bin/lima では limactl shell default が実行されるような形でした。

#!/bin/sh
set -eu
: "${LIMA_INSTANCE:=default}"
: "${LIMA_SHELL:=}"
: "${LIMA_WORKDIR:=}"
: "${LIMACTL:=limactl}"

if [ "$#" -eq 1 ]; then
  if [ "$1" = "-h" ] || [ "$1" = "--help" ]; then
    base="$(basename "$0")"
    echo "Usage: ${base} [COMMAND...]"
    echo
    echo "${base} is an alias for \"${LIMACTL} shell ${LIMA_INSTANCE}\"."
    echo "The instance name (\"${LIMA_INSTANCE}\") can be changed by specifying \$LIMA_INSTANCE."
    echo
    echo "The shell and initial workdir inside the instance can be specified via \$LIMA_SHELL"
    echo "and \$LIMA_WORKDIR."
    echo
    echo "See \`${LIMACTL} shell --help\` for further information."
    exit 0
  elif [ "$1" = "-v" ] || [ "$1" = "--version" ]; then
    exec "$LIMACTL" "$@"
  fi
fi

set - "$LIMA_INSTANCE" "$@"
if [ -n "${LIMA_SHELL}" ]; then
  set - --shell "$LIMA_SHELL" "$@"
fi
if [ -n "${LIMA_WORKDIR}" ]; then
  set - --workdir "$LIMA_WORKDIR" "$@"
fi
# Avoid converting paths with MSYS2
MSYS2_ARG_CONV_EXCL="*"
export MSYS2_ARG_CONV_EXCL
exec "$LIMACTL" shell "$@"

設定ファイルは ~/.lima/ に配置されるようです。 VM名の lima.yamlVM の設定ファイルのようです。

% tree -L 2 ~/.lima/
/Users/daisukeshimizu/.lima/
├── _config
│   ├── networks.yaml
│   ├── user
│   └── user.pub
├── default
│   ├── basedisk
│   ├── cidata.iso
│   ├── diffdisk
│   ├── ga.sock
│   ├── ha.pid
│   ├── ha.sock
│   ├── ha.stderr.log
│   ├── ha.stdout.log
│   ├── lima.yaml
│   ├── qemu.pid
│   ├── qmp.sock
│   ├── serial.log
│   ├── serial.sock
│   ├── serialv.log
│   ├── serialv.sock
│   ├── ssh.config
│   └── ssh.sock
└── testvm
    ├── basedisk
    ├── cidata.iso
    ├── diffdisk
    ├── ga.sock
    ├── ha.pid
    ├── ha.sock
    ├── ha.stderr.log
    ├── ha.stdout.log
    ├── lima.yaml
    ├── qemu.pid
    ├── qmp.sock
    ├── serial.log
    ├── serial.sock
    ├── serialv.log
    ├── serialv.sock
    ├── ssh.config
    └── ssh.sock

Docker を使ってみる

Lima の VM に Docker Server をインストールし、macOS を Docker クライアントをインストールして、少し触ってみます。

Docker クライアントのセットアップ

macOS へ Docker CLI インストール

Docker CLI (クライアント)をインストールします。

% curl -OL https://download.docker.com/mac/static/stable/x86_64/docker-24.0.7.tgz
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
100 16.3M  100 16.3M    0     0  4157k      0  0:00:04  0:00:04 --:--:-- 4167k

バージョンを見てみます。この時点では Server の情報は出てこず、 Client の情報のみ出てきます。

% docker version
Client:
 Cloud integration: v1.0.29
 Version:           20.10.21
 API version:       1.41
 Go version:        go1.18.7
 Git commit:        baeda1f
 Built:             Tue Oct 25 18:01:18 2022
 OS/Arch:           darwin/amd64
 Context:           default
 Experimental:      true

macOS へ Docker Compose Plugin インストール

Docker Compose Plugin をインストールします。

% curl -SL https://github.com/docker/compose/releases/download/v2.2.2/docker-compose-darwin-x86_64 -o ~/.docker/cli-plugins/docker-compose
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
  0     0    0     0    0     0      0      0 --:--:-- --:--:-- --:--:--     0
100 26.0M  100 26.0M    0     0  7913k      0  0:00:03  0:00:03 --:--:-- 9667k

実行権限を付与します。

% chmod +x ~/.docker/cli-plugins/docker-compose
% docker compose version
Docker Compose version v2.13.0

Docker Server のセットアップ

Lima VM への Docker インストール

get.docker.comスクリプトがあるので、 Lima で起動した VM にパイプで渡して実行できるので実行します。

% curl -fsSL https://get.docker.com | limactl shell testvm

Lima VM で Docker を設定して起動します。

% limactl shell testvm
lima@lima-testvm:/Users/dshimizu$

/etc/docker/daemon.jsonを作成します。

lima@lima-testvm:/Users/dshimizu$ sudo vim /etc/docker/daemon.json

以下のように記述します。

{
    "hosts": [
        "tcp://127.0.0.1:2375",
        "unix:///var/run/docker.sock"
    ]
}

/etc/systemd/system/docker.service.d/override.conf を作成します。

lima@lima-testvm:/Users/dshimizu$ sudo vim /etc/docker/daemon.json

以下のように記述します。

[Service]
ExecStart=  # この記述も必要
ExecStart=/usr/bin/dockerd   # 上書きする設定
lima@lima-testvm:/Users/dshimizu$ sudo systemctl daemon-reload
lima@lima-testvm:/Users/dshimizu$ sudo systemctl start docker
lima@lima-testvm:/Users/dshimizu$  sudo docker ps
CONTAINER ID   IMAGE     COMMAND   CREATED   STATUS    PORTS     NAMES

Lima VMをDocker ホストとして指定するために DOCKER_HOST 環境変数を指定します。

% echo  "export DOCKER_HOST='tcp://127.0.0.1:2375'" >> $HOME/.profile
% source $HOME/.profile

ここでは TCP を使ってますが、下記のテンプレートに相当することができればUnixドメインソケットでも大丈夫なようです。

これで macOS から Lima VM の Docker に接続できるようになりました。

% docker version
Client:
 Cloud integration: v1.0.29
 Version:           20.10.21
 API version:       1.41
 Go version:        go1.18.7
 Git commit:        baeda1f
 Built:             Tue Oct 25 18:01:18 2022
 OS/Arch:           darwin/amd64
 Context:           default
 Experimental:      true

Server: Docker Engine - Community
 Engine:
  Version:          24.0.7
  API version:      1.43 (minimum version 1.12)
  Go version:       go1.20.10
  Git commit:       311b9ff
  Built:            Thu Oct 26 09:07:58 2023
  OS/Arch:          linux/amd64
  Experimental:     false
 containerd:
  Version:          v1.7.7
  GitCommit:        8c087663b0233f6e6e2f4515cee61d49f14746a8
 runc:
  Version:          1.1.9
  GitCommit:        v1.1.9-0-gccaecfcb
 docker-init:
  Version:          0.19.0
  GitCommit:        de40ad0

コンテナ起動

コンテナを起動してみます。

% docker run --name some-nginx -d -p 8080:80 nginx

まとめ

Lima を触って、Docker コンテナを実行してみました。

nerdctl はまだわかっていないので次はその辺りを触ってみようかと思います。

参考