Running a Docker Host under OpenBSD using vmd(8)
920 words, 5 minutes
The OpenBSD virtual machine daemon works pretty well with Linux VMs nowadays. This was time for me to see if I could replace the Synology Docker service with some Docker host provided by vmd(8).
Setup the virtual machine(s) environment
I’m currently running OpenBSD 7.1/amd64. Read the manpage to ensure commands are still valid at the time of reading.
Enable vmd(8):
# rcctl enable vmd
# rcctl start vmd
vmd(ok)
All my vm related stuff go to a dedicated place:
# mkdir /opt/vm
# cd /opt/vm
I’m using Alpine Linux as the Docker Host and use the “Virtual” image for installation:
# ftp \
https://dl-cdn.alpinelinux.org/alpine/v3.16/releases/x86_64/alpine-virt-3.16.2-x86_64.iso
I already have a bridge(4) and a vether(4) interface for other purposes. VMs will be added to the bridge to gain network access.
I don’t want to filter on the tap(4) interface of each VMs. So the pf.conf(5) file has to be modified.
# grep tap /etc/pf.conf
pass on tap
Create the VM and install Alpine Linux
Create the virtual disk, setup vmd and start the VM:
# vmctl create -s 64G docker.qcow2
vmctl: qcow2 imagefile created
# cat /etc/vm.conf
switch "uplink" {
interface bridge0
}
vm "docker" {
disable
memory 2G
cdrom "/opt/vm/alpine-virt-3.16.2-x86_64.iso"
disk "/opt/vm/docker.qcow2"
interface {
switch "uplink"
locked lladdr fe:e1:ba:d2:02:30
}
}
# rcctl restart vmd
# vmctl start -c -B cdrom docker
Connected to /dev/ttyp1 (speed 115200)
(...)
Welcome to Alpine Linux 3.16
Kernel 5.15.59-0-virt on an x86_64 (/dev/ttyS0)
The bootloader detects COM parameters, boots the OS and gets you to the prompt. Read the User Handbook and proceed to installation. The process is quite straight forward. I choosed the “sys” disk layout.
localhost login: root
Welcome to Alpine!
The Alpine Wiki contains a large amount of how-to guides and general
information about administrating Alpine systems.
See <http://wiki.alpinelinux.org/>.
You can setup the system with the command: setup-alpine
You may change this message by editing /etc/motd.
localhost:~# setup-alpine
(...)
Installation is complete. Please reboot.
# poweroff
Modify vm.conf(5) by commenting “disable” and reload vmd to restart the VM automatically.
Setup the Docker host
Connect to the VM using SSH to finish the configuration.
Looking for “docker” in the Alpine Linux packages repository, it shows the repository list has to be updated.
# vi /etc/apk/repositories
(...)
http://dl-cdn.alpinelinux.org/alpine/v3.16/community
# apk update
fetch http://dl-cdn.alpinelinux.org/alpine/v3.16/main/x86_64/APKINDEX.tar.gz
fetch http://dl-cdn.alpinelinux.org/alpine/v3.16/community/x86_64/APKINDEX.tar.gz
v3.16.2-140-gb38ba50d49
[http://dl-cdn.alpinelinux.org/alpine/v3.16/main]
v3.16.2-144-g3f8087714f
[http://dl-cdn.alpinelinux.org/alpine/v3.16/community]
OK: 17026 distinct packages available
# apk add docker
(...)
Executing docker-20.10.16-r3.pre-install
Executing busybox-1.35.0-r17.trigger
Executing ca-certificates-20220614-r0.trigger
OK: 285 MiB in 82 packages
Enable the Docker management for non-root user:
# addgroup myself docker
Have Docker start by default:
# rc-service docker status
* status: stopped
# rc-update add docker
* service docker added to runlevel default
# rc-service docker start
* Caching service dependencies ... [ ok ]
* Mounting cgroup filesystem ... [ ok ]
* /var/log/docker.log: creating file
* /var/log/docker.log: correcting owner
* Starting Docker Daemon ... [ ok ]
# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
And that’s basically all :)
Test the Docker service
Run a simple test container to ensure eveyrthing works properly:
# docker run hello-world
Unable to find image 'hello-world:latest' locally
latest: Pulling from library/hello-world
2db29710123e: Pull complete
Digest:
sha256:7d246653d0511db2a6b2e0436cfd0e52ac8c066000264b3ce63331ac66dca625
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.
(amd64)
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 image ls
REPOSITORY TAG IMAGE ID CREATED SIZE
hello-world latest feb5d9fea6a5 11 months ago 13.3kB
Manage Docker from OpenBSD
Running Docker using OpenBSD’s vmd(8) is great. But managing Docker from the OpenBSD workstation is even greater.
Install the docker-cli package and set the user environment to target the Docker host. Then run the test container to ensure it works remotely and properly.
# pkg_add docker-cli
(...)
docker-cli-20.10.5: ok
# export DOCKER_HOST=ssh://user@docker-host
# docker ps
# docker run hello-world
As an example, an InfluxDB container can be run this way. Connect to the Docker host to prepare things. This means a dedicated storage directory with specific permissions limited to a dedicated user.
# mkdir -p /home/containers/influxdb/etc
# mkdir -p /home/containers/influxdb/data
# addgroup -g 10000 influxdb
# adduser -h /home/containers/influxdb \
-g InfluxDB -s /sbin/nologin -G influxdb \
-D -u 10000 influxdb
# chown -R influxdb:influxdb /home/containers/influxdb
Back to the workstation, populate and run the container.
# docker pull influxdb:1.8
(...)
Status: Downloaded newer image for influxdb:1.8
docker.io/library/influxdb:1.8
# docker run --user 10000:10000 influxdb:1.8 \
influxd config > /home/containers/influxdb/etc/influxdb.conf
Merging with configuration at: /etc/influxdb/influxdb.conf
reporting-disabled = false
bind-address = "127.0.0.1:8088"
(...)
# docker run -d --user 10000:10000 --name influxdb \
--restart=unless-stopped -p 8086:8086 -p 25826:25826/udp \
-v /home/containers/influxdb/data:/var/lib/influxdb \
-v /home/containers/influxdb/etc:/etc/influxdb \
influxdb:1.8
# docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
c8f12af8e96b influxdb:1.8 "/entrypoint.sh infl…" 9 days ago Up 9 days 0.0.0.0:8086->8086/tcp, :::8086->8086/tcp, 0.0.0.0:25826->25826/udp, :::25826->25826/udp influxdb
The InfluxDB service can now be access from tcp/dockerhost:8086. And I can now stop the Docker service on my Synology and only use OpenBSD to play with containers.