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/shFrom 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 basiccompose.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 (namedmy_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 bealpine-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 bemy_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
Socials
Github
Gitlab
Stack
Overflow
LinkedIn