Docker Networking : Part1 Docker Bridge
Debayan Chakraborty
AI- Gen AI architect at Infineon, Ex - Walmart || Ex- Citrix
Spinning up a docker container has now became an integral part of our development cycle . May it be for production platform like Kubernetes,or a testing environment like local Linux laptop the key idea of docker networking is to create a communication between Docker containers and the outside via the host machine. Talking about the communications , this is established with the help of few network drivers .
Going from the top, Docker Bridge can be subdivided in to two categories
Default Bridge
Understanding the default bridge , its automatically created at the time of docker installation , and daemon automatically use it if no other N/W driver is specified . Once Docker is installed , a simple ifconfig to console can show Docker0 as default docker bridge .
docker0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>? mtu 150
??????? inet 172.17.0.1? netmask 255.255.0.0? broadcast 172.17.255.255
??????? inet6 fe80::42:1bff:fe80:f6d0? prefixlen 64? scopeid 0x20<link>
??????? ether 02:42:1b:80:f6:d0? txqueuelen 0? (Ethernet)
??????? RX packets 0? bytes 0 (0.0 B)
??????? RX errors 0? dropped 0? overruns 0? frame 0
??????? TX packets 34? bytes 5136 (5.1 KB)
??????? TX errors 0? dropped 0 overruns 0? carrier 0? collisions 0
0
How Docker Bridge Works
Once a container created in the host , it automatically connects to Docker Bridge establishing a veth pair between container virtual network interface and docker bridge. A "veth pair" is basically a virtual network cable which have a virtual network interface device on each end. So by default container acquires an IP from linux docker bridge(docker0) subnet ( 172.17.0.0/16).
docker inspect nework? bridge
"Containers": {
??????????? "1c23810989b99f829776e348aabc491adf7461b38c6ca670522e9b4b26575d39": {
??????????????? "Name": "sad_leakey",
??????????????? "EndpointID": "2ab9a915a1684df3ef723c518e58f942a98c095cc9307e5af53cfc76d67cca8c",
??????????????? "MacAddress": "02:42:ac:11:00:02",
??????????????? "IPv4Address": "172.17.0.2/16",
??????????????? "IPv6Address": ""
??????????? },
??????????? "5ed1c2a690fad7ecd7ad76b06b9845dc75419483d800fa8b38d50b56db403e8f": {
??????????????? "Name": "lucid_carver",
??????????????? "EndpointID": "24f630921801381ddba701226f921758d85c9dbe612845f19ea3d4827300754d",
??????????????? "MacAddress": "02:42:ac:11:00:03",
??????????????? "IPv4Address": "172.17.0.3/16",
??????????????? "IPv6Address": ""
??????????? }
??????? }
Once we install docker daemon in linux host and Docker0 (bridge) gets created, by default daemon installs two custom iptables chains named DOCKER-USER and DOCKER, and it ensures that incoming packets are always checked by these two chains first.
领英推荐
Run iptables -t nat -L
Chain DOCKER (2 references
target???? prot opt source?????????????? destination??????? ?
RETURN???? all? --? anywhere???????????? anywhere?????????? ?
)
Chain DOCKER-USER (1 references
?pkts bytes target???? prot opt in???? out???? source?????????????? destination??????? ?
??? 0???? 0 RETURN???? all? --? *????? *?????? 0.0.0.0/0??????????? 0.0.0.0/0???
)
Now lets understand ingress & egress traffic to/from a docker container . As docker0 can not be accessed from outside world ,lets try to access it by mapping the container IP and port with Hosts physical network interface . Lets run docker run -d -p 8080:80 nginx:latest . Once the nginx container got provisioned it acquire an IP of 172.17.0.3 ( same subnet of docker0), while our Hosts physical nic's (eth0) IP is 192.168.0.2. So a DNAT rule needs to be there in the Linux Hosts Nat table to forward traffic to 172.17.0.3 port 80 (nginx container's IP) once traffic reaches the physical nic ( eth0 IP 192.168.0.2 ).Docker daemon by default takes care of this by provisioning an iptables chain and assign this chain to PREROUTING chain.
updated chain Docker
ChainCKER (2 references
target???? prot opt source?????????????? destination??????? ?
RETURN???? all? --? anywhere???????????? anywhere?????????? ?
DNAT?????? tcp? --? anywhere???????????? anywhere???????????? tcp dpt:http to:172.17.0.3:80)
PREROUTING chain
Chain PREROUTING (policy ACCEPT
target???? prot opt source?????????????? destination??????? ?
DOCKER???? all? --? anywhere???????????? anywhere???????????? ADDRTYPE match dst-type LOCAL
)
So once inbound traffic reaches the eth0 (physical nic) of the host, Traffic gets forwarded to host's linux kernel where in the Nat iptable PREROUTING chain (rule) gets loaded , internally it checks the DNAT rule in Docker chain . Once it matches , it forward the traffic to the Docker container through docker bridge network.
For the outbound traffic generated from the container flow is almost same . In this case a Source Nat rule gets appended to Nat table by docker daemon in the POST ROUTING chain.
Chain POSTROUTING (policy ACCEPT
target???? prot opt source?????????????? destination??????? ?
KUBE-POSTROUTING? all? --? anywhere???????????? anywhere???????????? /* kubernetes postrouting rules */
MASQUERADE? all? --? 172.17.0.0/16??????? anywhere?????????? ?
MASQUERADE? tcp? --? 172.17.0.3?????????? 172.17.0.3?????????? tcp dpt:http
)
Regarding the communication between 2 or more container's as all the containers are connected to Docker bridge( docker0) . Traffic can communicate between container's via IP address.
Ruby developer
2 年nice explanation about the relationship between docker network and iptables!