limaを使ってみた

Docker Desktopの一部有償化を受けてlimaとdockerを組み合わせて利用する場面が増えているっぽい。 ということでlimaを触ってみることにした。 今回はlimaの基本的な使い方だけ。 dockerと組み合わせた活用方法はまた後で。

limaとは?

MacOSの環境でLinuxVMを提供するソフトウェア。 containerd + nerdctlな環境をMacユーザに提供することが目的で開発されている。

github.com

limaをインストールする

homebrewで入れるだけでOK。

brew install lima

sampleという名前でインスタンスを起動する

lima start <インスタンス名>と実行する。 インスタンス名を入れない場合はdefaultというインスタンス名になる。

$ limactl start sample

? Creating an instance "sample"  [Use arrows to move, type to filter]
> Proceed with the default configuration
  Open an editor to override the configuration
  Exit

ここでconfigに関する選択肢が表示される。 このconfigでディストリビューションを指定したり、instanceに割り当てるリソースを指定したりできる。

  • Proceed with the default configuration:デフォルトのconfigをそのまま利用する
  • Open an editor to override the configuration:デフォルトをベースにconfigをカスタマイズする

今回はcpus:4→2に変更して起動してみる。 Open an editor to override the configurationを選択するとエディタが起動してyamlの編集画面に入るので、そこで cpusの値を変更すればOK。 yamlの編集を終えるとインスタンスが起動する。

INFO[0179] Attempting to download the image from "~/Downloads/impish-server-cloudimg-amd64.img"  digest=
INFO[0179] Attempting to download the image from "https://cloud-images.ubuntu.com/impish/current/impish-server-cloudimg-amd64.img"  digest=
INFO[0179] Using cache "/Users/<user>/Library/Caches/lima/download/by-url-sha256/ac74da77a6828e35de7edaa06fdbb33d12ef97cce2726550017e3c1066c88fb1/data"
INFO[0179] Attempting to download the nerdctl archive from "https://github.com/containerd/nerdctl/releases/download/v0.15.0/nerdctl-full-0.15.0-linux-amd64.tar.gz"  digest="sha256:ca40d99d257e69f0220bb1cbdab1b602032692f45f713c901f328d2f4e3c12b3"
INFO[0179] Using cache "/Users/<user>/Library/Caches/lima/download/by-url-sha256/0528f21ffeedfade0c993f8323bdfb5b26dfbdc7c67702a5188ca25c15d755a1/data"
INFO[0181] [hostagent] Starting QEMU (hint: to watch the boot progress, see "/Users/<user>/.lima/sample/serial.log")
INFO[0181] SSH Local Port: 64937
INFO[0181] [hostagent] Waiting for the essential requirement 1 of 5: "ssh"
INFO[0209] [hostagent] Waiting for the essential requirement 1 of 5: "ssh"
INFO[0235] [hostagent] The essential requirement 1 of 5 is satisfied
INFO[0235] [hostagent] Waiting for the essential requirement 2 of 5: "user session is ready for ssh"
INFO[0235] [hostagent] The essential requirement 2 of 5 is satisfied
INFO[0235] [hostagent] Waiting for the essential requirement 3 of 5: "sshfs binary to be installed"
INFO[0250] [hostagent] The essential requirement 3 of 5 is satisfied
INFO[0250] [hostagent] Waiting for the essential requirement 4 of 5: "/etc/fuse.conf to contain \"user_allow_other\""
INFO[0290] [hostagent] Waiting for the essential requirement 4 of 5: "/etc/fuse.conf to contain \"user_allow_other\""
INFO[0290] [hostagent] The essential requirement 4 of 5 is satisfied
INFO[0290] [hostagent] Waiting for the essential requirement 5 of 5: "the guest agent to be running"
INFO[0290] [hostagent] The essential requirement 5 of 5 is satisfied
INFO[0290] [hostagent] Mounting "/Users/<user>"
INFO[0291] [hostagent] Mounting "/tmp/lima"
INFO[0291] [hostagent] Waiting for the optional requirement 1 of 2: "systemd must be available"
INFO[0291] [hostagent] Forwarding "/run/lima-guestagent.sock" (guest) to "/Users/<user>/.lima/sample/ga.sock" (host)
INFO[0291] [hostagent] The optional requirement 1 of 2 is satisfied
INFO[0291] [hostagent] Not forwarding TCP 127.0.0.53:53
INFO[0291] [hostagent] Not forwarding TCP 0.0.0.0:22
INFO[0291] [hostagent] Waiting for the optional requirement 2 of 2: "containerd binaries to be installed"
INFO[0291] [hostagent] Not forwarding TCP [::]:22
INFO[0291] [hostagent] The optional requirement 2 of 2 is satisfied
INFO[0291] [hostagent] Waiting for the final requirement 1 of 1: "boot scripts must have finished"
INFO[0306] [hostagent] The final requirement 1 of 1 is satisfied
INFO[0306] READY. Run `limactl shell sample` to open the shell.

