Docker cannot resolve DNS on private network
Docker populates /etc/resolv.conf
by copying the host's /etc/resolv.conf
, and filtering out any local nameservers such as 127.0.1.1. If there are no nameservers left after that, Docker will add Google's public DNS servers (8.8.8.8 and 8.8.4.4).
According to the Docker documentation:
Note: If you need access to a host’s localhost resolver, you must modify your DNS service on the host to listen on a non-localhost address that is reachable from within the container.
The DNS service on the host is dnsmasq, so if you make dnsmasq listen on your docker IP and add that to resolv.conf, docker will configure the containers to use that as the nameserver.
1 . Create/edit /etc/dnsmasq.conf
† and add these lines:
interface=lo
interface=docker0
2 . Find your docker IP (in this case, 172.17.0.1
):
root@host:~# ifconfig | grep -A2 docker0
docker0 Link encap:Ethernet HWaddr 02:42:bb:b4:4a:50
inet addr:172.17.0.1 Bcast:0.0.0.0 Mask:255.255.0.0
3 . Create/edit /etc/resolvconf/resolv.conf.d/tail
and add this line:
nameserver 172.17.0.1
4 . Restart networking, update resolv.conf
, restart docker:
sudo service network-manager restart
sudo resolvconf -u
sudo service docker restart
Your containers will now be able to resolve DNS from whatever DNS servers the host machine is using.
† The path may be /etc/dnsmasq.conf
, /etc/dnsmasq.conf.d/docker.conf
, /etc/NetworkManager/dnsmasq.conf
, or /etc/NetworkManager/dnsmasq.d/docker.conf
depending on your system and personal preferences.
DNS not working within docker containers when host uses dnsmasq and Google's DNS server are firewalled?
A clean solution is to configure docker+dnsmasq so than DNS requests from the docker container are forwarded to the dnsmasq daemon running on the host.
For that, you need to configure dnsmasq to listen to the network interface used by docker, by adding a file /etc/NetworkManager/dnsmasq.d/docker-bridge.conf
:
$ cat /etc/NetworkManager/dnsmasq.d/docker-bridge.conf
listen-address=172.17.0.1
Then restart network manager to have the configuration file taken into account:
sudo service network-manager restart
Once this is done, you can add 172.17.0.1
, i.e. the host's IP address from within docker, to the list of DNS servers. This can be done either using the command-line:
$ sudo docker run -ti --dns 172.17.0.1 mmoy/ubuntu-netutils bash
root@7805c7d153cc:/# ping www.example.com
PING www.example.com (93.184.216.34) 56(84) bytes of data.
64 bytes from 93.184.216.34: icmp_seq=1 ttl=54 time=86.6 ms
... or through docker's configuration file /etc/docker/daemon.json
(create it if it doesn't exist):
$ cat /etc/docker/daemon.json
{
"dns": [
"172.17.0.1",
"8.8.8.8",
"8.8.4.4"
]
}
(this will fall back to Google's public DNS if dnsmasq fails)
You need to restart docker to have the configuration file taken into account:
sudo service docker restart
Then you can use docker as usual:
$ sudo docker run -ti mmoy/ubuntu-netutils bash
root@344a983908cb:/# ping www.example.com
PING www.example.com (93.184.216.34) 56(84) bytes of data.
64 bytes from 93.184.216.34: icmp_seq=1 ttl=54 time=86.3 ms
Docker container can reach DNS but not resolve hosts
They have fixed the issue in 1.8: https://github.com/docker/docker/issues/13381 Cheers.
Docker doesn't resolve hostname
Docker 1.10 introduced some new networking features which include an internal DNS server where host lookups are done.
On the default bridge network (docker0), lookups continue to function via /etc/hosts
as they use to. /etc/resolv.conf
will point to your hosts resolvers.
On a user defined network, Docker will use the internal DNS server. /etc/resolv.conf
will have an internal IP address for the Docker DNS server. This setup allows bridge, custom and overlay networks to work in a similar fashion. So an overlay network on swarm will populate host data from across the swarm like a local bridge network would.
The "legacy" setup was maintained so the new networking features could be introduced without impacting existing setups.
Discovery
The DNS resolver is able to provide IP's for a docker compose service via the name of that service.
For example, with a web
and db
service defined, and the db
service scaled to 3
, all db
instances will resolve:
$ docker-compose run --rm web nslookup db
Name: db
Address 1: 172.22.0.4 composenetworks_db_2.composenetworks_mynet
Address 2: 172.22.0.5 composenetworks_db_3.composenetworks_mynet
Address 3: 172.22.0.3 composenetworks_db_1.composenetworks_mynet
Docker image stops resolving host.docker.internal after I add 8.8.8.8 DNS entry
architecturally, container solutions all run internal DNS services which forward to upstream DNS providers like 8.8.8.8, if you directly set the DNS to resolve at 8.8.8.8, it won't be "proxied" through internal DNS, which is responsible for resolving docker.internal, etc.
the upstream is set via /etc/resolv.conf, so it's easier if you just update system DNS to 8.8.8.8.
Related Topics
How to Access Environment Variables Inside .Gdbinit and Inside Gdb Itself
How to You Configure The Command Prompt in Linux to Show Current Directory
Create a Hard Link from a File Handle on Unix
Checking If a Binary Compiled with "-Static"
How to Find Files Except Given Name
Is There a 'ssh-Add' Linux Alpine One Liner
Bash Loop Through Directory Including Hidden File
How to Make Sure Only One Instance of a Bash Script Is Running at a Time
How to Detect If a Server Is Using Spdy
Can't Remove, Purge, Unistall Mongodb from Debian
Detecting The Output Stream Type of a Shell Script
Difference Between Dts and Acpi
How to Display The Current Disk Io Queue Length on Linux
Extract a Specific Folder to Specific Directory from a Tar.Gz