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.255Ok 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 alpineNotice that I used --name parameter so I can call my container with this name instead of its alphanumeric id.
docker container lswill return us our container. Yep it's running. Now let's check container's ip.
docker container inspect alpine1will 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}}" alpine1In 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 lsThis command will return virtual networks of docker containers. "bridge" is the default one. Which containers is using this virtual network then?
docker network inspect bridgeUnder 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_networkLet'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 localYep now let's attach the existing container to this virtual network.
docker network connect my_custom_network alpine1If you want to check what's bound to this network:
docker network inspect my_custom_networkYou'll see that it's successful.
docker container run -t -d --name alpine2 --network my_custom_network alpineIf you do network inspect you'll see alpine1 and alpine2 as containers.
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 msNice! 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.