Dnsmasq Workaround with Docker Containers on Ubuntu
The Issue
Dnsmasq is helpful in development situations where a user needs to connect to several different environments. (https://www.thekelleys.org.uk/dnsmasq/doc.html) Domain names are easier to remember than IPs and it follows that a developer using Docker would want to reference these domain names in their application.
However, as of version 1.11.1, Docker Engine has one problematic quirk. Docker Engine automatically replaces nameserver 127.0.0.1 in /etc/resolve.conf with 8.8.8.8. Without being able to send DNS requests to 127.0.0.1, Dnsmasq obviously cannot respond to them.
The Solution
Here we will go over a simple workaround to use Dnsmasq with Docker. This workaround will apply to Ubuntu version 15.10 and up. We are currently using Docker Engine version 1.11.1
There are a number of ways we could set the DNS for a docker file. For this post, our objective is to set a default DNS entry for all of our docker containers to use dnsmasq.
The normal process of setting defaults for Docker involves updating the DOCKER_OPTS variable in /etc/default/docker (https://docs.docker.com/engine/admin/). However, as of ubuntu 15.10, that file is no longer recognized. You need to create a systemd config file that references that default file. (https://docs.docker.com/engine/admin/systemd/).
First we will update /etc/default/docker. Remember that since we cannot use localhost for the DNS entry we will instead use our external IP.
DOCKER_OPTS=”--dns=<eno1_IP> --dns=8.8.8.8”
This allows Docker to send DNS requests to our host, working around the localhost limitation.
Next we need to update our systemd to reference this file.
- Navigate to /etc/systemd/system
- Create a new directory ‘docker.service.d’
- Inside this directory create a file called ubuntu.conf
[Service] EnvironmentFile=/etc/default/docker ExecStart= ExecStart=/usr/bin/docker deamon -H fd:// $DOCKER_OPTS
This will update the Docker Engine so that it respects the defaults in DOCKER_OPTS
We then need to load in the new config: ‘sudo systemctl daemon-reload’
Then restart the Docker Engine itself with: ‘sudo service docker restart’
We can verify that we setup the config correctly by looking at the Docker process:
pgrep -a docker
You should see something like:
1140 /usr/bin/docker daemon -H fd:// --dns 1.2.3.4 --dns 8.8.8.8
If you don’t see the dns flags, something didn’t work right and you need to troubleshoot your config files.
Next restart dnsmasq to ensure it’s listening: ‘sudo service dnsmasq restart’
That’s it! Start up your containers and you should be able to make full use of dnsmasq. If you setup dsnmasq to only listen to a specific interface, you will need to update your dnsmasq.conf to listen on the interface you chose.