Einleitung
Docker stellt Netzwerkfunktionen bereit, über die Container miteinander, mit dem Docker-Host und mit externen Systemen kommunizieren können. Dabei verwendet Docker die Netzwerkmechanismen des Hostbetriebssystems und richtet die erforderlichen virtuellen Schnittstellen, IP-Adressen und Netzwerkregeln weitgehend automatisch ein.
Unter Linux bilden sogenannte Network Namespaces die Grundlage der Netzwerkisolation. Sie ermöglichen es, jedem Container eine eigene Netzwerkumgebung mit eigenen Schnittstellen, IP-Adressen und Routingtabellen bereitzustellen. Je nach gewähltem Netzwerkmodus können Container voneinander getrennt, miteinander verbunden oder unmittelbar in den Netzwerkstack des Hosts integriert werden.
Docker unterstützt hierfür unterschiedliche Netzwerktreiber und Betriebsarten. Der standardmäßig verwendete Bridge-Modus verbindet Container über eine virtuelle Linux-Bridge. Daneben stehen unter anderem der Host-Modus ohne eigenen Netzwerk-Namespace und der Netzwerkmodus none ohne externe Netzwerkanbindung zur Verfügung.
Dieser Artikel erläutert die grundlegende Netzwerkarchitektur von Docker unter Linux und zeigt anhand praktischer Beispiele, wie Container in Netzwerke eingebunden werden und wie die Kommunikation zwischen Containern und dem Docker-Host funktioniert. Benutzerdefinierte Netzwerke, die integrierte DNS-Namensauflösung sowie die weiterführende Konfiguration von Netzwerkzugriffen werden in separaten Artikeln behandelt.
Die Netzwerkarchitektur unter Linux
Docker verwendet für die Netzwerkkommunikation von Containern die Netzwerkfunktionen des Linux-Kernels. Dabei übernimmt Docker die Einrichtung und Verwaltung der benötigten virtuellen Netzwerke, Schnittstellen und Netzwerkregeln. Die eigentliche Verarbeitung der Netzwerkpakete erfolgt durch den Netzwerkstack des Hostbetriebssystems.
Eine zentrale Rolle spielen dabei die sogenannten Network Namespaces. Sie ermöglichen es, einem Container eine eigene Netzwerkumgebung bereitzustellen. Innerhalb dieser Umgebung besitzt der Container eigene Netzwerkschnittstellen, IP-Adressen, Routingtabellen und einen eigenen TCP-/UDP-Port-Namensraum. Dadurch können beispielsweise mehrere Container gleichzeitig einen Webserver auf Port 80 betreiben, ohne miteinander in Konflikt zu geraten.
Im standardmäßig verwendeten Bridge-Modus verbindet Docker die Netzwerkschnittstelle eines Containers über ein virtuelles Ethernet-Paar (veth-Pair) mit einer Linux-Bridge auf dem Host. Ein Ende dieser Verbindung befindet sich im Network Namespace des Containers, das andere im Netzwerk-Namespace des Hosts.
Die Linux-Bridge übernimmt dabei die Funktion eines virtuellen Ethernet-Switches. Container im selben Bridge-Netzwerk können auf diesem Weg direkt miteinander kommunizieren.

