MultipassでローカルのDocker環境構築

Posted by rhoboro on 2024-05-03

Limaを特に困っているわけではないが、設定ファイルの項目が多く個人的には too much だと感じている。 UbuntuのVMを簡単に管理できるMultipassがシンプルで良さそうなので試してみたのでその作業ログ。 ホストのdockerコマンドから操作できるようにしている。

cloud-initファイルの作成

canonical/multipass-blueprintsにあったdocker.yamlをベースにmultipass-docker.yaml を用意した。 cloud-initの内容としては、変更箇所は下記のみ。

  • 自動起動するportainerを削除。使ったことはないけどWeb UIからDocker関連の設定ができるサービスらしい。
  • ホストマシンのdockerコマンドから操作するために2375番ポートでListen

VMの作成

$ multipass launch --name docker --cpus 4 --memory 24G --disk 100G --cloud-init ~/dotfiles/multipass-docker.yaml 22.04

cloud-init が正常に実行されたことを確認。

$ multipass exec docker tail /var/log/cloud-init.log  
2024-05-03 01:16:37,150 - util.py[DEBUG]: Writing to /var/lib/cloud/instance/boot-finished - wb: [644] 70 bytes
2024-05-03 01:16:37,150 - handlers.py[DEBUG]: finish: modules-final/config-final_message: SUCCESS: config-final_message ran successfully
2024-05-03 01:16:37,150 - main.py[DEBUG]: Ran 12 modules with 0 failures
2024-05-03 01:16:37,150 - atomic_helper.py[DEBUG]: Atomically writing to file /var/lib/cloud/data/status.json (via temporary file /var/lib/cloud/data/tmp6z89z6dq) - w: [644] 635 bytes/chars
2024-05-03 01:16:37,151 - atomic_helper.py[DEBUG]: Atomically writing to file /var/lib/cloud/data/result.json (via temporary file /var/lib/cloud/data/tmp087mp3i1) - w: [644] 96 bytes/chars
2024-05-03 01:16:37,151 - util.py[DEBUG]: Creating symbolic link from '/run/cloud-init/result.json' => '../../var/lib/cloud/data/result.json'
2024-05-03 01:16:37,151 - util.py[DEBUG]: Reading from /proc/uptime (quiet=False)
2024-05-03 01:16:37,151 - util.py[DEBUG]: Read 14 bytes from /proc/uptime
2024-05-03 01:16:37,151 - util.py[DEBUG]: cloud-init mode 'modules' took 53.795 seconds (53.79)
2024-05-03 01:16:37,151 - handlers.py[DEBUG]: finish: modules-final: SUCCESS: running modules for final

VM内でdockerコマンドが使えることを確認。 VM内で--rmのように--が含まれるコマンドを実行する場合は、VMの指定とコマンドの間に--が必要らしい。

$ multipass exec docker -- docker run --rm hello-world
Unable to find image 'hello-world:latest' locally
latest: Pulling from library/hello-world
478afc919002: Pull complete 
Digest: sha256:a26bff933ddc26d5cdf7faa98b4ae1e3ec20c4985e6f87ac0973052224d24302
Status: Downloaded newer image for hello-world:latest

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

To generate this message, Docker took the following steps:
 1. The Docker client contacted the Docker daemon.
 2. The Docker daemon pulled the "hello-world" image from the Docker Hub.
    (arm64v8)
 3. The Docker daemon created a new container from that image which runs the
    executable that produces the output you are currently reading.
 4. The Docker daemon streamed that output to the Docker client, which sent it
    to your terminal.

To try something more ambitious, you can run an Ubuntu container with:
 $ docker run -it ubuntu bash

Share images, automate workflows, and more with a free Docker ID:
 https://hub.docker.com/

For more examples and ideas, visit:
 https://docs.docker.com/get-started/

ホストマシンのdockerコマンドで操作できるようにする

ホストマシンからdockerコマンドが実行できることも確認。

$ multipass info docker
Name:           docker
State:          Running
Snapshots:      0
IPv4:           192.168.64.9
                172.17.0.1
Release:        Ubuntu 22.04.4 LTS
Image hash:     3d803c091384 (Ubuntu 22.04 LTS)
CPU(s):         4
Load:           0.09 0.23 0.12
Disk usage:     2.2GiB out of 96.8GiB
Memory usage:   247.1MiB out of 23.4GiB
Mounts:         --

-HオプションでVM内のdockerdに接続している。

# ホストのdockerコマンド
$ docker -H 192.168.64.9:2375 run --rm hello-world

Hello from Docker!
...

Docker Contextを作ってコマンドで切り替えられるようにした。

# これ相当
# docker context create multipass-docker --docker "host=tcp://$(multipass info docker --format json | jq -r '.info.docker.ipv4[0]'):2375"
$ docker context create multipass-docker --docker "host=tcp://192.168.64.9:2375"
multipass-docker
Successfully created context "multipass-docker"

$ docker context use multipass-docker
multipass-docker
Current context is now "multipass-docker"

$ docker run --rm hello-world

Hello from Docker!
...

ホストマシンからVMへのPort Forwardingは未実装

Issue Port forwarding #309 がオープンの状態。 docker run -p 8888:80 ... のように立ち上げたWebサービスにホストマシンのブラウザからアクセスするには、VMのIPを直接指定してアクセスする形が一番楽。 このあたりはhosts書き換え、SSH Port Forwardingなど好みに合わせ行えば良さそう。

マウントによるホストマシンとのデータ共有

/Users/private/Volumesをマウントした。 これらは https://docs.docker.com/desktop/settings/mac/#file-sharing でデフォルトでマウントされている。

$ multipass mount /Users docker:/Users
$ multipass mount /private docker:/private
$ multipass mount /Volumes docker:/Volumes
ultipass info docker
Name:           docker
State:          Running
Snapshots:      0
IPv4:           192.168.64.9
                172.17.0.1
Release:        Ubuntu 22.04.4 LTS
Image hash:     3d803c091384 (Ubuntu 22.04 LTS)
CPU(s):         4
Load:           0.03 0.11 0.09
Disk usage:     2.2GiB out of 96.8GiB
Memory usage:   251.9MiB out of 23.4GiB
Mounts:         /Users   => /Users
                    UID map: 501:default
                    GID map: 20:default
                /private => /private
                    UID map: 501:default
                    GID map: 20:default
                /Volumes => /Volumes
                    UID map: 501:default
                    GID map: 20:default

動作確認

現在メインで開発しているプロジェクトでdocker compose upやデータの書き込みを行ったが特に問題なさそう。 しばらくこれで開発してみる。

tags: Docker