docker network

  • https://entwickler.de/online/development/docker-netzwerk-container-microservices-126443.html

  • http://blog.sequenceiq.com/blog/2014/08/12/docker-networking/

  • sehr guter Beitrag: http://stackoverflow.com/questions/24319662/from-inside-of-a-docker-container-how-do-i-connect-to-the-localhost-of-the-mach?rq=1

  • http://www.linuxjournal.com/content/concerning-containers-connections-docker-networking

Getting Started

Ein Container kann ein Netzwerk konfiguriert haben - muß aber nicht. Man kann auch nachträglich ein Netzwerk erzeugen (oder ein bestehendes verwenden) und einkonfigurieren.

Beim Start eines Containers kann das zu verwendende Netzwerk per --network=blablubb angegeben werden:

docker run --network=isolated_nw -itd --name=container3 busybox

Alle Container des gleichen Netzwerks können automatisch miteinander kommunizieren.

Je nach Netzwerkkonfiguration wird ein neues Netzwerkdevice erzeugt, das man per sudo ifconfig sehen kann:

╰─➤  sudo ifconfig
br-37a31f7f9696: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
        inet 172.18.0.1  netmask 255.255.0.0  broadcast 0.0.0.0
        inet6 fe80::99:994ff:fe1a:4a71  prefixlen 64  scopeid 0x20<link>
        ether 99:42:94:1a:4a:71  txqueuelen 0  (Ethernet)
        RX packets 800513  bytes 173457174 (165.4 MiB)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 728155  bytes 294072701 (280.4 MiB)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

Auf dem Docker Host werden IpTables-Einträge für die Kommunikation mit den Containern angelegt - siehe iptables -t nat -L.

Docker Host Konfiguration

Unter Ubuntu findet man die /etc/default/docker, in der wichtige Konfigurationsparameter für den Docker Daemon hinterlegt sind. Folgende Einstellungen sind netzwerktechnisch besonders interessant:

Netzwerktypen

Docker bringt Ünterstützung für folgende Netzwerktypen ... jeder Netzwerktyp ist einem sog. Diver zugeordnet, hat einen Namen, eine ID :

  • docker0 ... veraltet

  • Bridge

    • ausreichend für kleine Netzwerke, die nur auf einem einzigen Host laufen

  • Overlay

    • für verteilte Netzwerke (nicht nur auf einem Host)

  • MACVLAN

Nach der Installation von Docker sind bereits folgende Netzwerk-Interfaces im System registriert:

  • docker0: Default Bridge-Network - veraltet

Zudem existieren schon folgende Docker-Netzwerke:

  • bridge

    • Details zum Treiber findet man per docker inspect bridge

  • host

    • Details zum Treiber findet man per docker inspect host

  • none

Welche Netzwerke die Docker Container verwendet ermittelt man per docker network ls. Details erhält man über die Netzwerk-ID (z. B. 94d431c39280) per docker network inspect 94d431c39280.

Netzwerkinterfaces

Netzwerkkommunikation läuft IMMER über ein Netzwerkinterface ... der Docker-Container hat welche und der Docker-Host auch. Eine Übersicht über alle vorhanden Netzwerkinterfaces erhält man per ifconfig

oder auch ip addr

Diese Netzwerkinterfaces sind i. a. größtenteils nicht physikalisch vorhanden, sondern es handelt sich um virtuelle Devices. Diese virtuellen Devices werden von Docker automatisch auf dem Docker Host angelegt und zudem IPTables Einträge gemacht, um das Routing entsprechend abzubilden.

All diese Interfaces lassen sich anpingen (z. B. ping 172.18.0.1).

Docker Bridged Netzwerk br-1bb4da4d6e7c

... hat die IP-Adresse 172.18.0.1 auf Docker-Host Seite.

Der Netwerkkonfiguration des Docker-Container, der dieses Interface verwendet sieht folgendermaßen aus:

d. h. der Docker-Container (in diesem Fall sind es sogar zwei, die in diesem Subnetz 172.18.0.0 hängen) verwendet die Docker-Host IP-Adresse des Netzwerkinterfaces als Gateway (172.18.0.1). Dadurch ist die non-internal Kommunikation mit der Außenwelt über den Docker Host sichergestellt. Interne Netzwerkkommunikation erfolgt über die internen IP-Adressen ... bei entsprechender Alias-Konfiguration (z. B. automatisch bei Verwendung von Docker-Compose) läßt sich der Container über einen logischen Names (foo) adressieren.

