Home Systemd Namespace Containers
Post
Cancel

Systemd Namespace Containers

In my journey to demystify containers and get away from a product and run containers with nothing but my Linux laptop i decided that Containers From Scratch were great, but what if it was easier to manage your container once its created? It is! And you can do it all with nothing but systemd!

Prerequisites

Have machinectl installed. This package provides systemd tools for nspawn and container/VM management: * systemd-nspawn * systemd-machined and machinectl * systemd-importd

If its not installed install it the following ways:

Ubuntu/Debian/Kali/Raspbian

1
apt install systemd-container

RHEL/CentOS

1
yum install systemd

Fedora

1
dnf install systemd-container

Arch

1
pacman -S systemd

Container Images

There are multiple ways to create/get a container image.

  • From scratch ie bootstrap
  • From a already made tar or img file such as a Ubuntu’s cloudimage or from snpawn.org
  • From a docker image/container

From scratch

See my blog “Bootstrapping Debian As a Container Image”.

From a ready to go image

There are several cloud images out there here are the ones for ubuntu:

  • https://cloud-images.ubuntu.com/kinetic/current/kinetic-server-cloudimg-arm64.tar.gz Theres also this great nspawn image hub (similar to docker hub) for namespace container images!
  • https://hub.nspawn.org/images/

This is what we will use, since its the fastest and simplest method

From a Docker container/image

This not work in most cases since you will need to create an init script on the container to start your services. But it is a container it just wont run anything automatically until you login to the container and run it manually.

First find the docker image you want from docker hub - in my example i have chosen dokuwiki. Second pull the image down.

1
docker pull dokuwiki

Third run the container how you would like it to run.

1
2
3
4
5
6
7
8
docker run -d \
  --name=dokuwiki \
  -e PUID=1000 \
  -e PGID=1000 \
  -e TZ=America/Chicago \
  -p 80:80 \
  --restart unless-stopped \
  lscr.io/linuxserver/dokuwiki:latest

Finally export the image to a tar file that can be used with systemd-namespace containers.

1
docker export --output=dokuwiki.tar dokuwiki

exporting a docker image

Downloading or Oulling the Image

wget/curl

If you got your image hosted somewhere on the internet just use wget or curl to download it.

Pulling an “image” using machinectl

tarball image

The below example uses the “ready to go image” example

1
machinectl pull-tar https://hub.nspawn.org/storage/centos/8/tar/image.tar.xz

img/raw image

The below example uses the “ready to go image” example

1
machinectl pull-raw https://hub.nspawn.org/storage/centos/8/raw/image.raw.xz

Example:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
tamalerhino@localhost:~$ sudo machinectl pull-raw https://hub.nspawn.org/storage/centos/8/raw/image.raw.xz --verify=no
Enqueued transfer job 1. Press C-c to continue download in background.
Pulling 'https://hub.nspawn.org/storage/centos/8/raw/image.raw.xz', saving as 'image'.
HTTP request to https://hub.nspawn.org/storage/centos/8/raw/image.roothash failed with code 404.
Root hash file could not be retrieved, proceeding without.
HTTP request to https://hub.nspawn.org/storage/centos/8/raw/image.roothash.p7s failed with code 404.
Root hash signature file could not be retrieved, proceeding without.
Downloading 381.8M for https://hub.nspawn.org/storage/centos/8/raw/image.raw.xz.
HTTP request to https://hub.nspawn.org/storage/centos/8/raw/image.verity failed with code 404.
Verity integrity file could not be retrieved, proceeding without. https://hub.nspawn.org/storage/centos/8/raw/image.verity
Downloading 32B for https://hub.nspawn.org/storage/centos/8/raw/image.nspawn.
Download of https://hub.nspawn.org/storage/centos/8/raw/image.nspawn complete.
Got 1% of https://hub.nspawn.org/storage/centos/8/raw/image.raw.xz. 1min 49s left at 3.4M/s.
........
Got 99% of https://hub.nspawn.org/storage/centos/8/raw/image.raw.xz. 284ms left at 13.1M/s.
Download of https://hub.nspawn.org/storage/centos/8/raw/image.raw.xz complete.
Created new local image 'image'.
Created new file /var/lib/machines/image.nspawn.
Operation completed successfully.
Exiting.
tamalerhino@localhost:~$

