Docker Netzwerk

Gerade zum Entwickeln will man oft einen Container an ein internes Netz binden, ohne das Default Interface docker0 anfassen zu müssen. Am besten baut man sich dazu ein dedziertes Bridge Interface auf, an das sich dann via docker-compose einzelne Container andocken können.

Systemd

Im Zusammenhang mit Systemd haben Bridge Interfaces gewisse Eigenheiten, die man aber auch wieder mit Systemd umgehen kann. Zunächst werden unter /etc/systemd/network/ die folgenden Dateien angelegt:

60-br0.netdev

[NetDev]
Name=br0
Kind=bridge

60-br0.network

[Match]
Name=br0

[Network]
ConfigureWithoutCarrier=true
Address=192.168.48.1/24

60-dummy0.netdev

[NetDev]
Name=dummy0
Kind=dummy

60-dummy0.network

[Match]
Name=dummy0

[Network]
Bridge=br0

Das Dummy Interface sorgt dafür, dass das br0 Interface nicht im Status NO-CARRRIER verbleibt. Mit systemctl daemon-reload && systemctl enable --now systemd-networkd wird das Bridge Interface aktiviert.

iptables

Docker stellt für eigene Netzwerkregeln den Chain DOCKER-USER zur Verfügung. Normalerweise ist ein Traffic zwischen den Containern nur innerhalb von Links möglich. Für br0 wird dazu eine Ausnahme erstellt. Die folgende Regel darf nur für die Entwicklung verwendet werden. So etwas mit Internetzugang zu bauen ist gefährlich und sollte daher keinesfalls gemacht werden.

*nat
:PREROUTING ACCEPT [0:0]
:INPUT ACCEPT [0:0]
:OUTPUT ACCEPT [0:0]
:POSTROUTING ACCEPT [0:0]

-A POSTROUTING -o wlp4s0 -j MASQUERADE

COMMIT

*filter
:INPUT ACCEPT [0:0]
:FORWARD ACCEPT [0:0]
:OUTPUT ACCEPT [0:0]
:DOCKER-USER - [0:0]

-A INPUT -m state --state RELATED,ESTABLISHED -j ACCEPT
-A INPUT -p icmp -j ACCEPT
-A INPUT -i lo -j ACCEPT
-A INPUT -i br1 -j ACCEPT
-A INPUT -j REJECT --reject-with icmp-host-prohibited

-A FORWARD -m state --state RELATED,ESTABLISHED -j ACCEPT
-A FORWARD -s 192.168.48.0/24 -j ACCEPT
-A FORWARD -j REJECT --reject-with icmp-host-prohibited

-A DOCKER-USER -i br1 -s 192.168.48.0/24 -j ACCEPT
-A DOCKER-USER -o br1 -d 192.168.48.0/24 -j ACCEPT

COMMIT

Mit diesem Ruleset dürfen die Container nach außen kommunizieren und untereinander, sofern eine Bindung an br0 besteht.

Docker

Damit Docker br1 nutzen kann, wird es mit

docker network create --driver=bridge --subnet=192.168.48.0/24 -o "com.docker.network.bridge.name=br0" br0

bekannt gemacht. Jetzt kann in den docker-compose .yaml Files das Interface br0 genutzt werden.

Docker