By Tcoch

Docker containers and DNS resolution


Why this article ?

I often see some confusion in regard to this subject ... Hell, let's be honest, I was confused too at first. But now that I have a good grasp, let's share!

About 'localhost'

I'm making this short section specifically about localhost, but keep in mind that the base reflection is actually applicable for every DNS request.

When trying to access 'localhost', remember from where you are trying to resolve this:
  • If the command is initiated from your host machine, localhost is your host machine
  • If the command is initiated from within a container, localhost is the container, not the host machine

DNS resolution in a container

Let's launch a container:
$ docker run -it alpine /bin/sh
From this container, what will be available is:
  • localhost: it's this container
  • Everything your host machine could resolve based on its DNS server. If you have some entries in your host file on your host machine, these will not be used by your container

DNS resolution between two related containers

First, let's establish a basic compose.yml file.
name: my_compose_file
services:
  alpine-1:
    image: alpine:latest
    container_name: my_first_alpine
    command: ["tail", "-f", "/dev/null"]
  alpine-2:
    image: alpine:latest
    container_name: my_second_alpine
    command: ["tail", "-f", "/dev/null"]
This is the base minimum we're going to need. However, if you want to deploy it, you might have to declare some other stuff (ports, volume, environment variables, and so on).

Just two containers casually talking to each other

In this configuration, the two containers (named my_first_alpine and my_second_alpine for practicality) can talk to each other directly, as they are on the same docker network. But, handling IP is so boring. How can they access each other with DNS names ?
Using services names
Yes, two containers can talk two each other using the services names ! For us, that would be alpine-1 and alpine-2. Without any configuration needed !
$ docker exec -it my_first_alpine sh
/ # ping alpine-1
PING alpine-1 (172.26.0.2): 56 data bytes
64 bytes from 172.26.0.2: seq=0 ttl=64 time=0.032 ms
64 bytes from 172.26.0.2: seq=1 ttl=64 time=0.130 ms
64 bytes from 172.26.0.2: seq=2 ttl=64 time=0.141 ms
64 bytes from 172.26.0.2: seq=3 ttl=64 time=0.180 ms
^C
--- alpine-1 ping statistics ---
4 packets transmitted, 4 packets received, 0% packet loss
round-trip min/avg/max = 0.032/0.120/0.180 ms
/ # ping alpine-2
PING alpine-2 (172.26.0.3): 56 data bytes
64 bytes from 172.26.0.3: seq=0 ttl=64 time=0.065 ms
64 bytes from 172.26.0.3: seq=1 ttl=64 time=0.077 ms
64 bytes from 172.26.0.3: seq=2 ttl=64 time=0.051 ms
64 bytes from 172.26.0.3: seq=3 ttl=64 time=0.109 ms
^C
--- alpine-2 ping statistics ---
4 packets transmitted, 4 packets received, 0% packet loss
round-trip min/avg/max = 0.051/0.075/0.109 ms
Using container names
Another possibility, is using container names! For us, that would be my_first_alpine and my_second_alpine
$ docker exec -it my_first_alpine sh
/ # ping my_first_alpine
PING my_first_alpine (172.26.0.2): 56 data bytes
64 bytes from 172.26.0.2: seq=0 ttl=64 time=0.022 ms
64 bytes from 172.26.0.2: seq=1 ttl=64 time=0.097 ms
64 bytes from 172.26.0.2: seq=2 ttl=64 time=0.046 ms
64 bytes from 172.26.0.2: seq=3 ttl=64 time=0.074 ms
^C
--- my_first_alpine ping statistics ---
4 packets transmitted, 4 packets received, 0% packet loss
round-trip min/avg/max = 0.022/0.059/0.097 ms
/ # ping my_second_alpine
PING my_second_alpine (172.26.0.3): 56 data bytes
64 bytes from 172.26.0.3: seq=0 ttl=64 time=0.091 ms
64 bytes from 172.26.0.3: seq=1 ttl=64 time=0.218 ms
64 bytes from 172.26.0.3: seq=2 ttl=64 time=0.093 ms
64 bytes from 172.26.0.3: seq=3 ttl=64 time=0.172 ms
^C
--- my_second_alpine ping statistics ---
4 packets transmitted, 4 packets received, 0% packet loss
round-trip min/avg/max = 0.091/0.143/0.218 ms
Using container ID
Doesn't seem like an everyday use, but yes, container ID is also resolved as a DNS alias to point to a container!
$ docker exec -it my_first_alpine sh
/ # hostname
cf01acea6a81
/ # ping cf01acea6a81
PING cf01acea6a81 (172.26.0.2): 56 data bytes
64 bytes from 172.26.0.2: seq=0 ttl=64 time=0.075 ms
64 bytes from 172.26.0.2: seq=1 ttl=64 time=0.034 ms
64 bytes from 172.26.0.2: seq=2 ttl=64 time=0.046 ms
64 bytes from 172.26.0.2: seq=3 ttl=64 time=0.052 ms
^C
--- cf01acea6a81 ping statistics ---
4 packets transmitted, 4 packets received, 0% packet loss
round-trip min/avg/max = 0.034/0.051/0.075 ms
/ # ping 473e0927b715
PING 473e0927b715 (172.26.0.3): 56 data bytes
64 bytes from 172.26.0.3: seq=0 ttl=64 time=0.109 ms
64 bytes from 172.26.0.3: seq=1 ttl=64 time=0.044 ms
64 bytes from 172.26.0.3: seq=2 ttl=64 time=0.296 ms
64 bytes from 172.26.0.3: seq=3 ttl=64 time=0.345 ms
^C
--- 473e0927b715 ping statistics ---
4 packets transmitted, 4 packets received, 0% packet loss
round-trip min/avg/max = 0.044/0.198/0.345 ms
Articles

Find a random article based on a tag:
Socials