zhu difeng - Fotolia
Basiswissen und Befehle für die Docker-Vernetzung
Viele Firmen nutzen Container unter Docker. Wir geben einige Basistipps, wie sich die dafür notwendigen, unterschiedlichen Netzwerke einrichten und nutzen lassen.
Docker-Netzwerke sind für die Kommunikation zwischen Containern und die Verwaltung ihrer Interaktionen mit externen Netzwerken unerlässlich. Die Netzwerkkonzepte von Docker sind eventuell nicht für jeden leicht verständlich, es gibt aber ein paar Basisansätze und Methoden, mit denen jeder Admin mit der Vernetzung beginnen kann. In diesem Beitrag finden Sie einen Überblick über die Grundlagen, einschließlich Befehle und Tipps. Wir erklären die unterschiedlichen Typen der Docker-Netzwerke sowie einige Konfigurationsdetails und wie sich Ports für die Kommunikation freigeben lassen.
Die wichtigsten Netzwerktypen für Docker
Docker unterstützt verschiedene Netzwerktreiber, die unterschiedliche Einsatzzwecke unterstützen. Im Folgenden finden Sie eine Kurzübersicht der wichtigsten Docker-Vernetzungen.
Bridge Network
Das Bridge-Netzwerk ist der Standard-Netzwerk-Typ für Container für Docker. Es ermöglicht Containern mittels IP-Adressen die Kommunikation innerhalb desselben Hosts über ein privates, internes Netzwerk. Dies ist nützlich, wenn Container unnerhalb desselben Hosts miteinander kommuniziereternen Netzwerk getrennt bleiben sollen.
Der Befehl für die Einrichtung des Netzwerks ist
docker network create --driver bridge my-bridge-network
Host Network
Im Host-Netzwerk nutzt der Container den Netzwerk-Stack des Hosts und erhält keine eigene IP-Adresse. Stattdessen verwendet er den IP- und Port-Bereich des Hosts. Das bedeutet, dass die Vernetzung den Container direkt mit dem Host-Netzwerk verbindet, so dass kein Port-Mapping erforderlich ist. Dies ist nützlich für Szenarien, in denen die Leistung entscheidend und der Overhead der Netzwerkübersetzung inakzeptabel ist, zum Beispiel bei Anwendungen, die eine geringe Latenzzeit erfordern.
Ein möglicher Befehl ist
docker run --network host my-container
Overlay Network
Ein Overlay-Netzwerk ermöglicht die Kommunikation von Containern auf verschiedenen Docker-Hosts und bildet ein virtuelles verteiltes Netzwerk. Dies ist besonders nützlich in einer Docker Swarm- oder Multi-Host-Umgebung. Das ist ideal für verteilte Anwendungen und Microservices-Architekturen die multiple Hosts umfassen.
Der Befehl für die Einrichtung des Netzwerks ist
docker network create -d overlay my-overlay-network
Macvlan Network
Macvlan-Netzwerke ermöglichen es Containern, ihre eigenen MAC-Adressen zu haben und als physische Geräte im Netzwerk zu erscheinen. Der Container ist direkt mit dem physischen Netz verbunden. Dieses Netzwerk eignet sich für Legacy-Anwendungen, die direkten Netzwerkzugriff benötigen oder wenn Container als physische Geräte im Netzwerk behandelt werden sollen.
Der Befehl für die Einrichtung dieses Netzwerktyps mit MAC-Adresse ist
docker network create -d macvlan --subnet=192.168.1.0/24 --gateway=192.168.1.1 -o parent=eth0 my-macvlan-network
IPvlan Network
Ähnlich wie Macvlan ermöglicht IPvlan den direkten Anschluss von Containern an das physische Netz, wobei sie ihre eigenen IP-Adressen aus dem Netzbereich erhalten. IPvlan bietet jedoch mehr Flexibilität und Einfachheit, da die Container eine einzige MAC-Adresse gemeinsam nutzen können. Diese Vernetzung kann genutzt werden, wenn Container auf verschiedenen Subnetzen miteinander oder direkt mit dem externen netzwerk kommunizieren sollen. Es eignet sich auch für Netzwerke, die nur geringe Latenz und Overhead tolerieren, beispielsweise für HPC- oder Low-Latency-Anwendungen.
Um dieses Netzwerk zu installieren wird dieser Befehl genutzt
docker network create -d ipvlan --subnet=192.168.1.0/24 --gateway=192.168.1.1 -o parent=eth0 ipvlan-net
None Network
Wenn ein Container mit dem None-Netzwerk verbunden ist, hat er außer der Loopback-Schnittstelle (localhost) keine Netzwerkschnittstellen. Dadurch wird der Container vollständig von jeglicher Netzwerkkommunikation isoliert. Dieses Konstrukt wird verwendet, wenn extrem isolierte Workloads ohne Netzwerkzugriff operieren sollen.
Eine Befehloption ist
docker run --network none my-container
Custom Network
Anwender können sich hier ein benutzerdefiniertes Netzwerk mit einem spezifischen Treiber (beispielsweise Bridge oder Overlay) aufbauen, um die Containerkommunikation zu konfigurieren und verwalten. Das ermöglicht die flexible Anpassung der Netzwerkarchitektur an die Anforderungen der Anwendung, zum Beispiel die Trennung von Frontend- und Backend-Diensten in verschiedenen Netzen.
Der Befehl für die Einstellung ist
docker network create --driver bridge my-custom-network
Docker Host und Bridge Network im Vergleich
Docker kommuniziert über Netzwerkadressen und Ports. Innerhalb von Docker-Hosts werden dafür Host- oder Bridge-Verbindungen genutzt.
Beim Host-Networking sendet der Docker-Host alle Kommunikationsmeldungen über Named Pipes. Diese Methode kann allerdings ein erhöhtes Sicherheitsrisiko bedeuten, da der gesamte Traffic ohne Trennmechanismen über dieselben Container läuft.
Bei der zweiten Variante für Docker, dem Bridge-Netzwerk, wird dies vermieden, indem ein internes Netzwerk erstellt wird, das sich mit dem externen verbindet. Die Liste der verfügbaren Netzwerke ruft man mit dem Befehl docker network ls auf. Der Output sollte dem Beispiel aus Abbildung 1 entsprechen.
Hier sind unter anderem auch die zwei primären Netzwerkoptionen, nämlich Bridge und Host aufgeführt. Die Netzwerkkennungen erscheinen in der ersten Spalte, danach folgen der Netzwerkname, Treiber und unter Scope die Netzdomäne des Treibers. Zwar entsprechen in diesem Beispiel die Namen der Netze denen der Treiber, jedoch sollte man im normalen Gebrauch Doppelbenennungen zugunsten der Eindeutigkeit vermeiden.
Admins können zusätzliche Netze konfigurieren, auf denen sich der Datenverkehr zwischen bestimmten Containergruppen, deren Funktion einheitlich festgelegt wurde, bewegt. Netzwerkverbindungen lassen sich so nach Funktionstypen, wie dem Frontend-Webserver, segmentieren.
Es gibt zudem Unterschiede beim IP Adressing. In einem Bridge-Netzwerk erhält jeder Container seine eigene IP-Adresse vom Bridge-Subnetz. Über diese Adressen kommunizieren die Container miteinander. Um mit externen Netzwerken kommunizieren zu können, nutzen die Conatiner NAT und die IP-Adresse des Hosts. Bei einem Host-Netzwerk haben die Container keine eigenen IP-Adressen, sondern teilen sich die des Hosts und dessen Port. Jeder Service auf den Containern kann direkt über die Host-IP erreicht werden.
In einem Host-Netzwerk ist kein Port Mapping erforderlich, wie es bei einem Bridge Network ist. Bei letzterem benötigen die Conatiner das Port Mapping zum Host-Port, damit die Services nach außen verfügbar gemacht werden können. Der Befehl docker run -p 8080:80 nginx mapped den Container-Port 80 zum Host-port 8080.
Aufgrund des etwas größeren Overheads durch die Nutzung von NAT und dem nötigen Port Mapping liegt die Performance des Bridge-Netzwerk etwas unter dem eines Host-Netzes. Das macht die Bridge-Konfiguration geeignet für die Entwicklung und Tests sowie für Multi-Container-Anwendungen. Host-Netzwerke lassen sich somit besser für Hochleistungsanwendungen und einzelne Container mit hoher Port-Nutzung einsetzen.
So arbeiten Sie mit einem Docker-Netzwerk
Um die Netzwerkkonfiguration einschließlich des Host-Netzwerks, des Subnetzes und des Standard-Gateway zu sehen, verwendet man den Befehl docker network inspect.
Spezifische Informationen über Bridge-Netze findet docker network inspect bridge. Dieser Befehl gibt ist eine Liste einschlägiger Netzwerkinformationen aus (siehe Abbildung 2).
Erzeugt ein Administrator ein Docker-Image, verwendet dieses Image standardmäßig das Bridge-Netzwerk. Um einen bereits laufenden Docker-Container anzubinden, gibt man docker attach ein. Der Befehl verbindet das Administrationsterminal mit dem laufenden Docker-Container über Standard-Ein- und -Ausgabedatenströme (Input/Output oder I/O).
Die wichtigsten Befehle sind hier im Folgenden gelistet, bevor wir auf ein Konfigurationsbeispiel eingehen.
Befehl für das Auflisten von Netzwerken:
docker network ls
Befehl für das Erstellen eines Netzwerks:
docker network create my-network
Zudem lassen sich spezifische Treiber einrichten, wie beispielsweise bridge, overlay oder macvlan:
docker network create --driver bridge my-bridge-network
docker network create --driver overlay my-overlay-network
Befehl für die Verbindung eines Containers zu einem Netzwerk:
docker run -d --name my-container --network my-network nginx
Es lassen sich auch bereits bestehende Container anbinden:
docker network connect my-network my-container
Befehl, um einen Container von einem Netzwerk zu trennen:
docker network disconnect my-network my-container
Befehl zur Überprüfung eines Netzwerks:
docker network inspect my-network
Befehl zum Entfernen eines Netzwerks:
docker network rm my-network
Befehle für erweiterte Netzwerkoptionen, beispielsweise das Einrichten von Aliases oder spezifischen IP-Adressen für Container:
docker run -d --network my-network --network-alias web nginx
docker network create --subnet=192.168.1.0/24 my-subnet-network
docker run --network my-subnet-network --ip 192.168.1.100 nginx
Befehl für das Netzwerk zwischen mehreren Hosts:
docker network create --driver overlay my-multi-host-network
Docker bietet darüber hinaus eine automatische DNS-Auflösung innerhalb benutzerdefinierter Netzwerke. Container können sich gegenseitig über Containernamen oder Alias erreichen, die Docker in die IP des Containers auflöst.
Ein Konfigurationsbeispiel erklärt
Zur Verdeutlichung weiterer Grundlagen für den Aufbau eines Netzwerkes, wird im Folgenden als Beispiel ein Ubuntu-Container im Netzwerk konfiguriert.
Als erstes gibt man folgenden Befehl am Host ein, um einen Basis-Ubuntu-Container zu installieren:
docker network create --driver overlay my-multi-host-network
Hat das System sich mit dem Container verbunden, gibt man die untenstehenden Befehle ein, um den Paketindex zu aktualisieren und anschließend das Softwarepaket Net-Tools zu installieren. Die notwendigen IP-Informationen findet man auf dem Host, der in diesem Beispiel eine auf Docker basierende Ubuntu-Installation ist:
apt-get update
apt-get install net-tools
Nach der Installation des Pakets kann der Admin wie in Abbildung 3 auf grundlegende Verbindungsfunktionen, die IP-Adresskonfiguration und andere Aspekte des Netzwerk-Setups zugreifen.
Danach lässt sich ein neues Netzwerk auf diese Bridge aufbauen. Mit dem nächsten Befehl spezifiziert der Anwender den Treiber für das Netzwerkmanagement, der sich standardmäßig mit der Bridge verbindet.
docker network create --driver bridge newnet
Um das Netzwerk anzubinden und zu verwenden, gibt man den Netzwerktyp und -namen über die Befehlszeile ein, zum Beispiel:
docker run --network=newnet -itd ubuntu
Mit komplexeren Befehlsfolgen lassen sich auch mehrere Einstellungen gleichzeitig festlegen. Das folgende Beispiel stammt von der Docker-Website.
docker network create \
--driver=bridge \
--subnet=172.28.0.0/16 \
--ip-range=172.28.5.0/24 \
--gateway=172.28.5.254 \
mysuperbridgenet
Auf diese Weise kann der Admin Netzwerkdetails wie Subnetze und Gateways konfigurieren. Die gesamte Kommunikation läuft jedoch noch immer über den Host. Deshalb ist ein Mapping auf Host-Ebene für die gesamte externe Kommunikation erforderlich.
Ports und ihre Funktionen
Ports spielen eine essenzielle Rolle in den Docker-Netzwerken, beispielsweise für die Art und Weise, wie Container mit der Außenwelt kommunizieren. Um sich von einem logischen Netzwerk aus mit einem Docker-Image zu verbinden, um etwa HTTP oder HTTPS freizugeben, müssen diese Ports für die Außenwelt verfügbar sein. Dafür werden sie beim Start eines neuen Containers freigegeben, indem innerhalb des betreffenden Befehls das Netzwerk und der Port wie unten gezeigt angegeben werden. Dazu wird der Befehl network=newnet respektive -p80:80 verwendet und anschließend http ausgewählt:
docker run -itd --network=newnet -p 80:80 http
Nun öffnet man einen Webbrowser und navigiert zur IP-Adresse des Docker-Hosts. Ist er fehlerfrei konfiguriert, sollte er den HTTP-Willkommens-Bildschirm des Apache-Webservers anzeigen (Abbildung 4).
Je nach den Anforderungen kann man mehrere Ports spezifizieren. So können Organisationen beispielsweise HTTP und HTTPS auf demselben Host verwenden.
Der Zugriff für externe Abrufe lässt sich auch mit folgendem Befehl einrichten:
docker run -p 8080:80 my-web-server
Danach ist der Service nun unter http://localhost:8080 erreichbar, dort wo der Host-Port 8080 mit dem des Containers (80) verbunden ist.
Für ein Port Mapping lässt sich zum Beispiel Port 3000 des Host mit Port 80 des Containers mit folgendem Befehl einrichten:
docker run -p 3000:80 nginx
Port Binding ist wichtig, um den Container-Port an eine spezifische IP-Adresse zu binden. Der generische Befehl lautet:
-p <host_ip>:<host_port>:<container_port>
Ein spezifisches Beispiel ist dieser Befehl, wonach der Service unter 192.168.1.100:8080 erreichbar ist:
docker run -p 192.168.1.100:8080:80 nginx
Um die Kommunikation zwischen Container zu ermöglichen, lassen sich interne Ports nutzen, ohne diese zum Host hin verfügbar zu machen. Dies ist nützlich für die sichere, interne Kommunikation von Microservices. Zum Beispiel können zwei Container im gleichen Docker-Netzwerk dann direkt ohne Port Mapping kommunizieren. Die Erkennung von Diensten wird über das interne DNS von Docker abgewickelt.
Anwendungssicherheit kann dadurch gewährleistet werden, indem der Admin sorgfältig kontrolliert, welche Ports offengelegt oder abgebildet werden. Dadurch wird die Angriffsfläche begrenzt. Container, die keinen externen Zugriff benötigen, sollten keine Ports freilegen.
Mehrere Container, auf denen derselbe Dienst läuft, können an verschiedene Host-Ports gebunden werden, was einen einfachen Lastausgleich oder Redundanz ermöglicht. So können beisielsweise mehrere Container diesselbe Anwendung ausführen, aber die Zuordnung erfolgt zu verschiedenen Ports auf dem Host.
Diese Grundlagen beziehen sich nur auf Arbeiten auf Host-Ebene. Wird das System auf mehr als einen Host erweitert, gibt es weiterführende Netzwerkoptionen, wie etwa Overlay-Netzwerke. Sie beseitigen viele der manuellen Konfigurationsaufgaben, die auf der Ebene der Einzel-Hosts anfallen.