How Does Docker DNS Work

How Does Docker DNS Work

This tutorial will explore learning about and testing DNS in Docker. DNS works a little differently depending on if you are using custom or default networks in your environment. Good working DNS is important with containers since you can’t rely on IP addresses in containers because containers are very dynamic. Containers tend to be ephemeral and changing. That is to say, they get launched, torn down, and moved frequently across environments. This is the nature of a microservices architecture. IP addresses can not be relied on as the way to talk from one container to another because there is no guarantee that the IP addresses will even be the same. This is why Docker has DNS naming built-in and it uses the container name as the equivalent of a hostname for containers to talk to each other. Let’s explore how DNS in Docker works.


Docker DNS Exercise

In this exercise, we want to complete the following steps.

  • Create a new custom network
  • Spin up an Ubuntu Container and connect it to the custom network
  • Spin up a second Ubuntu Container and connect it to the custom network
  • Install the Ping utility on both containers
  • Start both containers
  • Test network connectivity using ping tests from both containers

Create A Custom Network

By creating a custom network in Docker, we enable the automatic DNS resolution for any containers that get attached to this network. You need to ensure you name each container since DNS in Docker works based on the name of the container.

> docker network create custom_network
f37fa69420f0bb17b0dc57ebce73005b9d82ae41ec6690754064ca346aad7a7d


> docker network ls
NETWORK ID          NAME                DRIVER              SCOPE
313d57da9944        bridge              bridge              local
f37fa69420f0        custom_network      bridge              local
4c835cce5ea0        host                host                local
085638da5c3d        none                null                local

Create First Ubuntu Container

When we create the Ubuntu container, we give it a name and specify the network it is to connect to. We also install ping from bash in the container.

> docker container run -it --name ubuntu_one --network custom_network ubuntu
root@b63bf5467665:/# apt update
root@b63bf5467665:/# apt install iputils-ping -y
root@b63bf5467665:/# exit
exit

Create Second Ubuntu Container

In order to test network connectivity between containers, we need to set up a second container and connect it to the same custom network.

> docker container run -it --name ubuntu_two --network custom_network ubuntu
root@899ef9635122:/# apt update
root@899ef9635122:/# apt install iputils-ping -y
root@899ef9635122:/# exit
exit

Start Both Containers

A docker container only stays running if there is an active process running in the container. Since we exited the bash shell on each container above, they stopped. We can start them back up like so.

> docker container start ubuntu_one ubuntu_two
ubuntu_one
ubuntu_two

From Ubuntu One Connect To Ubuntu Two

Now we simply connect to the container and issue a ping command from one to the other.

> docker container exec -it ubuntu_one ping -c 3 ubuntu_two
PING ubuntu_two (172.20.0.3) 56(84) bytes of data.
64 bytes from ubuntu_two.custom_network (172.20.0.3): icmp_seq=1 ttl=64 time=0.137 ms
64 bytes from ubuntu_two.custom_network (172.20.0.3): icmp_seq=2 ttl=64 time=0.148 ms
64 bytes from ubuntu_two.custom_network (172.20.0.3): icmp_seq=3 ttl=64 time=0.255 ms

--- ubuntu_two ping statistics ---
3 packets transmitted, 3 received, 0% packet loss, time 2063ms
rtt min/avg/max/mdev = 0.137/0.180/0.255/0.053 ms

From Ubuntu Two Connect To Ubuntu One

The same test can be performed by connecting to the second container and testing network connectivity back to container one.

> docker container exec -it ubuntu_two ping -c 3 ubuntu_one
PING ubuntu_one (172.20.0.2) 56(84) bytes of data.
64 bytes from ubuntu_one.custom_network (172.20.0.2): icmp_seq=1 ttl=64 time=0.192 ms
64 bytes from ubuntu_one.custom_network (172.20.0.2): icmp_seq=2 ttl=64 time=0.170 ms
64 bytes from ubuntu_one.custom_network (172.20.0.2): icmp_seq=3 ttl=64 time=0.168 ms

--- ubuntu_one ping statistics ---
3 packets transmitted, 3 received, 0% packet loss, time 2100ms
rtt min/avg/max/mdev = 0.168/0.176/0.192/0.010 ms

It works! This exercise shows how DNS automatically works with containers connected to the same custom network. This is good to know since when you have a project with multiple containers, you’ll want them to be able to easily talk to each other. Docker Compose makes this easier by automatically creating new virtual networks when you launch an app making container communication automatic. It helps to see how this works manually, however, so we know what Docker compose is actually doing for us.


How Does Docker DNS Work Summary

  • DNS is used for communication between containers.
  • DNS works differently for the default bridge network vs custom-defined networks.
  • The –link command can be used for manual DNS on the bridge network.
  • Use Names Not IP Addresses – Static IP addressing for containers is an anti patter. Use names for communication instead.
  • Docker DNS – Docker daemon has a built-in DNS server that containers use by default.
  • DNS Default Values – Docker defaults the hostname to the container’s name
  • It is much easier to just create a custom network rather than rely on –link on the bridge network

Learn More