NetBSD as a Docker Container

I have this little toy project for quite a while now, and I have this idea of handling a fleet of NetBSD micro-vms with Kubernetes since I started my new job in which I am caring a k8s cluster.

I came to realize that starting a smolBSD micro-vm with Docker was not so difficult after all. Using mksmolnb’s startnb.sh I came up with this very simple Dockerfile:

FROM alpine:latest

RUN apk add --quiet --no-cache qemu-system-x86_64 iproute2 bridge-utils

COPY startnb.sh ./
COPY qemu/qemu-ifup qemu/qemu-ifdown /etc/

CMD /startnb.sh /netbsd-SMOL ${IMG} ${DISK}

qemu-ifup being a simple copy of Debian’s /etc/qemu-ifup.

Build the image

$ docker build -t imil/smolbsd:latest .

Build yourself a smolBSD micro-vm

And fire up the Docker container

$ docker run -it --rm --cap-add NET_ADMIN --device=/dev/kvm --device=/dev/net/tun -v $(pwd)/netbsd-SMOL:/netbsd-SMOL -v $(pwd)/root.img:/root.img imil/smolbsd:latest
WARNING: Image format was not specified for 'root.img' and probing guessed raw.
         Automatically detecting the format is dangerous for raw images, write operations on block 0 will be restricted.
         Specify the 'raw' format explicitly to remove the restrictions.
W: /etc/qemu-ifup: no bridge for guest interface found
[   1.0000000] [ Kernel symbol table invalid! ]
[   1.0000000] multiboot: Information structure flags: 0x0000024f
[   1.0000000] multiboot: Boot loader: qemu
[   1.0000000] multiboot: Command line: /netbsd-SMOL console=com root=ld0a
[   1.0000000] multiboot: 639 KB lower memory, 260980 KB upper memory
[   1.0000000] Copyright (c) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003,
[   1.0000000]     2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013,
[   1.0000000]     2014, 2015, 2016, 2017, 2018, 2019, 2020, 2021, 2022, 2023
[   1.0000000]     The NetBSD Foundation, Inc.  All rights reserved.
[   1.0000000] Copyright (c) 1982, 1986, 1989, 1991, 1993
[   1.0000000]     The Regents of the University of California.  All rights reserved.

[   1.0000000] NetBSD 10.0_BETA (GENERIC) #0: Mon Oct  2 17:39:38 UTC 2023
[   1.0000000]  mkrepro@mkrepro.NetBSD.org:/usr/src/sys/arch/i386/compile/GENERIC
[   1.0000000] total memory = 255 MB
[   1.0000000] avail memory = 228 MB
[   1.0000040] mainbus0 (root)
[   1.0000040] mainbus0: Intel MP Specification (Version 1.4) (BOCHSCPU 0.1         )
[   1.0000040] cpu0 at mainbus0 apid 0
[   1.0000040] ACPI Error: AE_BAD_PARAMETER, Thread 3244697728 could not acquire Mutex [ACPI_MTX_Tables] (0x2) (20221020/utmutex-326)
[   1.0000040] cpu0: QEMU Virtual CPU version 2.5+, id 0x60fb1
[   1.0000040] cpu0: node 0, package 0, core 0, smt 0
[   1.0000040] ioapic0 at mainbus0 apid 0
[   1.0000040] pci0 at mainbus0 bus 0: configuration mode 1
[   1.0000040] Intel 82441FX (PMC) PCI and Memory Controller (host bridge, revision 0x02) at pci0 dev 0 function 0 not configured
[   1.0000040] Intel 82371SB (PIIX3) PCI-ISA Bridge (ISA bridge) at pci0 dev 1 function 0 not configured
[   1.0000040] Intel 82371SB (PIIX3) IDE Interface (IDE mass storage, interface 0x80) at pci0 dev 1 function 1 not configured
[   1.0000040] Intel 82371AB (PIIX4) Power Management Controller (miscellaneous bridge, revision 0x03) at pci0 dev 1 function 3 not configured
[   1.0000040] vendor 1234 product 1111 (VGA display, revision 0x02) at pci0 dev 2 function 0 not configured
[   1.0000040] virtio0 at pci0 dev 3 function 0
[   1.0000040] virtio0: network device (id 1, rev. 0x00)
[   1.0000040] vioif0 at virtio0: features: 0x31870020<EVENT_IDX,INDIRECT_DESC,NOTIFY_ON_EMPTY,CTRL_MAC,CTRL_RX,CTRL_VQ,STATUS,MAC>
[   1.0000040] vioif0: Ethernet address 52:54:00:12:34:56
[   1.0000040] virtio0: config interrupting at msix0 vec 0
[   1.0000040] virtio0: queues interrupting at msix0 vec 1
[   1.0000040] virtio1 at pci0 dev 4 function 0
[   1.0000040] virtio1: block device (id 2, rev. 0x00)
[   1.0000040] ld0 at virtio1: features: 0x10000a54<INDIRECT_DESC,CONFIG_WCE,FLUSH,BLK_SIZE,GEOMETRY,SEG_MAX>
[   1.0000040] virtio1: config interrupting at msix1 vec 0
[   1.0000040] virtio1: queues interrupting at msix1 vec 1
[   1.0000040] ld0: 10240 KB, 20 cyl, 16 head, 63 sec, 512 bytes/sect x 20480 sectors
[   1.0000040] isa0 at mainbus0
[   1.0000040] com0 at isa0 port 0x3f8-0x3ff irq 4: ns16550a, 16-byte FIFO
[   1.0000040] com0: console
[   1.0000040] WARNING: system needs entropy for security; see entropy(7)
[   1.0000040] swwdog0: software watchdog initialized
[   1.0000040] boot device: ld0
[   1.0000040] root on ld0a dumps on ld0b
[   1.0000040] root file system type: ext2fs
[   1.0000040] kern.module.path=/stand/i386/10.0/modules
[   1.0000040] clock: unknown CMOS layout
# 

Sky is the limit.

Thanks @ConnorNelson for the inspiration.