ちなみに:yamlのサンプルが公開されている

yamlの例は https://github.com/lima-vm/lima/tree/master/examples にある。カスタマイズするときに参考にすると良さそう。

起動したインスタンスを確認する

limactl listインスタンスの一覧を見ることができる。 CPUSが2の状態で起動できていることがわかる。

$ limactl list
NAME      STATUS     SSH                ARCH      CPUS    MEMORY    DISK      DIR
sample    Running    127.0.0.1:64937    x86_64    2       4GiB      100GiB    /Users/<user>/.lima/sample

DIRの項目から察しが付くかもしれないが、~/.lima/sample配下にインスタンスに関するファイル群が置かれている。 ちなみにこの中にあるlima.yamlインスタンスのconfigを表したyamlファイルである。 上述のdefault.yamlを比較してみるとよい。

$ ls -l ~/.lima/sample
total 3283640
-rw-r--r--  1 <user>  staff  582221824  1 10 20:59 basedisk
-rw-r--r--  1 <user>  staff  208906240  1 10 20:59 cidata.iso
-rw-r--r--  1 <user>  staff  876937216  1 10 21:11 diffdisk
srw-------  1 <user>  staff          0  1 10 21:01 ga.sock
-rw-r--r--  1 <user>  staff          6  1 10 20:59 ha.pid
srwxr-xr-x  1 <user>  staff          0  1 10 20:59 ha.sock
-rw-r--r--  1 <user>  staff      20510  1 10 21:02 ha.stderr.log
-rw-r--r--  1 <user>  staff        167  1 10 21:02 ha.stdout.log
-rw-r--r--  1 <user>  staff      12093  1 10 20:59 lima.yaml
-rw-------  1 <user>  staff          6  1 10 20:59 qemu.pid
srwxr-xr-x  1 <user>  staff          0  1 10 20:59 qmp.sock
-rw-r--r--  1 <user>  staff     111127  1 10 21:02 serial.log
srwxr-xr-x  1 <user>  staff          0  1 10 20:59 serial.sock
srw-------  1 <user>  staff          0  1 10 21:00 ssh.sock

shellを起動する

limactl shell <インスタンス名>でlimaのshellを起動できる。

$ limactl shell sample
<user>@lima-sample:/Users/<user>$ ls -l
total 49324
drwx------ 1 <user> dialout       96 Sep  7  2020  Applications
drwx------ 1 <user> dialout      704 Dec  7 01:52  Desktop
drwx------ 1 <user> dialout      160 Oct  4 05:56  Documents

...

limactl shell <インスタンス名> <コマンド>とすればインスタンスに入らなくてもコマンドを実行できる。

$ limactl shell sample ls -l
<user>@lima-sample:/Users/<user>$ ls -l
total 49324
drwx------ 1 <user> dialout       96 Sep  7  2020  Applications
drwx------ 1 <user> dialout      704 Dec  7 01:52  Desktop
drwx------ 1 <user> dialout      160 Oct  4 05:56  Documents

...

lsの結果の通り、MacOS上のホームディレクトリがreadonlyでボリュームマウントされるっぽい。 yamlでもそのように定義されている。 一応書き込み権限は変更できるがyamlのコメントuntested and dangerousの通りやめておいたほうが良さそう。

$ cat /Users/<user>/.lima/sample/lima.yaml
# ===================================================================== #
# BASIC CONFIGURATION
# ===================================================================== #

...

# Expose host directories to the guest, the mount point might be accessible from all UIDs in the guest
# Default: none
mounts:
  - location: "~"
    # CAUTION: `writable` SHOULD be false for the home directory.
    # Setting `writable` to true is possible, but untested and dangerous.
    writable: false
  - location: "/tmp/lima"
    writable: true

ちなみに:limaというlima shell defaultへのエイリアスがある

defaultというインスタンスで起動している場合はlimaというエイリアスでshellを起動できる。 もしくは環境変数LIMA_INSTANCE=<インスタンス名>をセットすれば他のインスタンスでもエイリアスを利用可能。

