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
- What Is Overlay Network And How Does Dns Resolution Work (stackoverflow.com)
- How Does The Docker Dns Work (medium.com)
- Networking Configure Dns (docs.docker.com)
- Networking How Docker Container Dns Works (kerneltalks.com)
- Data Centers Docker Networking Basic Dns Configuration (networkcomputing.com)
- Container Linking And Docker Dns (hub.packtpub.com)