Die Linux-Bridge selbst ist kein Router. Sie arbeitet auf der Sicherungsschicht (Layer 2) und vermittelt Ethernet-Frames zwischen den angeschlossenen virtuellen Schnittstellen. Für die Kommunikation mit anderen IP-Netzen stellt dagegen der Linux-Host die Routingfunktionen bereit.
Dazu erhält die Bridge eine IP-Adresse im Docker-Netzwerk, die den Containern gewöhnlich als Standardgateway dient. Der Linux-Kernel übernimmt die Weiterleitung in andere Netzwerke. Docker konfiguriert hierfür bei Bedarf zusätzlich Network Address Translation (NAT), sodass Container beispielsweise über die Netzwerkschnittstelle des Hosts auf das Internet zugreifen können.
Damit entsteht eine virtuelle Netzwerkumgebung, deren Aufbau Docker automatisiert, während die zugrunde liegenden Netzwerkfunktionen weiterhin vom Linux-Kernel bereitgestellt werden.
Netzwerkverbindungen der Container untersuchen
Container im selben Bridge-Netzwerk erhalten eigene IP-Adressen und können grundsätzlich direkt miteinander kommunizieren. Dafür sind keine veröffentlichten Host-Ports erforderlich. Die Netzwerkverbindung wird über virtuelle Ethernet-Schnittstellen und die Linux-Bridge hergestellt.
Die Netzwerkschnittstelle eines Containers
Mit docker exec lässt sich die Netzwerkkonfiguration eines laufenden Containers untersuchen:
$ sudo docker exec academy-volume-nginx-01 ip addr
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN qlen 1000
---snip---
inet 127.0.0.1/8 scope host lo
---snap---
2: eth0@if19: <BROADCAST,MULTICAST,UP,LOWER_UP,M-DOWN> mtu 1500 qdisc noqueue state UP
link/ether 3a:6d:f0:5c:95:70 brd ff:ff:ff:ff:ff:ff
inet 172.17.0.4/16 brd 172.17.255.255 scope global eth0
---snip---
Docker-Netzwerke anzeigen und untersuchen
Docker verwaltet seine Netzwerke als eigenständige Objekte. Über die Docker-Kommandozeile lassen sich vorhandene Netzwerke anzeigen und ihre Konfiguration untersuchen.
Einen Überblick über die verfügbaren Netzwerke liefert:
$ sudo docker network ls
NETWORK ID NAME DRIVER SCOPE
dd70b5cc9abc bridge bridge local
3107afeded6f host host local
08db602fa7d1 none null local
Docker stellt hier drei Netzwerkmodi bereit: bridge, host und none. Sie unterscheiden sich darin, wie Container an den Netzwerkstack des Hosts angebunden werden. Die Spalte DRIVER bezeichnet den verwendeten Netzwerktreiber, während SCOPE den Geltungsbereich des Netzwerks angibt. local bedeutet, dass das jeweilige Netzwerk auf diesen Docker-Host beschränkt ist.
Das Standard-Bridge-Netzwerk untersuchen
Ohne ausdrückliche Angabe eines Netzwerks verbindet Docker neu erstellte Container standardmäßig mit dem Netzwerk bridge.
Dessen Konfiguration lässt sich mit folgendem Befehl anzeigen:
$ sudo docker network inspect bridge
Die Ausgabe erfolgt im JSON-Format und enthält unter anderem die Netzwerkkonfiguration, den verwendeten Treiber und die angeschlossenen Container.
Besonders relevant sind folgende Ausgaben:
---snip---
"Driver": "bridge",
"EnableIPv4": true,
"EnableIPv6": false,
"IPAM": {
"Driver": "default",
"Options": null,
"Config": [
{
"Subnet": "172.17.0.0/16",
"Gateway": "172.17.0.1"
}
]
},
---snip---
"Containers": {
"1b0aca617b703f8f95d41beec25163737815a50e6741af8814e1d6dbb3e26367": {
"Name": "academy-volume-nginx-02",
"EndpointID": "9496ff03deb3dcc6f398eb7a7721fb221e90564b745456515bfd0aa2023030e3",
"MacAddress": "6a:1d:eb:30:57:da",
"IPv4Address": "172.17.0.5/16",
"IPv6Address": ""
},
"5e59e2378eb2868a81958ac20f3f935aebf90b4663e3a83567bf397cba7c25a7": {
"Name": "academy-volume-nginx-01",
"EndpointID": "3ec7bfba82e7dda7029e2a49145ac60dfadd9c0371666e3bb3541a13f05eb609",
"MacAddress": "3a:6d:f0:5c:95:70",
"IPv4Address": "172.17.0.4/16",
"IPv6Address": ""
},
"ba04c9638cd3ec3bc3aac04228ceac3a32a4c1d924a6d5ea4431b7987549fdf6": {
"Name": "diag-nginx-01",
"EndpointID": "51dfaa5de3d57ab795a6c613efaf3137bfac5c82af2e5f7eff7ddff3c620e1d0",
"MacAddress": "0e:db:73:f5:c4:f3",
"IPv4Address": "172.17.0.2/16",
"IPv6Address": ""
},
"bc38637baed0dacec6d2dd64a8b50b364039dd9bb7b29e82decc9c2a84c7c9c5": {
"Name": "academy-bind-nginx-01",
"EndpointID": "060021e944f60c6ca598e5b23d4f39e46954018327e72ef9865594de7aaec49e",
"MacAddress": "e2:97:e7:17:8f:b8",
"IPv4Address": "172.17.0.3/16",
"IPv6Address": ""
}
}
---snip---
Das Netzwerk verwendet den Treiber bridge und besitzt das IPv4-Subnetz 172.17.0.0/16. Als Standardgateway ist 172.17.0.1 vorgesehen. IPv6 ist für dieses Docker-Netzwerk nicht aktiviert.
Im Abschnitt Containers werden die angeschlossenen Container mit ihren jeweiligen MAC- und IP-Adressen aufgeführt. Dadurch lässt sich feststellen, welche Container demselben Netzwerk angehören und unter welchen Adressen sie dort erreichbar sind.
Die IP-Adresse des Gateways ist auf dem Linux-Host der Bridge-Schnittstelle docker0 zugewiesen. Dies lässt sich unabhängig von Docker überprüfen:
$ ip addr show docker0
---snip---
inet 172.17.0.1/16 brd 172.17.255.255 scope global docker0
---snap---
Damit ist bestätigt, dass das von Docker verwaltete Netzwerk bridge auf einer tatsächlichen Linux-Netzwerkschnittstelle basiert.
Neben der Loopback-Schnittstelle lo besitzt der Container eine virtuelle Ethernet-Schnittstelle eth0 mit der IP-Adresse 172.17.0.4/16.
Die Bezeichnung eth0@if19 gibt einen Hinweis auf das verwendete virtuelle Ethernet-Paar (veth-Pair). Der Schnittstellenindex 19 bezeichnet das andere Ende dieser Verbindung, das sich im Netzwerk-Namespace des Linux-Hosts befindet.
Die dort vorhandenen Netzwerkschnittstellen lassen sich mit folgendem Befehl anzeigen:
$ ip -o link show
---snip---
4: docker0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP mode DEFAULT group
---snap---
19: veth71a1029@if2: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue master docker0 state UP
---snip---
Die Schnittstelle veth71a1029 besitzt den Index 19 und verweist ihrerseits mit @if2 auf die Schnittstelle 2 im Container. Die Angabe master docker0 bestätigt, dass dieses Ende des virtuellen Ethernet-Paars an die Linux-Bridge angeschlossen ist.

