Reputation: 2182
I'm running several containers on my "Ubuntu 16.10 Server" in a "custom" bridge network with compose 2.9 (in a yml version 2.1). Most of my containers are internally using the same ports, so there is no way for me to use the "host" network driver.
My containers are all links together, using the dedicated links
attribute.
But, I also need to access services exposed outside of my containers. These services have dedicated URL with names registered in my company's DNS server. While I have no problem to use public DNS and reach any public service from within my containers, I just can't reach my private DNS.
Do you know a working solution to use private DNS from a container? Or even better, use host's network DNS configuration?
PS: Of course, I can link to my company's services using the extra_hosts
attribute in my services in my docker-compose.yml file. But... that's definitively not the goal of having a DNS. I don't want to register all my services in my YML file, and I don't want to update it each time services' IP are updated in my company.
Context :
docker-compose.yml file (extract):
version: '2.1'
services:
nexus:
image: sonatype/nexus3:$NEXUS_VERSION
container_name: nexus
restart: always
hostname: nexus.$URL
ports:
- "$NEXUS_81:8081"
- "$NEXUS_443:8443"
extra_hosts:
- "repos.private.network:192.168.200.200"
dns:
- 192.168.3.7
- 192.168.111.1
- 192.168.10.5
- 192.168.10.15
volumes_from:
- nexus-data
networks:
- pic
networks:
pic:
driver: bridge
ipam:
driver: default
config:
- subnet: 172.18.0.0/16
gateway: 172.18.0.1
I tried with and without the ipam
configuration for the pic
network, without any luck.
Tests & Results:
docker exec -ti nexus curl repos.private.network
returns properly the HTML page served by this service
docker exec -ti nexus curl another-service.private.network
Returns curl: (6) Could not resolve host: another-service.private.network; Name or service not known
While curl another-service.private.network
from the host returns the appropriate HTML page.
And "of course" another-service.private.network
is known in my 4 DNS servers (192.168.3.7, 192.168.111.1, 192.168.10.5, 192.168.10.15).
Upvotes: 64
Views: 253646
Reputation: 1344
hostname
I had this problem today and it was a bear to figure out, finally looked at DNS logs to see what was going on.
I tried all the solutions, DNS
, dns_search
, network_mode
set to "host" and still it wouldn't work. Logically everything was in place. But it still wouldn't allow the UI to talk to the API.
network_mode: host
dns:
- 192.168.1.10
dns_search: myprivatedomain.com
I had two containers running on a machine for a UI and API. The UI was supposed to call the API by domain name. They both shared an IP of 192.168.1.10 running on a server with a reverse proxy to translate the name to the container url:port combination.
It came down to the fact of using a private DNS on pihole.
pihole
was forwarding the DNS lookup (A,AAAA) to the main gateway, instead of responding with the same address, because the docker containers had the same IP address. Even though they had different domain addresses, e.g. ui.myprivatedomain.com
and api.myprivatedomain.com
, they were both hosted in Portainer on the same server IP address.
Pihole (and other DNS) may think that it is circular and won't reply to the same address. I had to go to the gateway and create a DNS entry in my Unbound DNS server that basically did the same as Pihole and pointed the api.myprivatedomain.com back to the docker container again on the same IP.
Everything worked after that. The docker configuration was working, but DNS could not be resolved on the network.
I'm not sure if there is a limitation in Pihole or other DNS that can be overridden to prevent this behavior, to make Pihole understand the possibility of multiple hostnames
being on the same IP address
Upvotes: 1
Reputation: 5066
You don't specify which environment you're running docker-compose in e.g Mac, Windows or Unix, so it will depend a little bit on what changes are needed. You also don't specify if you're using the default bridge network in docker on a user created bridge network.
In either case, by default, Docker should try and map DNS resolution from the Docker Host into your containers. So if your Docker Host can resolve the private DNS addresses, then in theory your containers should be able to as well.
I'd recommend reading this official Docker DNS documentation as it is pretty reasonable. Here for the default Docker bridge network, here for user created bridge networks.
A slight gotcha is if you're running using Docker for Mac, Docker Machine or Docker for Windows you need to remember that your Docker Host is actually the VM running on your machine and not the physical box itself, so you need to ensure that the VM has the correct DNS resolution options set. You will need to restart your containers for changes to DNS resolution to be picked up by them.
You can of course override all the default settings using docker-compose
. It has full options for explicitly setting DNS servers, DNS search options etc. As an example:
version: 2
services:
application:
dns:
- 8.8.8.8
- 4.4.4.4
- 192.168.9.45
You'll find the documentation for those features here.
Upvotes: 90