Using systemd-networkd inside a podman container

179 Views Asked by At

The end goal is to have a macvlan interface set up within a Podman container. I have the following Dockerfile

FROM docker.io/library/debian:bookworm-slim
RUN apt-get --yes install systemd
RUN systemctl set-default multi-user.target
CMD ["/lib/systemd/systemd"]

If I then run this in privileged mode (detached) and attach a shell to the running container (as root), I can set up a macvlan interface called macvlan1 on the default tap interface using iproute2:

# apt install iproute2
# ip link add macvlan1 link tap0 type macvlan mode bridge

However, I want to avoid this, and I think it should be possible using systemd-networkd, but I'm not having much luck. I've tried the following .network and .netdev files (which I have tested to work on my host machine):

### 99-test.network
[Match]
Name=tap0

[Network]
MACVLAN=macvlan1
### 99-test.netdev
[Match]
# Empty

[NetDev]
Name=macvlan1
Kind=macvlan

[MACVLAN]
Mode=bridge

I update my Dockerfile like so:

FROM docker.io/library/debian:bookworm-slim
COPY 99-test.network /lib/systemd/network
COPY 99-test.netdev /lib/systemd/network
RUN apt-get --yes install systemd
RUN systemctl set-default multi-user.target
RUN systemctl enable systemd-networkd
CMD ["/lib/systemd/systemd"]

But when I start up the container, I see no macvlan interface created. If I look at the output of systemctl status systemd-networkd there are no logs or error messages suggesting that it's attempted to read the .network and .netdev files. The only clue I have is that when I run networkctl on my host machine, it shows the physical interfaces as unmanaged in the SETUP column whereas in the container, it shows all interfaces as pending (including for a manually-created macvlan interface).

Is what I'm trying to do possible with systemd in Podman? If not, why not?

2

There are 2 best solutions below

0
On

You can set up a --driver macvlan network (configurable with --options) outside the container as a podman network. Then "plug it in" to the podman container with --network <name>.

To avoid manual setup steps, see also Podman Quadlet usage with [Container] Network=<name>.network and [Network] Driver=macvlan for augmented systemd unit files. (Note that Quadlet *.network units are completely separate from systemd-networkd *.network files.)

This way Podman resources and unit files are set up on the host, keeping the container light-weight. There is no need to install systemd in the container, which would then become "too heavy".

Also consider running the container and macvlan network in rootless mode, either as yourself or as systemd services from a separate unprivileged loginctl enable-linger user.

0
On

If you want something medium-weight, between virtual machine and container, consider systemd-nspawn. Can be used to spawn "machines" from full distribution images, or minimal directories. With the machine in place, you can run individual commands, shells, or perform a full --boot.

This solution sets up and manages network interfaces from the host. You can spawn a new machine with --network-macvlan=<device> to create a separate network.

Control the machine with machinectl. You can machinectl enable to autostart [email protected], which implies --boot.

Spawning a machine which uses systemd as PID 1 allows certain synergies. You can then use other systemd tools with --machine directly from the host machine. One example is systemctl --machine: sudo systemctl --machine my-user@my-machine status.