systemd-nspawn: my thoughts and its uses
Note: if you came here to get some quick references check the TL;DR section.
Quoting from the man page, systemd-nspawn
is “in many ways similar to
chroot(1), but more powerful since it fully virtualizes the file system hierarchy, as well as the process tree, the various IPC subsystems and the host
and domain name… It may be invoked on any directory tree containing an operating system tree”.
Bottom line and as the ArchWiki says: “is like the chroot command, but it
is a chroot on steroids”. Not only that but based on the description from the manual page (extract above) systemd-nspawn
can definitely be used as an
alternative to well-known operating system-level-virtualization… such as Docker.
But why have another solution for os-level-virtualization (containers) if we already have LXC,
Docker, chroot and
others? A follow up question to that could be: Why should I use
systemd-nspawn
if I can easily use Docker
? Without going into the war that is among the community regarding systemd, it’s a fact that a lot of distros out there adopted it you like or not! If that is the case for
the distro you’re using, then there is a high chance systemd-nspawn
is already present in your machine. This means you have a way to virtualize another GNU/Linux
environment with just a couple of commands. You can spin up a container within seconds with tools already at your hands; without installing more packages!
If you’re anything like me this is great news, specially since I’m constantly trying new softwares/application, playing around with AUR and also trying to
port packages to BlackArch. Now I can use systemd-nspawn
to spin up a vanilla Arch Linux environment and do
my tests without messing with my host installation, leaving it as clean as possible. And of course everything that you can do with Docker you can probably do with
systemd-nspawn
too.
Network
By default the guest, i.e., container, running on systemd-nspawn
will share the network with the host. This is not the default behavior with Docker, so could
cause some confusion. But you can tweak the configuration in order to create private network or a bridged one. I highly recommend checking the
man page for systemd-nspawn
since it covers all configurations,
features and more.
But going back to the point that the guest shares the network with the host, this make testing applications way easier and out-of-the-box. For instance, I didn’t
know what to expect from Jekyll so I ran an vanilla Arch installation as guest using systemd-nspawn
, installed all the necessary packages (ruby), gems and did
all the development using the container. In fact, I’m right now writing this blog post inside the container using systemd-nspawn
. The good thing is that my base
installation is untouched and since the guest shares the network I test the blog by accessing the localhost:4000 on my browser. :)
This behavior can also make it a bit easier, or just out-of-the-box, to sandbox applications. You can spin up a small Linux base installation, install your browser and use it from within the container. Of course you’ll need to configure X properly and for that just visit: ArchWiki - Systemd-nspawn: Using X and follow the instructions.
My thoughts
systemd-nspawn
can be a great alternative for os-level-virtualization and it’s probably already installed in your distro. Having the network shared with the host
by default create the easiest scenarios for testing and sandboxing applications.
However, it always comes down to your use case. You should use solutions that address your problems in an effective matter. For me, systemd-nspawn
won my space
for containers since it is easy to use and already in my system (base installation).
TL;DR: Arch Linux using systemd-nspawn
Running an Arch Linux on systemd-nspawn, considering you are on an Arch host:
# Install arch scripts to get pacstrap
sudo pacman -S arch-install-scripts --needed
# Create a folder to hold the environment files (system tree):
mkdir arch-container
# Use pacstrap to create the base directory tree for Arch, we don't need the kernel
pacstrap -i -c arch-container base base-devel --ignore linux
# Spin up the container
sudo systemd-nspawn -b -D arch-container
-b
/ --boot
: automatically search for an init program and invoke it as PID 1, instead of a shell or a user supplied program.
-D
/ --directory=
: directory to use as file system root for the container.
You’ll be able to login as root
without any password. After that you can tweak the environment as you see fit, the same way if it was a regular installation.
For full reference check: https://wiki.archlinux.org/index.php/Systemd-nspawn#Create_and_boot_a_minimal_Arch_Linux_distribution_in_a_container