Im Docker-Host ist das Netzwerk folgendermaßen ins Routing eingebunden:

Aus diesem Grund kann ich den foo-Service per ping 172.18.0.2 anpingen.

host Netzwerk

Bei einem Host-Netzwerk (docker run --net=host) verhält sich der Container netzwerktechnisch wie der Docker Host, d. h.

  • localhost im Container ist der Docker Host

  • alle Ports, die der Container öffnet sind auch auf dem Docker-Host geöffnet - ACHTUNG: wenn der Container seinen Service an alle Netzwerkinterfaces bindet (0.0.0.0), dann sind die für alle erreichbar (evtl. sind Firewall-Regeln notwendig)

ACHTUNG: braucht man nur den Zugriff auf den Docker Host aus einem Docker Container, dann kann man vielleicht auch ein Bridged Netzwerk verwenden und einen Alias auf das Loopback Device erstellen - siehe Dokumentation. In den neueren Docker-Versionen gibt es meines Wissens FQDN, die richtig geroutet werden ... allerdings ist das dann nur eine Option, die vom Container zum Host funktioniert ... allerdings nicht vom Host zum Container.

bridge Netzwerk

Beim Bridge-Netzwerk erhalten beide Enden der Brücke eine eigene IP-Adresse, d. h.

  • im Docker Host

Iptables

Diese Einstellung auf dem Docker Host regelt Kommunikation auf unterster Ebene. Docker legt hier slebständig eigene Einträge ein, die über abstraktere Konfigurationen (z. B. in docker run oder docker-compose.yml) beschrieben werden. Deshalkb muß man selten in diese Konfiguration schauen, wenn man aber Fehler beheben will, dann kommt man hier nicht herum.

Anpassung /etc/hosts im Docker-Container

Beim Start eines Docker-Containers kann man per docker run --add-host host.docker.internal:172.22.0.1 ... eine Anpassung der /etc/hosts-Datei im Docker-Container vornehmen.

Docker-Network-Subsystem

Einen Überblick über das Subsystem liefert

Hier sind alle erzeugten Netwerke sichtbar

läßt sich darstellen, welche laufenden Container das Docker-Network-Subsystem nutzen. So findet man beispielsweise raus, welche IP-Adressen die Container bekommen haben.

Netzwerk erzeugen

Über

läßt sich eine Netzwerkinstanz mit dem Namen pierre_network erzeugen, so daß zwei Container mit diesem Netzwerk miteinander kommunizieren können:

Anschließend sieht dieses Netzwerk folgendermaßen aus:

Anschließend kann man beispielsweise folgendermaßen die Kommunikationswege prüfen:

Die Auflösung von pierre2 nach 172.20.0.3 macht in User-defined-Networks der Docker-interne DNS, der auch in /etc/resolv.conf des Containers eingetragen ist (mehr Details https://docs.docker.com/engine/userguide/networking/configure-dns/).

Networking mit docker-compose

  • https://docs.docker.com/compose/networking/

Docker-Compose erstellt beim Start sein eigenes Netzwerk, in dem die verschiedenen Container über deren Name erreichbar sind. Das ist auf jeden Fall schon mal komfortabler als in einem reinen Docker-Setup, in dem man das manuell konfigurieren muß (z. B. per docker run --link nachbilden). Die Container kommunizieren über dieses eigene Subnetzwerk. Da Docker-Compose kein HOST Netzwerk verwendet, sondern Bridge oder Overlay kommen sich die Container verschiedener Docker-Compose-Projekte bei den Ports auch nicht in die Quere. Ports müssen explizit an den Docker Host exponiert werden. Außerdem muß ich auch keinen Port zum Docker-Host exponieren ... und damit kann das natürlich auch mit den Ports des Docker-Host nicht in Konflikt stehen.

Mit einem Overlay-Netzwerk kann man sogar über Maschinengrenzen hinweg transparent (für die docker-compose.yml) kommunizieren. Das ist beispielsweise bei Docker-Swarm relevant.

Last updated

Was this helpful?