unifios-utilities/nspawn-container/examples/multicast-relay
Pedro Pombeiro 695f3d22f9
Fix location of ResolvConf option (#573)
`ResolvConf` belongs in `Exec` section, otherwise an error results. See https://www.freedesktop.org/software/systemd/man/systemd.nspawn.html#ResolvConf=
2023-11-23 07:45:45 -08:00
..
configure-container.sh Adds example for multicast-relay (#545) 2023-05-29 01:20:02 -07:00
README.md Fix location of ResolvConf option (#573) 2023-11-23 07:45:45 -08:00

Create the filesystem overlay

If you're going to create several nspawn containers, you can save some disk space by using overlayfs to use a common base. Follow the instructions in the unifi-utilities documentation for UnifiOS 3.0+ containers. I called my container debian-base.

Next, we need an upperdir where the file changes are saved and a workdir where temporary file changes are saved. I'm going to create a container for multicast-relay, replacing the podman container that I used prior to 3.x. An important note is that upperdir and workdir must not be on the overlayfs that UnifiOS uses. I opted to store this data on the hard drive that I use for video storage at /volume1.

So, we have the following directories, which you need to create:

  • /var/lib/machines/multicast-relay: This will be the root directory of our new container.
  • /volume1/machines/multicast-relay/upper: This stores the differences from the base container.
  • /volume1/machines/multicast-relay/work: This is a temporary directory for changes before they're saved to upper. This could possibly be on a tmpfs mount, but I didn't want to mess with available memory.
  • /data/custom/machines/debian-base: This is the base container directory created by following the README linked above.

Do it:

mkdir -p /var/lib/machines/multicast-relay /volume1/machines/multicast-relay/{upper,work}

Now add the matching entry to your fstab. I'm not 100% sure how permanent this is, but I'll find out when I either reboot or do a firmware upgrade.

Append this to /etc/fstab

overlay /var/lib/machines/multicast-relay overlay noauto,x-systemd.automount,lowerdir=/data/custom/machines/debian-base,upperdir=/volume1/machines/multicast-relay/upper,workdir=/volume1/machines/multicast-relay/work 0 0

If everything is good, you can mount /var/lib/machines/multicast-relay. If there's any error from that, you have some homework to do. This should automount on reboot, but I haven't tested by rebooting my UDM Pro yet. We'll see 🤞.

Configure the container

With your overlay in place, you can start the container and install your stuff.

systemd-nspawn -M multicast-relay -D /var/lib/machines/multicast-relay

You should now be at a root shell inside the container. I configured this all manually, but you can use the script I created during my trial and error to save yourself some time. Minimal Debian doesn't have curl or wget, so you can install one of those and download the script, or copy-paste into vi or something. This is left as an exercise to the reader.

To escape this container, you'll have to press the cheat code given at the start of your session. (HINT: Press Ctrl + ] 3 times.)

NOTE: I didn't set the root password, which you will see in many tutorials. It isn't needed. The host can bypass any login prompt using machinectl shell <container>. You might want to set a root password and/or other user if you are using the container as a lightweight VM.

Run the container

If this is your first systemd-nspawn service, you'll need to create the config directory.

mkdir -p /etc/systemd/nspawn

Now create the container launch configuration in the file indicated. multicast-relay requires the ability to open raw sockets, so we grant that capability and strip the rest. Be sure you specify the interfaces you wish to use in the Environment= line. Optionally, you can specify additional multicast-relay options in OPTS

# /etc/systemd/nspawn/multicast-relay.nspawn
[Exec]
Boot=on
Capability=CAP_NET_RAW
ResolvConf=off
Environment=INTERFACES="br0 br50"
Environment=OPTS=

[Network]
Private=off
VirtualEthernet=off

Once that file is in place, you're ready to enable the container on boot and run it.

machinectl enable multicast-relay
machinectl start multicast-relay

Troubleshooting

You can view the stdout of the container in the host journal.

journalctl -xe

Output from multicast-relay itself won't be found here though. You should be able to view a containers journal from the host, but I got an error when I tried suggesting the Debian container has a newer journal format than the UnifiOS host.

No matter, you can just enter the container and get a root shell (no login required).

machinectl shell multicast-relay

Now, we're setting the interface and options via environment variables set on the host. If you want to double check that's working correctly, check the environment of systemd from within the container.

cat /proc/1/environ | tr '\0' '\n'

output:

PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
container=systemd-nspawn
HOME=/root
USER=root
LOGNAME=root
container_uuid=c05b41ce-0995-412d-bd2d-338759b24e54
NOTIFY_SOCKET=/run/host/notify
container_host_version_id=11
container_host_id=debian
INTERFACES=br0 br50

You could use the same command to view the environment of our service. In this case, we can use the PID of dash, the shell script interpreter from start.sh.

root@DreamMachinePro:~# cat /proc/$(pidof dash)/environ | tr '\0' '\n'
LANG=C.UTF-8
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
INVOCATION_ID=d1cfaf43a00b4e79bcddca6a1595837c
JOURNAL_STREAM=8:51317778
SYSTEMD_EXEC_PID=47
INTERFACES=br0 br50