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:
ifconfig |grep "inet "
gives me
inet 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.
docker 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.
docker container ls
will return us our container. Yep it's running. Now let's check container's ip.
docker 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.
docker 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.
docker network ls
This command will return virtual networks of docker containers. "bridge" is the default one. Which containers is using this virtual network then?
docker network inspect bridge
Under containers part you'll see our alpine1.
 "Containers": {
            "2b8b07d5062743fc4ffe6dc8557adb25948ae3385d66052b9f254fa60ba52c6d": {
                "Name": "alpine1",
                "EndpointID": "5ce2ea615f9022ac6f1cae1af4fa44d1058f79dd73994a96a2d15305b3539f7f",
                "MacAddress": "02:42:ac:11:00:02",
                "IPv4Address": "172.17.0.2/16",
                "IPv6Address": ""
            }
        }
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.
docker network create my_custom_network
Let's check if my_customer_network is there:
NETWORK ID          NAME                     DRIVER              SCOPE
3ad04560bc37        bridge                   bridge              local
905cd858e5a6        host                     host                local
cba2a990c957        my_custom_network        bridge              local
Yep now let's attach the existing container to this virtual network.
docker network connect my_custom_network alpine1
If you want to check what's bound to this network:
docker 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.
docker 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.
docker container exec -it alpine1 ash
/ # ping -c 3 alpine2
PING alpine2 (172.22.0.3): 56 data bytes
64 bytes from 172.22.0.3: seq=0 ttl=64 time=0.117 ms
64 bytes from 172.22.0.3: seq=1 ttl=64 time=0.153 ms
64 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.