Docker Networking ist kompliziert?
Hier ist das Tutorial, welches Deine Netzwerkknoten im Kopf auflöst.
Starten wir!
Warum brauche ich ein Netzwerk für Docker?
Docker ist mehr als nur eine Art virtuelle Maschine. Du kannst virtuellen Rechenzentren innerhalb eines Computers aufbauen, Arbeitslasten trennen und verschiedene Aufgaben jedem Container zu weisen.
Die Anwendungen von Unternehmen liefen früher auf vielen Servern (1 Anwendung = 1 Server), welche mit einem LAN-Kabel verbunden waren. Docker Networking brauchen wir jetzt, um die virtuellen Server virtuell miteinander zu verbinden. Wir bauen unser eigenes digitales Rechenzentrum innerhalb eines Computers.
Natürlich wäre es nett, wenn alle Server zu allen Servern reden können, weil diese auf einer Maschine laufen. Aas birgt ein Sicherheitsrisiko. Wenn eine Anwendung kompromittiert wird, soll eine Netzwerkstücklung in VLANs, die Ausbreitung verhindern.
In der Regel redet ein Container / Anwendung nur mit einem oder zwei anderen Containern:
- Der Datenbank-Container redet mit dem Applikationslogik-Container
- … der Applikationslogik-Container mit dem Frontend-Container
- … der Frontend-Container mit dem Browser des Kunden
Diese Verkettung setzt Docker Networking um.
Vorteile – Was kann ich damit machen?
- Separierung: Wie bereits erklärt, kannst Du verhindern, dass Anwendung A nicht mit Anwendung B redet, wenn Sie es nie brauchen.
- Verbindung: Du kannst Anwendungen reden lassen, welche kommunizieren sollen.
- Performance: Der Art des Networks bestimmt die Performance. Ein Host-Network-Container ist performanter als ein Bridge-Container. Jede virtualisierte Zwischenschicht führt zu einem Performanceverlust.
- Netzwerke über physische Systeme: Ein physischer Server ist meist nicht genug. Wenn einer ausfällt, dann sollte ein zweiter Container auf einem anderen Computer übernehmen. Die virtuellen Netzwerke kannst Du über verschiedene physische Computer aufspannen.
- Domain Name System: Wie verbindet man sich zu einem Server? Der Anwender kennt die Domain und erhält die IP von einem DNS-Server, wenn dieser den Browser verwendet. Das Gleiche macht Docker Networking. Du kennst den Container-Namen und verbindest Dich über die Docker DNS im virtuellen Docker Netzwerk zu der richtigen IP.
Art von Docker Netzwerken?
Das sind Beispiele für jede Netzwerkart:
Bridge Network: Verbinde Container in einem internen Netzwerk. Diseser Typ ist ideal für die meisten Anwendungsfälle. Bei diesem Beispiel sind Container in einem internen Netzwerk verbunden und können miteinander kommunizieren:
docker network create --driver bridge mein_bridge_net
docker run -dit --name mein_container --network mein_bridge_net nginx
Host Network: Nutze das Host-Netzwerk, um die Performance zu verbessern. Der Container arbeitet wie ein native installiertes Programm auf dem Host. Das eignet sich für Anwendungen, die eine geringe Latenz erfordern (DNS, Gameserver):
docker run -dit --name mein_container --network host nginx
Overlay Network: Verbinde Container auf verschiedenen physischen Computern. Voraussetzung: Der Docker Swarm-Mode muss aktiviert sein. Es läuft eine Docker Installation auf allen Computer, welche die gleichen Container verwenden.
docker swarm init
docker network create --driver overlay mein_overlay_net
docker service create --name mein_service --network mein_overlay_net nginx
Macvlan Network: Verleihe einem Container eine eigene MAC-Adresse. Gibt Containern eine eigene MAC-Adresse und lässt diese wie physische Maschinen im Netzwerk agieren:
docker network create -d macvlan \
--subnet=192.168.1.0/24 \
--gateway=192.168.1.1 \
-o parent=eth0 mein_macvlan_net
docker run -dit --name mein_container --network mein_macvlan_net nginx
Das virtuelle LAN-Kabel einstecken
Wenn Du erreichen möchtest, dass die Anwendungen miteinander reden sollen, dann müssen wir diese in ein Netzwerk bringen:
version: "3.9"
services:
jenkins:
image: jenkins/jenkins:latest
container_name: jacklin
ports:
- 60011:80
- 50000:50000
networks:
- super_sec_network
networks:
super_sec_network:
external: true
name: super_sec_network
In diesem Beispiel erstellen wir ein Netzwerk mit dem Namen super_sec_network
und fügen den Container in das Netzwerk ein. Bei dem zweiten Container fügen wir auch das Netzwerk hinzu.
Lege einen Container-Namen fest, um den Container zu erreichen container_name: jacklin
. Du kannst von Container einen ping ausführen mit ping jacklin
und der Container erreicht die Jenkins Instanz.
Häufige Probleme
Blockieren und Umleiten – Das Port Mapping
Beim Port-Mapping leiten wir die Ports um. Der Docker Container „Webserver NGINX“ publiziert seine Webseite über den Port 80. Da schon ein anderes Programm über Port 80 auf dem physischen Computer läuft, wollen wir die Ausgabe auf einen anderen Port umleiten:
version: "3.9"
services:
nginx:
image: nginx/nginx:latest
ports:
- 60011:80
networks:
- mysql_sec_network
Die Schreibweise „60011:80“ bedeutet, dass wir vom internen Port 80 des Docker Container diesen auf 60011 des Host-Systems umleiten. Wir müssen sicherstellen, dass der Port auch frei ist und nicht von einem anderen Container oder einer nativen Anwendung genutzt wird. Der Container startet sonst nicht.
Kein Container wegen blockierten Ports
Docker gibt es auch als Variante rootless. Das bedeutet, wir führen Docker im Nutzerkontext ohne Root Privilegien aus. Diese Art des Betriebs ist sicherer, da Kriminelle nicht direkt auf Root zugreifen können, wenn der Docker deamon kompromittiert ist. Auf der anderen Seite kann diese Docker Installation sich nicht einfach die Standardports von 1 bis 1024 nehmen. Diese sind reserviert für die bekannte Software wie SSH, Telnet, FTP …
Wenn Du doch diese Ports verwenden willst, dann musst Du diesen Befehl ausführen:
sudo sh -c "echo 0 > /proc/sys/net/ipv4/ip_unprivileged_port_start"
oder als Cronjob im Root-Kontext: sudo crontab -e
und dann füge diese Zeile unten ein
@reboot sudo sh -c "echo 0 > /proc/sys/net/ipv4/ip_unprivileged_port_start"
Bessere Performance und Container
Um die beste Performance mit Docker zu erhalten, brauchen wir Grundlagen-Linux-Pakete:
sudo apt-get install -y dbus-user-session
sudo apt-get install -y fuse-overlayfs
sudo apt-get install -y slirp4netns
- dbus-user-session: Dieses Programm hilft Programmen auf Deinem Computer, miteinander zu sprechen. Wichtig für Dienste im Hintergrund.
- fuse-overlayfs: Beschleunigt Dein Dateisystem. Macht das Speichern und Abrufen von Dateien schneller und effizienter.
- slirp4netns: Verbessert die Netzwerkgeschwindigkeit für virtuelle Netzwerke, ermöglicht virtuellen Maschinen schnelleren Internetzugang.
Du kannst Docker auch ohne diese nutzen, aber Du wirst nie Deine Hardware voll ausreizen.
Das Networking Cheat Sheet
Zum Schluss gibt es noch eine Übersicht über wichtige Docker Networking Befehle. Wenn das Netzwerk einmal steht und die Container laufen, musst Du selten das Netzwerk noch verändern.
Befehl | Beschreibung |
---|---|
docker network create <name> | Erstellt ein neues Netzwerk |
docker network ls | Listet alle Netzwerke auf |
docker network rm <name> | Löscht ein Netzwerk |
docker network inspect <name> | Zeigt detaillierte Informationen zu einem Netzwerk an |
docker network connect <network-name> <name> | Verbindet einen Container mit einem Netzwerk |
docker network disconnect <network-name> <name> | Trennt einen Container von einem Netzwerk |
docker network prune | Löscht alle ungenutzten Netzwerke |