Skip to main content

Docker DNS, Google, and You

Posted in Tech on April 29th 2016
author photo
COO and Co-Founder

If you live in a part of the world where Google is blocked (China, for example), it's likely that you suffer hostnames that don't reliably resolve inside your Docker containers. This is because Docker containers are configured by default to hit Google nameservers for hostname lookups.

We've addressed another article earlier of the year on How Docker Changed Our Workflow. Herewith a brief introduction for Docker:

What is Docker

Docker containers wrap up a piece of software in a complete filesystem that contains everything it needs to run: code, runtime, system tools, system libraries – anything you can install on a server. This guarantees that it will always run the same, regardless of the environment it is running in. What is Docker?

A "dockerized" application is a collection of pre-configured Docker containers that completely encapsulates all the servers, configuration, and code required to run an application. The containers are portable: they run exactly the same way on everyone's computer, regardless of how their computer is set up (not exactly -- more on this later).

With Docker, you can develop, deploy, test and run the application much faster, therefore shortening the time needed between writing the code and running it.

The Problem

With Rich (our tech lead), we'll demonstrate this problem by spinning up an alpine container on an Ubuntu host with a fresh Docker installation. We're in China.

    # docker run -ti alpine:latest sh

From inside the container, sometimes we can ping baidu.com, and other times we can't.

    / # ping baidu.com
    ping: bad address 'baidu.com'
    / # ping baidu.com
    PING baidu.com (180.149.132.47): 56 data bytes
    64 bytes from 180.149.132.47: seq=0 ttl=53 time=41.421 ms

Let's take a look at /etc/resolv.conf inside the container:

    / # cat /etc/resolv.conf
    # Dynamic resolv.conf(5) file for glibc resolver(3) generated by resolvconf(8)
    # DO NOT EDIT THIS FILE BY HAND -- YOUR CHANGES WILL BE OVERWRITTEN
    search lan

    nameserver 8.8.8.8
    nameserver 8.8.4.4

Surprise, surprise: Google nameservers.

The Solution

What we need to do is tell the Docker daemon to configure containers with viable DNS nameservers at container start time. Doing this is a simple matter of editing /etc/default/docker on an Ubuntu/Debian host. The file looks something like this:

    # Docker Upstart and SysVinit configuration file

    #
    # THIS FILE DOES NOT APPLY TO SYSTEMD
    #
    #   Please see the documentation for "systemd drop-ins":
    #   https://docs.docker.com/engine/articles/systemd/
    #

    # Customize location of Docker binary (especially for development testing).
    #DOCKER="/usr/local/bin/docker"

    # Use DOCKER_OPTS to modify the daemon startup options.
    #DOCKER_OPTS="--dns 8.8.8.8 --dns 8.8.4.4"

    # If you need Docker to use an HTTP proxy, it can also be specified here.
    #export http_proxy="http://127.0.0.1:3128/"

    # This is also a handy place to tweak where Docker's temporary files go.
    #export TMPDIR="/mnt/bigdrive/docker-tmp"

Just uncomment the line containing DOCKER_OPTS and supply the nameserver IPs you want your containers to hit. The following works for me in China; the first server is a public DNS server in China and the second is our LAN gateway.

DOCKER_OPTS="--dns=121.199.20.67 --dns=192.168.10.1"

Restart the Docker daemon:

    # service docker restart 

Now if we spin up a new container, the nameserver IPs that we added to /etc/default/docker appear in the container's resolv.conf.

   # docker run -ti alpine:latest sh

    / # cat /etc/resolv.conf
    search lan
    nameserver 121.199.20.67
    nameserver 192.168.10.1


In conclusion, if your access to Google nameservers is spotty, making a one-line change to the way the Docker daemon starts up will save you DNS-related headaches.