Damit lässt sich die Verbindung zwischen Container und Bridge auf beiden Seiten nachvollziehen.
Direkte Kommunikation zwischen Containern
Die Kommunikation innerhalb des Bridge-Netzwerks lässt sich mit zwei bereits laufenden nginx-Containern überprüfen.
Der Container academy-volume-nginx-01 besitzt die Adresse 172.17.0.4, während academy-bind-nginx-01 unter 172.17.0.3 erreichbar ist. Beide befinden sich im selben Subnetz 172.17.0.0/16.
Mit folgendem Befehl wird aus dem ersten Container eine HTTP-Anfrage an den zweiten gesendet:
$ sudo docker exec academy-volume-nginx-01 wget -qO- http://172.17.0.3:80
<!DOCTYPE html>
<html lang="de">
<head>
<meta charset="UTF-8">
<title>Docker Lernprojekt</title>
</head>
<body>
<h1>Docker Bind Mount</h1>
<p>Diese Webseite liegt auf dem Docker-Host.</p>
<p>Sie wird von nginx aus einem Container ausgeliefert.</p>
<p>Diese Zeile wurde nach dem Containerstart hinzugefügt.</p>
</body>
</html>
Die erfolgreiche HTTP-Anfrage bestätigt, dass die beiden Container unmittelbar über ihre internen IP-Adressen miteinander kommunizieren können. Bemerkenswert ist, dass der zweite nginx-Container zwar über den Host-Port 8081 erreichbar ist, für die interne Kommunikation aber sein tatsächlicher Dienstport 80 verwendet wird. Die veröffentlichte Portzuordnung spielt dabei keine Rolle.
Standardgateway und Kommunikation mit externen Netzwerken
Container im Bridge-Netzwerk können nicht nur untereinander kommunizieren, sondern auch Verbindungen zu Systemen außerhalb ihres eigenen Subnetzes aufbauen. Die dafür erforderliche Weiterleitung übernimmt der Netzwerkstack des Linux-Hosts.
Als Standardgateway dient den Containern gewöhnlich die IP-Adresse der Linux-Bridge docker0. In unserer Lernumgebung besitzt sie die Adresse 172.17.0.1/16.
Die Routingtabelle eines Containers lässt sich mit folgendem Befehl anzeigen:
$ sudo docker exec academy-volume-nginx-01 ip route
default via 172.17.0.1 dev eth0
172.17.0.0/16 dev eth0 scope link src 172.17.0.4
Die erste Zeile definiert die Standardroute. Pakete an Ziele außerhalb des eigenen Subnetzes werden über das Gateway 172.17.0.1 an den Linux-Host übergeben.
Die zweite Zeile beschreibt das direkt angeschlossene Docker-Netzwerk. Ziele innerhalb des Subnetzes 172.17.0.0/16 sind unmittelbar über die Netzwerkschnittstelle eth0 erreichbar.
Routing und Network Address Translation
Damit der Linux-Host Pakete zwischen verschiedenen IP-Netzen weiterleiten kann, muss das IPv4-Forwarding aktiviert sein. Der aktuelle Zustand lässt sich mit folgendem Befehl überprüfen:
$ sudo sysctl net.ipv4.ip_forward
net.ipv4.ip_forward = 1
Zusätzlich richtet Docker für das standardmäßige Bridge-Netzwerk Regeln für Network Address Translation (NAT) ein.
Verbindet sich beispielsweise ein Container mit einem Webserver im Internet, verwendet er zunächst seine interne IP-Adresse 172.17.0.4 als Quelladresse. Der Linux-Host leitet das Paket anhand seiner Routingtabelle weiter. Beim Verlassen über die physische Netzwerkschnittstelle kann die Quelladresse mittels IP-Masquerading durch die entsprechende IP-Adresse des Hosts ersetzt werden.
Die Rückantwort wird anhand der Verbindungsinformationen des Linux-Kernels wieder dem ursprünglichen Container zugeordnet.

