Docker’s internet won’t be stable or won’t be working properly sometimes, which can lead to a number of obscure errors with your applications like DNS lookups are failing on Docker images.
Here will discuss is DNS the problem and system wide solution for the same.
Is DNS the problem?
Fortunately, it’s easy to test Docker’s DNS.
First, check that basic internet connectivity is working by pinging a public IP address. It should succeed, giving you output similar to this:
# docker run busybox ping -c 5 192.203.230.10 # Ping a London-based NASA
PING 192.203.230.10 (192.203.230.10) 56(84) bytes of data. 64 bytes from 192.203.230.10: icmp_seq=1 ttl=50 time=131 ms 64 bytes from 192.203.230.10: icmp_seq=2 ttl=50 time=133 ms 64 bytes from 192.203.230.10: icmp_seq=3 ttl=50 time=133 ms 64 bytes from 192.203.230.10: icmp_seq=4 ttl=50 time=133 ms 64 bytes from 192.203.230.10: icmp_seq=5 ttl=50 time=132 ms --- 192.203.230.10 ping statistics --- 5 packets transmitted, 5 received, 0% packet loss, time 4005ms rtt min/avg/max/mdev = 131.795/132.963/133.578/0.713 ms
But now try resolving the domain google.com:
# docker run busybox nslookup google.com
Server: 8.8.8.8 Address 1: 8.8.8.8 nslookup: can't resolve 'google.com'
If it fails as shown above, then there is a problem resolving DNS.
Why?
By default, if Docker can’t find a DNS server locally defined in your /etc/resolv.conf file, containers will default to using Google’s public DNS server, 8.8.8.8, to resolve DNS.
In some networks, the administrators intentionally block the use of public DNS servers to encourage people to use the network’s own DNS server.
For this case, Docker containers using the default configuration won’t be able to resolve DNS, rendering the internet effectively unusable from within those containers.
Fix: Overriding Docker’s DNS
Fortunately, it’s easy to directly run a docker container with a custom DNS server.
Discover the address of your DNS server
You can find out what network’s DNS server from within Ubuntu as follows:
# nmcli dev show | grep ‘IP4.DNS’
IP4.DNS[1]: 192.168.0.3
Run Docker with the new DNS server
To run a docker container with this DNS server, provide the –dns flag to the run command. For example, let’s run the command we used to check if DNS is working:
# docker run –dns 192.168.0.3 busybox nslookup google.com
Server: 192.168.0.3 Address 1: 192.168.0.3 Name: google.com Address 1: 2607:f8b0:4007:80a::200e lax02s22-in-x0e.1e100.net Address 2: 216.58.216.46 lax02s22-in-f46.1e100.net
And that’s what success looks like.
Permanent fix
Above mentioned solution is only preferable for temporarily inside restrictive network you only need to run containers directly.
However, most of the time you’ll want this to work by default and keep working on your system, and for any other programs that rely on Docker.
Update the Docker daemon
To achieve this, you need to change the DNS settings of the Docker daemon. You can set the default options for the docker daemon by creating a daemon configuration file at /etc/docker/daemon.json.
You should create this file with the following contents to set two DNS, firstly your network’s DNS server, and secondly the Google DNS server to fall back to in case that server isn’t available:
# vi /etc/docker/daemon.json
{ "dns": ["192.168.0.3", "8.8.8.8"] }
Then restart the docker service:
# systemctl start docker
Testing the fix
Now you should be able to ping google.com successfully from any Docker container without explicitly overriding the DNS server, e.g.:
# docker run busybox nslookup google.com
Server: 192.168.0.3 Address 1: 192.168.0.3 Name: google.com Address 1: 2607:f8b0:4007:80a::200e lax02s22-in-x0e.1e100.net Address 2: 216.58.216.46 lax02s22-in-f46.1e100.net