Saturday, October 24, 2020

docker tutorial part 2 - the good the bad and the ip

In this second part of docker tutorial, I'll explain basics of networking in docker with stand-alone containers. Remember from the previous part of the tutorial where we mapped port of our host machine and the container? In this part, we will setup our containers so they can communicate with each other and for that we don't need to do an explicit mapping like we previously did with -p subcommand.

Containers have their own virtual network when created. Let's begin by checking the ip of our host machine and then container ip.

I'm on a mac so I'll do ifconfig:
1ifconfig |grep "inet "
gives me
1inet 192.168.178.164 netmask 0xffffff00 broadcast 192.168.178.255
Ok so my host machine ip is 192.168.178.164. Now let's see the docker container one.
1docker container run -t -d --name alpine1 alpine
Notice that I used --name parameter so I can call my container with this name instead of its alphanumeric id.
1docker container ls
will return us our container. Yep it's running. Now let's check container's ip.
1docker container inspect alpine1
will return a huge list of properties related to container. If you feel on the adventurous side, you can also try format and get less data.
1docker container inspect --format "{{.NetworkSettings.IPAddress}}" alpine1
In my case I got "172.17.0.2" as ip. As you can see it's different than my host machine's ip. The reason is that containers use their own virtual network. Can we check all these virtual networks? We are talking about them but I'm not really convinced if I don't see them.
1docker network ls
This command will return virtual networks of docker containers. "bridge" is the default one. Which containers is using this virtual network then?
1docker network inspect bridge
Under containers part you'll see our alpine1.
1"Containers": {
2           "2b8b07d5062743fc4ffe6dc8557adb25948ae3385d66052b9f254fa60ba52c6d": {
3               "Name": "alpine1",
4               "EndpointID": "5ce2ea615f9022ac6f1cae1af4fa44d1058f79dd73994a96a2d15305b3539f7f",
5               "MacAddress": "02:42:ac:11:00:02",
6               "IPv4Address": "172.17.0.2/16",
7               "IPv6Address": ""
8           }
9       }
What about the promise of containers that can communicate with each other? Let's create a new custom virtual network and connect several alpine containers together.
1docker network create my_custom_network
Let's check if my_customer_network is there:
1NETWORK ID          NAME                     DRIVER              SCOPE
23ad04560bc37        bridge                   bridge              local
3905cd858e5a6        host                     host                local
4cba2a990c957        my_custom_network        bridge              local
Yep now let's attach the existing container to this virtual network.
1docker network connect my_custom_network alpine1
If you want to check what's bound to this network:
1docker network inspect my_custom_network
You'll see that it's successful. 
Now let's get crazy and run a container with a customer virtual network.
1docker container run -t -d --name alpine2 --network my_custom_network alpine
If you do network inspect you'll see alpine1 and alpine2 as containers. 
Now it's time for communication between containers. Let's execute bash on them (or rather ash) and make them ping each other.
1docker container exec -it alpine1 ash
1/ # ping -c 3 alpine2
2PING alpine2 (172.22.0.3): 56 data bytes
364 bytes from 172.22.0.3: seq=0 ttl=64 time=0.117 ms
464 bytes from 172.22.0.3: seq=1 ttl=64 time=0.153 ms
564 bytes from 172.22.0.3: seq=2 ttl=64 time=0.155 ms
Nice! alpine1 was able to ping alpine2! But how? Yes same virtual network and stuff but how do they know each others ip? How the container name gets resolved to an ip? It's thanks to automatic dns resolution. Containers can resolve each other based on their container name regardless of their ip address on the same virtual network. 

To recap, in this part of the course we learnt how to create a virtual network and attach our containers to it so they can communicate with each other. Also we learnt how to check container ip and why it is different than host ip.