Troubleshooting

You might run into an issue where it wants to be verified, in that case run:

1
--verify=no

Importing a local image

tarball image

1
machinectl import-tar dokuwiki.tar

img/raw image

1
machinectl import-raw dokuwiki.img

View the installed images.

1
2
machinectl list-images --all
machinectl show-image <imagename>

When i downloaded my centos image it named it image for some reason, so just replace that with whatever it named yours.

Example:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
tamalerhino@localhost:~$ sudo machinectl list-images
NAME  TYPE RO USAGE CREATED                     MODIFIED
image raw  no  3.2G Sun 2022-08-14 02:41:35 UTC Sun 2022-08-14 02:41:35 UTC

1 images listed.
tamalerhino@localhost:~$ sudo machinectl show-images image
Unknown command verb show-images.
tamalerhino@localhost:~$ sudo machinectl show-image image
Name=image
Path=/var/lib/machines/image.raw
Type=raw
ReadOnly=no
CreationTimestamp=Sun 2022-08-14 02:41:35 UTC
ModificationTimestamp=Sun 2022-08-14 02:41:35 UTC
Usage=3489710080
Limit=3489701888
UsageExclusive=3489710080
LimitExclusive=3489701888
tamalerhino@localhost:~$

Starting The Container

There are two main ways to start the container, using machinectl or nspawn,which is like chroot but on steroids, sometimes machinectl wont start it so use nspawn.

machinectl

1
tamalerhino@localhost:~$ sudo nspawn -i centos/8/raw

When i downloaded my centos image it named it image for some reason, so just replace that with whatever it named yours.

Example:

1
2
3
4
5
6
7
8
9
10
11
12
tamalerhino@localhost:~$ machinectl start image
tamalerhino@localhost:~$ sudo machinectl login image
Connected to machine image. Press ^] three times within 1s to exit session.

CentOS Linux 8
Kernel 5.15.0-46-generic on an x86_64

centos8 login: root
Password:
[root@centos8 ~]# cat /etc/redhat-release
CentOS Linux release 8.5.2111
[root@centos8 ~]#

nspawn

1
sudo systemd-nspawn -M <image>

Example:

1
2
3
4
5
6
7
tamalerhino@localhost:~$ sudo systemd-nspawn -M image
Ignoring Capability= setting, file /var/lib/machines/image.nspawn is not trusted.
Spawning container image on /var/lib/machines/image.raw.
Press ^] three times within 1s to kill container.
[root@image ~]# cat /etc/redhat-release
CentOS Linux release 8.5.2111
[root@image ~]#

Using a directory

Depending if you want a shell or not it might be best to untar it and run it with the --boot -b flag to let systemd run systemd inside of the container.

This is assuming you used the docker tar image or some image that is using a directory

1
systemd-nspawn -bD dokuwiki/

Clean Up

Stopping an image

1
machinectl stop image

Deleting the images

Just as an FYI the default directory where all of this gets downloaded to is /var/lib/machines To clean most of this up you can run machinectl clean --all

References

  • https://en.wikipedia.org/wiki/POSIX
  • https://www.freedesktop.org/software/systemd/man/machinectl.html
  • https://wiki.archlinux.org/title/Systemd-nspawn
  • https://docs.docker.com/engine/reference/commandline/export/
  • https://cloud-images.ubuntu.com/
  • https://www.nomadproject.io/plugins/drivers/community/nspawn
  • https://wiki.debian.org/Debootstrap
  • https://wiki.polaire.nl/doku.php?id=airspy_in_nspawn_chroot
  • https://medium.com/@huljar/setting-up-containers-with-systemd-nspawn-b719cff0fb8d
This post is licensed under CC BY 4.0 by the author.