Das Netzwerk von Docker
ist work in progress
Ausgangslage Linux System (Netz bei Windows und MAC anders) Ein Ethernet-Interface mit oeffentlicher Adresse enp4s0 Ethernet Hwaddr c8:60:00:88:70:55 inet addr:134.76.82.240 Bcast:134.76.82.255 Mask:255.255.255.0
Die Docker Bridge Docker legt eine bridge an: docker0 eine Bridge ist wie ein virtueller Hub alle angeschlossenen Interfaces sehen alle Ethernetpakete mit privater Adresse 172.17.0.1 (Class B Netz) docker0 HWaddr 02:42:10:e2:6e:1a inet addr:172.17.0.1 Bcast:0.0.0.0 Mask:255.255.0.0
Die virtuellen Interfaces pro Container wird ein virtuelles Ethernet- Interface an die Bridge angeschlossen : veth4f37176 Ethernet HWaddr 86:ac:44:24:7a:46 IP-adresse mit ip bzw. ifconfig nicht sichtbar ist aber aus dem 172.17.0.0/16-Netz Routing ist zwischen Bridge und realen Interface ist eingeschaltet: 1 in /proc/sys/net/ipv4/ip_forward
Das NAT-Netzwerk Jeder Container bekommt eine private IP- Adresse aus 172.17.0.0/16 iptables realisiert das NAT-Netzwerk unter Linux
iptables das Wichtigste Firewall von Linux Es gibt tables, chains und rules Eine table enthaelt mehrere chains Die chains enthalten die rules
ip Pakete enthalten folgende Informationen source ip-adresse und TCP/UDP Port destination ip-adresse und TCP/UDP Port haben aus der Sicht von iptables einen connection state (cstate): NEW, ESTABLISHED, RELATED, INVALID
Targets Die iptables rule legt an Hand der Informationen im ip-paket fest, was mit dem Paket passiert. Das springt (jump) zu einem Ziel (target) zulaessige targets sind: ACCEPT, DROP, RETURN,DNAT,MASQUERADE oder eine selbstdefinierte chain
vordefinierte tables & chains filter INPUT (destination Adresse ist eine IP-Adresse der Firewall) OUTPUT (source Adresse ist eine IP-Adresse der Firewall) FORWARD (source und destination keine IP-Adresse der Firewall) nat PREROUTING (routing Entscheidung) INPUT OUTPUT POSTROUTING (Adressen umschreiben)
iptables (filter table) iptables L chain INPUT (policy ACCEPT) target prot opt source destination Chain FORWARD (policy DROP) target prot opt source destination DOCKER ISOLATION all anywhere anywhere ACCEPT all anywhere anywhere ctstate RELATED,ESTABLISHED DOCKER all anywhere anywhere ACCEPT all anywhere anywhere Chain OUTPUT (policy ACCEPT) target prot opt source destination
docker chains Chain DOCKER (1 references) target prot opt source destination ACCEPT tcp anywhere 172.17.0.2 tcp dpt:http Chain DOCKER ISOLATION (1 references) target prot opt source destination RETURN all anywhere anywhere
iptables NAT-Tabelle iptables L t nat Chain PREROUTING (policy ACCEPT) target prot opt source destination DOCKER all anywhere anywhere ADDRTYPE match dst type LOCAL Chain INPUT (policy ACCEPT) target prot opt source destination Chain OUTPUT (policy ACCEPT) DOCKER all anywhere!loopback/8 ADDRTYPE match dst type LOCAL Chain POSTROUTING (policy ACCEPT) MASQUERADE all 172.17.0.0/16 anywhere MASQUERADE tcp 172.17.0.2 172.17.0.2 tcp dpt:http Chain DOCKER (2 references) RETURN all anywhere anywhere DNAT tcp anywhere anywhere tcp dpt:http to:172.17.0.2:80
docker-proxy docker-proxy -proto tcp -host-ip 0.0.0.0 -host-port 80 -container-ip 172.17.0.2 -container-port 80 Portforwarding aller Pakete, die am Host an einem Port ankommen zu diesem Port eines Containers, wenn sie nicht von iptables behandelt werden koennen Pakete an 127.0.0.0/8 werden nicht geroutet => Die Weitergabe uebernimmt docker-proxy
docker expose docker run --name miwww --expose 80 Kann auch im Dockerfile benutzt werden EXPOSE Eigentlich nur informativ
docker publish docker run --name miname --publish 53:53/udp --publish 53:53/tcp Stellt Port wirklich zur Verfuegung startet docker-proxy erstellt die iptables rules
docker network inspect docker network inspect bridge "Name": "bridge", "Id": "b2c3b8a497065dfbbc799da87b2ea24125eaabdd9c17dcf5db5a357766ca6e46", "Created": "2017-08-04T11:32:45.648502628+02:00", "Scope": "local", "Driver": "bridge", "EnableIPv6": false, "IPAM": { "Driver": "default", "Options": null, "Config": [ { "Subnet": "172.17.0.0/16", "Gateway": "172.17.0.1" }
container mit fester Adresse Beim Start container: ip a add ip-adresse/netmask dev device ip a eth0: link/ether c8:60:00:88:71:ae brd ff:ff:ff:ff:ff:ff inet 134.76.82.243/24 brd 134.76.82.255 scope global eth0 inet 134.76.82.247/24 scope global secondary eth0 inet 134.76.82.50/24 scope global secondary eth0 inet 134.76.82.58/24 scope global secondary eth0 inet 134.76.82.57/24 scope global secondary eth0 Beim Stop container: ip a del ip-adresse/netmask dev device
Ports Jeder Port auf einem Docker Host ist nur einmal verfuegbar Zu erforschen: vielleicht mit den richtigen rules stimmt diese Aussage nicht mehr
Inside in /etc/hosts steht die IP-Adresse /etc/resolv.conf vom Host normalerweise keine net-tools
Was fehlt User-defined networks Overlay networks in swarm mode Overlay network without swarm mode
Links https://docs.docker.com/engine/userguide/networking http://windsock.io/the-docker-proxy/ http://www.selflinux.org/selflinux/html/iptables.html https://www.ctl.io/developers/blog/post/docker-networkingrules/