A Use Case for Systemd Nspawn (Part 1)
Docker is all the rage in the world of containerization, but there is another container technology that may prove to be invaluable for certain use cases… Enter systemd-nspawn.
In this article I will outline a use case for systemd-nspawn. All examples below use the RedHat variant (centos).
Nspawn container as an RPM build host
Part of my daily routine at work is to manage specific RPM packages for inclusion in internal repositories. An interesting use of nspawn is as a build/test host. Setting up nspawn on a RHEL7 (Oracle, Centos, Scientific, etc.) is pretty trivial:
RHEL7 Style Setup
yum -y --release=7 --installroot=/srv/ns-host install systemd passwd yum rpmdevtools yum-utils
cp /etc/os-release /srv/ns-host/etc/os-release
systemd-nspawn -D /srv/ns-host
passwd root
useradd rpm999
passwd rpm999
exit
What did we do?
We installed a release 7 filesystem into the directory /srv/ns-host with some required packages.
The second step copies over the os-release file to the container (this is required as of systemd-219).
Next we temporarily start the container by passing the -D flag and filesystem location. Finally we
add the root password and create a user for our RPM builds. It is best practice to run your rpmbuilds
as a non-root user, even in a container.
Boot your new container
systemd-nspawn -bD /srv/ns-host
login as rpm999
rpmdev-setuptree && mkdir incoming
Copy your source data to the rpmbuild directory. You may utilize external tools (ie - tools outside of the container - git/vim) for editing text or revision control.
Systemd’s machinectl interface
The machinectl interface gathers data published by the kernel and can be used to start/stop containers (and vms).
Setup:
ln -s /srv/ns-test /var/lib/machines/.
machinectl start ns-test
machinectl (Shows running vms/containers)
machinectl enable ns-test (Enable container start at boot time)
In order to ensure that your builds are isolated from the network it is important to disable network
sharing to the container by changing the --network flag to --private-network. The config is located
at /etc/systemd/system/machine.target.wants.
# /etc/systemd/system/machine.target.wants
# This file is part of systemd.
#
# systemd is free software; you can redistribute it and/or modify it
# under the terms of the GNU Lesser General Public License as published by
# the Free Software Foundation; either version 2.1 of the License, or
# (at your option) any later version.
[Unit]
Description=Container %I
Documentation=man:systemd-nspawn(1)
PartOf=machines.target
Before=machines.target
[Service]
ExecStart=/usr/bin/systemd-nspawn --quiet --keep-unit --boot --link-journal=try-guest --private-network --machine=%I
KillMode=mixed
Type=notify
RestartForceExitStatus=133
SuccessExitStatus=133
Slice=machine.slice
Delegate=yes
[Install]
WantedBy=machines.target
In the next post I will show you how you can make an ephemeral container instance using btrfs and nspawn.