Networking with systemd-nspawn containers

Submitted by olaf on 2016-06-25

These days, I discovered systemd-nspawn as a chroot-like version of starting a container.

Even though not everything works as I expect, it looks simple enough to be useful to me. After playing around a bit, I want to network connect several containers. In the default configuration (at least on Ubuntu), nspawn creates two veth interfaces per container, one on the host side and one inside the container.

Containers

After setting up the test containers below /var/lib/machines, let’s start the containers first

systemctl start systemd-nspawn@host1
systemctl start systemd-nspawn@host2
systemctl start systemd-nspawn@host3

machinectl shows the running containers

machinectl list

MACHINE CLASS SERVICE
host1 container systemd-nspawn
host2 container systemd-nspawn
host3 container systemd-nspawn

3 machines listed.

To enter a container, we can use either machinectl login host1 or machinectl shell host1. If this doesn’t work for some reason, we can also use plain nsenter from util-linux

nsenter --target 2566 --mount --uts --ipc --net --pid

The target pid can be taken from the Leader property

machinectl -p Leader show host1

Inside the container we setup the network by assigning an IP address and bringing up the interface

ip addr add 10.0.0.1/24 dev host0
ip link set dev host0 up

This also installs the necessary routing table entry. This is repeated on every container we want to connect.

Host

To connect these containers on the host side, we need a network bridge, which works roughly like a physical hub or switch, and connect the host side interfaces to this bridge.

Create the bridge

ip link add name br0 type bridge

assign an IP address and bring up the bridge

ip addr add 10.0.0.10/24 dev br0
ip link set dev br0 up

As in the containers, this creates the routing entry for the 10.0.0.0/24 network.

The last step consists of linking the host side interfaces to the bridge.

ip link set dev ve-host1 master br0
ip link set dev ve-host1 up

This last step can be automated by creating a file /etc/systemd/nspawn/host1.nspawn for each container

[Network]
Bridge=br0

But then the bridge must exist before starting any container.

Test

Now go inside host1 and check connectivity by pinging itself, the host, or another container

ping -c 1 10.0.0.1
ping -c 1 10.0.0.10
ping -c 1 10.0.0.2

Post a comment

All comments are held for moderation; Markdown and basic HTML formatting accepted. If you want to stay anonymous, leave name, e-mail and website empty.