Auf dem Docker-Host läßt sich die NAT-Regel mit folgendem Kommando nachprüfen:
$ sudo iptables -t nat -S
-P PREROUTING ACCEPT
-P INPUT ACCEPT
-P OUTPUT ACCEPT
-P POSTROUTING ACCEPT
-N DOCKER
-A PREROUTING -m addrtype --dst-type LOCAL -j DOCKER
-A OUTPUT ! -d 127.0.0.0/8 -m addrtype --dst-type LOCAL -j DOCKER
-A POSTROUTING -s 172.17.0.0/16 ! -o docker0 -j MASQUERADE
-A DOCKER ! -i docker0 -p tcp -m tcp --dport 8080 -j DNAT --to-destination 172.17.0.2:80
-A DOCKER ! -i docker0 -p tcp -m tcp --dport 8081 -j DNAT --to-destination 172.17.0.3:80
-A DOCKER ! -i docker0 -p tcp -m tcp --dport 8082 -j DNAT --to-destination 172.17.0.4:80
-A DOCKER ! -i docker0 -p tcp -m tcp --dport 8083 -j DNAT --to-destination 172.17.0.5:80
pronto@ps-docker:~$
Diese Regel sorgt dafür, dass Pakete aus dem Docker-Subnetz einer Quelladressübersetzung unterzogen werden, wenn sie den Host über eine andere Schnittstelle als docker0 verlassen. Bei der direkten Kommunikation zwischen Containern innerhalb desselben Bridge-Netzwerks ist diese Adressübersetzung nicht erforderlich.
Die Netzwerkmodi bridge, host und none
Docker stellt unter Linux standardmäßig die Netzwerkmodi bridge, host und none zur Verfügung. Sie unterscheiden sich insbesondere darin, ob Container einen eigenen Network Namespace verwenden und wie sie mit dem Netzwerk des Docker-Hosts verbunden sind.
Bridge-Modus
Docker richtet für jeden angeschlossenen Container eine virtuelle Netzwerkschnittstelle mit einer eigenen IP-Adresse ein. Über die Linux-Bridge docker0 können Container miteinander kommunizieren und bei entsprechender Konfiguration auch externe Netzwerke erreichen.
Da jeder Container einen eigenen Network Namespace besitzt, können mehrere Container denselben internen Dienstport verwenden. Sollen diese Dienste über den Docker-Host erreichbar sein, können sie mithilfe von Port-Mapping auf unterschiedliche Host-Ports veröffentlicht werden.
Ein Container lässt sich ausdrücklich im Bridge-Modus starten:
$ sudo docker run --rm --network bridge alpine ip addr
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN qlen 1000
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
inet 127.0.0.1/8 scope host lo
---snip---
2: eth0@if31: <BROADCAST,MULTICAST,UP,LOWER_UP,M-DOWN> mtu 1500 qdisc noqueue state UP
link/ether 96:fb:1a:1f:41:48 brd ff:ff:ff:ff:ff:ff
inet 172.17.0.6/16 brd 172.17.255.255 scope global eth0
---snip---
Host-Modus
Im Host-Modus verwendet ein Container unmittelbar den Netzwerk-Namespace des Linux-Hosts. Er erhält daher weder eine eigene Container-IP-Adresse noch eine separate virtuelle Netzwerkschnittstelle.
Ein im Container gestarteter Netzwerkdienst verwendet dieselben IP-Adressen und denselben Port-Namensraum wie andere Prozesse des Hosts. Dadurch können Portkonflikte entstehen, wenn mehrere Prozesse dieselbe Kombination aus IP-Adresse, Transportprotokoll und Port belegen möchten.
Das Verhalten lässt sich mit folgendem Befehl untersuchen:
$ sudo docker run --rm --network host alpine ip addr
---snip---
2: enp1s0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc fq_codel state UP qlen 1000
link/ether 48:21:0b:7d:a0:3f brd ff:ff:ff:ff:ff:ff
inet 192.168.178.119/24 brd 192.168.178.255 scope global dynamic noprefixroute enp1s0
---snip---
4: docker0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP
link/ether ea:75:50:8a:61:03 brd ff:ff:ff:ff:ff:ff
inet 172.17.0.1/16 brd 172.17.255.255 scope global docker0
---snip---
Die Ausgabe zeigt die Netzwerkschnittstellen des Docker-Hosts, darunter beispielsweise enp1s0 und docker0.
Da Container im Host-Modus unmittelbar auf den Netzwerkstack des Hosts zugreifen, ist kein Docker-Port-Mapping erforderlich. Die Netzwerkisolation zwischen Container und Host entfällt weitgehend. Andere Isolationsmechanismen von Docker bleiben grundsätzlich bestehen.
None-Modus
Im Netzwerkmodus none erhält der Container einen eigenen Network Namespace, jedoch keine externe Netzwerkanbindung.
Innerhalb des Containers steht lediglich die Loopback-Schnittstelle lo zur Verfügung. Netzwerkverbindungen zu anderen Containern, zum Docker-Host oder zum Internet sind über die standardmäßige Netzwerkkonfiguration nicht möglich.
Der Modus lässt sich folgendermaßen untersuchen:
$ sudo docker run --rm --network none alpine ip addr
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN qlen 1000
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
inet 127.0.0.1/8 scope host lo
---snip---
Der Modus eignet sich beispielsweise für Verarbeitungsaufgaben, die keine Netzwerkverbindung benötigen. Er ersetzt allerdings keine vollständige Sicherheitsisolation des Containers.
Vergleich der Netzwerkmodi
| Eigenschaft | bridge | host | none |
|---|---|---|---|
| Eigener Network Namespace | Ja | Nein | Ja |
| Eigene Container-IP | Ja | Nein | Nein |
Verbindung über docker0 | Ja | Nein | Nein |
| Externe Netzwerkverbindungen | Normalerweise möglich | Über den Host | Nicht möglich |
| Docker-Port-Mapping | Möglich | Nicht erforderlich | Nicht möglich |
| Netzwerkisolation zum Host | Vorhanden | Weitgehend aufgehoben | Sehr weitgehend |
| Typische Verwendung | Webanwendungen und miteinander kommunizierende Dienste | Anwendungen mit besonderen Netzwerkanforderungen | Aufgaben ohne Netzwerkbedarf |
Für die meisten gewöhnlichen containerisierten Anwendungen ist der Bridge-Modus die geeignete Ausgangsbasis. Der Modus eignet sich beispielsweise für lokale Verarbeitungs- und Verwaltungsaufgaben, die keine externe Netzwerkverbindung benötigen. Die weiterhin verfügbare Loopback-Schnittstelle ermöglicht dabei die Kommunikation zwischen mehreren Prozessen innerhalb desselben Containers, beispielsweise zwischen einer Anwendung und einem ausschließlich lokal erreichbaren Hintergrunddienst.
Benutzerdefinierte Bridge-Netzwerke bieten darüber hinaus zusätzliche Möglichkeiten zur Trennung von Containergruppen und zur Kommunikation über Containernamen.
Fazit
Docker verwendet die Netzwerkfunktionen des Linux-Kernels, um Container miteinander, mit dem Host und mit externen Netzwerken zu verbinden. Network Namespaces ermöglichen dabei getrennte Netzwerkumgebungen, während virtuelle Ethernet-Paare und Linux-Bridges die Kommunikation zwischen Containern herstellen.
Der standardmäßige Bridge-Modus bietet eine eigene IP-Adresse für jeden Container und ermöglicht die Kommunikation über ein gemeinsames virtuelles Netzwerk. Routing und NAT werden vom Linux-Host übernommen, wobei Docker die erforderlichen Netzwerkregeln weitgehend automatisch einrichtet.
Die Netzwerkmodi host und none bieten alternative Betriebsarten, bei denen entweder der Netzwerk-Namespace des Hosts gemeinsam genutzt oder auf eine externe Netzwerkanbindung verzichtet wird.
Für den Betrieb mehrerer zusammenarbeitender Container sind insbesondere benutzerdefinierte Bridge-Netzwerke von Bedeutung. Sie ermöglichen eine gezieltere Netzwerksegmentierung und eine automatische Namensauflösung zwischen den angeschlossenen Containern.
Befehlszeilenreferenz
| Befehl | Funktion |
|---|---|
docker network ls | Vorhandene Docker-Netzwerke anzeigen |
docker network inspect bridge | Konfiguration des Standard-Bridge-Netzwerks anzeigen |
docker exec <container> ip addr | Netzwerkschnittstellen eines Containers anzeigen |
docker exec <container> ip route | Routingtabelle eines Containers anzeigen |
ip -o link show | Netzwerkschnittstellen des Linux-Hosts anzeigen |
ip addr show docker0 | IP-Konfiguration der Linux-Bridge anzeigen |
sysctl net.ipv4.ip_forward | IPv4-Forwarding des Hosts überprüfen |
iptables -t nat -S | NAT-Regeln anzeigen |
docker run --rm --network <modus> alpine ip addr | Netzwerkmodus eines temporären Containers untersuchen |
![]()