Introducing Docker networking

At an earlier point, we have somewhat glanced over our use of IP 172.17.0.1 in the web_server code, and it is something that is not well covered in other materials, but it is a very important thing to understand if you want to have a solid grasp on Docker. When the Docker service is started on a machine, a number of networking iptables rules are added to your machine in order to allow the container to connect to the world through forwarding and vice versa. Effectively, your machine becomes an Internet router for all containers started. On top of this, each new container is assigned a virtual address (most likely in the range of 172.17.0.2+) and any communication it does will be normally invisible to the other containers unless a software-defined network is created, so connecting multiple container on the same machine is actually a really tricky task to do manually without helper software that is in the Docker infrastructure called Service Discovery.

Since we didn't want the overhead of this Service Discovery for now (which we will cover later in more depth), and we couldn't use localhost/127.0.0.1/::1, which would not have worked at all, we needed to give it the Docker virtual router IP (almost always 172.17.0.1) so that it would find our actual machine where other container ports have been bound.

Please note that large parts of this next section do not work on macOS nor Windows machines due to the way their networking stack is implemented for Docker. For those systems, I would suggest that you use an Ubuntu virtual machine to follow along.

If you would like to verify this, we can use a few commands outside and inside of Docker in order to really see what is happening:

$ # Host's iptables. If you have running containers, DOCKER chain wouldn't be empty.
$ sudo iptables -L
<snip>
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
ACCEPT all -- anywhere anywhere
<snip>
Chain DOCKER (1 references)
target prot opt source destination

Chain DOCKER-ISOLATION (1 references)
target prot opt source destination
RETURN all -- anywhere anywhere
<snip>

$ # Host's network addresses is 172.17.0.1
$ ip addr
<snip>
5: docker0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default
link/ether 02:42:3c:3a:77:c1 brd ff:ff:ff:ff:ff:ff
inet 172.17.0.1/16 scope global docker0
valid_lft forever preferred_lft forever
inet6 fe80::42:3cff:fe3a:77c1/64 scope link
valid_lft forever preferred_lft forever
<snip>

$ # Get container's network addresses
$ docker run --rm
-it
web_server /bin/bash


root@08b6521702ef:/# # Install pre-requisite (iproute2) package
root@08b6521702ef:/# apt-get update && apt-get install -y iproute2

<snip>

root@08b6521702ef:/# # Check the container internal address (172.17.0.2)
root@08b6521702ef:/# ip addr

1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
inet 127.0.0.1/8 scope host lo
valid_lft forever preferred_lft forever
722: eth0@if723: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default
link/ether 02:42:ac:11:00:02 brd ff:ff:ff:ff:ff:ff link-netnsid 0
inet 172.17.0.2/16 scope global eth0
valid_lft forever preferred_lft forever

root@08b6521702ef:/# # Verify that our main route is through our host at 172.17.0.1
root@08b6521702ef:/# ip route

default via 172.17.0.1 dev eth0
172.17.0.0/16 dev eth0 proto kernel scope link src 172.17.0.2

root@08b6521702ef:/# exit

As you can see, this system is a bit odd, but it works pretty well. Generally when building bigger systems, service discovery is practically mandatory, so you wouldn't have to worry about such low-level details in the field.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.19.244.187