Running DnsDock on Docker development environment
Anyone who is using Docker on their development environment will understand the pain of using IP address to connect to a container. DnsDock provides an elegant solution to tackle this issue.
It is a nameserver running inside docker container that monitor running container and map their IP to a domain name. So you can connect to any container using a domain name instead of IP address.
I am running on Ubuntu 15.10 so your configuration might be a little different. But the concept is the same.
Running DnsDock in container as system daemon
The image accepts a number of optional argument.
- nameserver You can specify the forwarding DNS. Any DNS query that this server can not answer will get forwarded to that nameserver.
- domain and environment are use as a suffix for the domain name. The format are <anything>.<container-name>.<image-name>.<environment>.<domain>
Description=DNS Dock Service
ExecStartPre=-/usr/bin/docker pull tonistiigi/dnsdock
ExecStartPre=-/usr/bin/docker rm -f dnsdock
ExecStart=/usr/bin/docker run -name dnsdock -v /var/run/docker.sock:/var/run/docker.sock -p 172.17.42.1:53:53/udp -m 64M tonistiigi/dnsdock -domain=local -environment=dev
ExecStop=/usr/bin/docker rm -f dnsdock
- For more argument on this service, please refer to the project Git repository.
After you have setup that file, you will need to get Systemd to reload its configuration, enable and start the service.
sudo systemctl daemon-reload
sudo systemctl enable dnsdock.service
sudo systemctl start dnsdock.service
You should see dnsdock container running when you run docker ps.
Configure your Docker daemon to use the DNS server
Docker daemon allows you to specify the nameserver to use when building an image.
- You just need to find your Docker daemon configuration file. The following command will give you the location of the Docker service configuration file.
systemctl status docker.service
- Add dns=172.17.42.1 to the ExecStart parameter. For example,
ExecStart=/usr/bin/docker -d --dns=172.17.42.1 -H fd://
- Reload Systemd configuration and restart the Docker service.
Add the new nameserver on the host
To be able to resolve domain name for containers in your environment, you will need to tell the host to use the new nameserver. You can achieve that by appending “nameserver 172.17.42.1” in /etc/resolvconf/resolve.conf.d/head file.
Manually create network bridge for Docker daemon
One of the issue with running nameserver as a container is it interfere with how docker dynamically creation of bridge interface. When Docker starts, it will detect that your DNS is running on 172.17.42.1 and create a bridge on a different IP range. Which in turn change the IP address of your nameserver running inside the container.
To get around that issue, you need to create a permanent bridge for Docker to use. This way it does not need to guess what IP range to create and use.
Before you start, make you have stop docker daemon and shut down the bridge interface that docker created manually.
- Add the following to network interfaces
iface docker0 inet static
- Configure Docker daemon to use this bridge.
ExecStart=/usr/bin/docker -d -b docker0 --dns=172.17.42.1 -H fd://
- Restart your Docker daemon. Make sure the bridge is running on 172.17.42.1
- Try running Dig to resolve your container domain name. It should return 172.17.42.2 if that is the only container running in your environment.
There you have it. Now you can get to your container using domain name instead of IP address. The complication in the setup for me was not knowing the need of manual creating bridge interface. The Docker IP range keeps changing and causes domain name lookup to timeout.
I like to say thank you Tõnis Tiig for building DnsDock, it has made developing on Docker environment so much better.