$ lima --help
Usage: lima [COMMAND...]

lima is an alias for "limactl shell default".
The instance name ("default") can be changed by specifying $LIMA_INSTANCE.

See `limactl shell --help` for further information.
$ LIMA_INSTANCE=sample lima uname -n;
lima-sample

nerdctlでコンテナを起動してみる

nerdctlでnginxコンテナを起動してみる。

$ limactl shell sample nerdctl run -d --name nginx -p 127.0.0.1:8080:80 nginx:alpine
docker.io/library/nginx:alpine:                                                   resolved       |++++++++++++++++++++++++++++++++++++++|
index-sha256:eb05700fe7baa6890b74278e39b66b2ed1326831f9ec3ed4bdc6361a4ac2f333:    done           |++++++++++++++++++++++++++++++++++++++|
manifest-sha256:544ba2bfe312bf2b13278495347bb9381ec342e630bcc8929af124f1291784bb: done           |++++++++++++++++++++++++++++++++++++++|
config-sha256:cc44224bfe208a46fbc45471e8f9416f66b75d6307573e29634e7f42e27a9268:   done           |++++++++++++++++++++++++++++++++++++++|
layer-sha256:40e5d2fe5bcd566dbde3e961f33ced0f1503fc6ee320a427b185a07afe2f96ae:    done           |++++++++++++++++++++++++++++++++++++++|
layer-sha256:59bf1c3509f33515622619af21ed55bbe26d24913cedbca106468a5fb37a50c3:    done           |++++++++++++++++++++++++++++++++++++++|
layer-sha256:f3322597df46099a66ed5773c10a9d1cb587faca7be14ceba985e3d1fbfdbc36:    done           |++++++++++++++++++++++++++++++++++++++|
layer-sha256:d09cf91cabdcf5f64672598b8e4da9b0b7d8546e83ec49633bdd92abb994ba61:    done           |++++++++++++++++++++++++++++++++++++++|
layer-sha256:3a97535ac2efcf94ab3e5f93a6ec4d934469de66909f17ba1229f86ee660970a:    done           |++++++++++++++++++++++++++++++++++++++|
layer-sha256:919ade35f869e23d663ea51fdf2e99aa183239a73b4b4780e052c8b248ed5b7e:    done           |++++++++++++++++++++++++++++++++++++++|
elapsed: 10.6s                                                                    total:  9.7 Mi (937.8 KiB/s)                       
449379ddeb21602e71e198fa34ab54058767027f50b9fede47060566e0c67bf7

$ limactl shell sample nerdctl ps
CONTAINER ID    IMAGE                             COMMAND                   CREATED          STATUS    PORTS                     NAMES
449379ddeb21    docker.io/library/nginx:alpine    "/docker-entrypoint.…"    3 minutes ago    Up        127.0.0.1:8080->80/tcp    nginx

ホストからcurlするとnginxコンテナへ接続できることが確認できる。

$ curl --head 127.0.0.1:8080
HTTP/1.1 200 OK
Server: nginx/1.21.5
Date: Mon, 10 Jan 2022 13:12:50 GMT
Content-Type: text/html
Content-Length: 615
Last-Modified: Tue, 28 Dec 2021 18:48:00 GMT
Connection: keep-alive
ETag: "61cb5be0-267"
Accept-Ranges: bytes

インスタンスの停止

lima stop <インスタンス名>でOK。

$ limactl stop sample
INFO[0000] Sending SIGINT to hostagent process 85032
INFO[0000] Waiting for the host agent and the qemu processes to shut down
INFO[0000] [hostagent] Received SIGINT, shutting down the host agent
INFO[0000] [hostagent] Shutting down the host agent
INFO[0000] [hostagent] Stopping forwarding "/run/lima-guestagent.sock" (guest) to "/Users/<user>/.lima/sample/ga.sock" (host)
INFO[0000] [hostagent] Unmounting "/Users/<user>"
INFO[0000] [hostagent] Unmounting "/tmp/lima"
INFO[0000] [hostagent] Shutting down QEMU with ACPI
INFO[0000] [hostagent] Sending QMP system_powerdown command
INFO[0001] [hostagent] QEMU has exited
$ limactl list
NAME      STATUS     SSH            ARCH      CPUS    MEMORY    DISK      DIR
sample    Stopped    127.0.0.1:0    x86_64    2       4GiB      100GiB    /Users/<user>/.lima/sample

今回はここまで。 次回はlima + dockerのことを書こうかな。