Precedence of DNS entry vs. Compose service name

Hi there,

according to the documentation here, containers of the same pod can access each other through their service names as defined in the compose file.

I was wondering how this could interfere with already existing DNS names that are known to the host system.

So for example, let’s assume we have a server that is known under the local DNS names db and db.mycompany.com which resolve to the IP address 10.0.0.42. Let’s furthermore assume that on another machine with IP 10.0.0.1 we have a compose file where the services app and db are defined.

When we then execute a docker-compose up on 10.0.0.1 and an application inside the app container tries to connect to db, which container/machine will it hit? The internal db-container on 10.0.0.1 or the external machine 10.0.0.42?
Will there be some sort of error/warning when executing docker-compose up in the case of overlapping DNS names?

Does anyone have any thoughts on this? It seems as if the service name would shadow / overrule the DNS entry. Can I assume that this is by design or could it just be flaky behaviour depending on other constraints, such as, e.g., timing.

“Services” created via docker compose are containers that are connected via a docker custom network. Containers thus connected use Docker’s embedded DNS server, which resolves container names and aliases itself, and forwards all other lookups to DNS servers configured on the host. This is documented in the first paragraph here. Service names are aliases for the respective containers.

Thus, a service name will always resolve before an external DNS entry.

User definied networks provide service discovery based on dns. Services within a compose file, that use the same user defined network, are able to leverage service discovery. Neither plain docker, nor swarm services implment the concept of pods. Though with swarm services, a service task (created per replica) is comparable to a kubernetes pod, except a service task always has a 1:1 binding - each task does run exactly one container, while a pod can have multiple initContainers and containers.

For a user defined network, entries from the host’s /etc/resolv.conf should be the upstream dns servers.

You can easily test it yourself by attaching a netshoot container into the network namespace of your db container using this command (replace with the name or id of the container):

docker run -it --net container:<container_name> nicolaka/netshoot

Inside the netshoot container, use nslookup to see the behavior for yourself. Since the netshoot container uses --net container:${name or id of the db container} it will use the virtual network interface of the db container and therefor get the same results as the db container would get.

update: I missed the respone of rajchaudhuri. Take my response as additional notes on the topic :slight_smile:

1 Like

Thank you for your explanation and the link you provided. I was not aware that Docker Compose also uses a so-called “custom network” even if I don’t have a networks section in my Compose file. Thus, I didn’t find/look into said paragraph. The relationship between Docker and Docker Compose are not always clear to me. There’s a lot of magic behind the scenes, at least for beginners like myself. :slight_smile:

Again, thanks for clarifying.

Thanks for providing so much additional information. I will definitely look into the netshoot image. That’s new to me. Seems like a great tool.