Installation and configuration documentation of my Arch Linux setup in GitHub Pages.
This page describes the setup and use of systemd-nspawn containers.
Please also see the info concerning this topic for Arch Linux.
Please install package arch-install-scripts
.
To create a container named ‘container’, do the following as root:
export CONTAINER=container
export FOLDER=/var/lib/machines/$CONTAINER
mkdir -p $FOLDER
pacstrap -icMGd $FOLDER systemd
tee -a /etc/systemd/nspawn/$CONTAINER.nspawn <<EOF
[Network]
Port=<host port>:<container port>
EOF
tee -a /etc/systemd/nspawn/$CONTAINER.nspawn <<EOF
[Files]
Bind=<folder on host>:/mnt
EOF
e.g. for making available /dev/ttyUSB0
in the container:
tee -a /etc/systemd/nspawn/$CONTAINER.nspawn <<EOF
[Files]
Bind=/dev/ttyUSB0
EOF
First check the device’s attributes with file
:
file /dev/ttyUSB0
# /dev/ttyUSB0: character special (188/0)
Then determine the alias of its primary device number (in this case 188
) from /proc/devices
:
cat /proc/devices | grep 188
# 188 ttyUSB
tee /etc/systemd/system/systemd-nspawn@$CONTAINER.service.d/override.conf <<EOF
[Service]
DeviceAllow=char-ttyUSB rwm
EOF
machinectl start $CONTAINER
or
systemctl start systemd-nspawn@$CONTAINER
or
systemd-nspawn -bnD $FOLDER
machinectl shell $CONTAINER
systemctl enable machines.target # Only the first time
systemctl enable systemd-nspawn@$CONTAINER
From within the container:
systemctl enable --now systemd-networkd
From host system:
ln -s /usr/lib/systemd/system/systemd-networkd.service\
$FOLDER/etc/systemd/system/multi-user.target.wants/systemd-networkd.service
From within the container:
systemctl enable --now systemd-resolved
ln -sf /run/systemd/resolve/stub-resolv.conf /etc/resolv.conf
From host system:
ln -s /usr/lib/systemd/system/systemd-resolved.service\
$FOLDER/etc/systemd/system/multi-user.target.wants/systemd-resolved.service
ln -sf /run/systemd/resolve/stub-resolv.conf $FOLDER/etc/resolv.conf
Since kernel 4.14, systemd-nspawn containers will be unprivileged by default (PrivateUsers=pick
) which means that those may not have the right permissions to fulfill the functions for which they’re created. In addition, the owner of all files/directories within the root folder of the container (in /var/lib/machines/
) is recursively shifted to the automatically created unprivileged user namespace.
To create a privileged container, add PrivateUsers=false
to the [Exec]
section of the respective .nspawn
file like:
[Exec]
PrivateUsers=false
To revert a shift to the automatically created unprivileged user namespace back to the user namespace of the host (starting at 0
for root):
.nspawn
doesn’t contain PrivateUsers=false
execute the following:
systemd-nspawn --quiet --boot --link-journal=try-guest --network-veth -U --settings=override --private-users=0 --private-users-chown --machine=$CONTAINER
To make the container privileged again, enable the PrivateUsers=false
again in the .nspawn
file and start the container.
A container’s packages can be updated by calling the following from the host:
pacman -Syur /var/lib/machines/$CONTAINER
Running the command above will sometimes fail with the following in which case you’ll need to update the keyring locally:
==> ERROR: DDB867B92AA789C165EEFA799B729B06A680C281 could not be locally signed.
A container’s keyring can be updated by:
sudo machinectl shell $CONTAINER /usr/bin/pacman-key --populate archlinux