Automagic discover docker containers with dnsdock and CoreOs
Note: This is the second part of How I develop in PHP with CoreOS and Docker. I recommend reading that post first to get a better view on this post.
Docker is an awesome tool for developing all kinds of applications in an isolated environment. Altough I came across some minor issues and flaws.
- Run only one container on a specific port
- Manually add a container’ IP and domainname in
/etc/hosts
I managed to fix these flaws with dnsdock. dnsdock
is a DNS service discovery for Docker containers written in golang.
In other words, everytime I start a container the dnsdock
service, which is also a container, creates a new dns record pointing to the IP of this container.
This is awesome! Why? Because I don’t need configure a specific port-forwarding to the host machine AND domainnames are added automaticaly.
It’s also possible to add one or more aliases to a specific container.
How to setup
Since I’m using the Docker in CoreOs setup from my previous post - How I develop in PHP with CoreOS and Docker - all we need to do is the following:
- Autostart the
dnsdock
service with CoreOs - Add nameserver entry in
/etc/resolver/docker
to lookup in thednsdock
service - Edit the
Vagrantfile
, so CoreOS accept packets for other IPs - Add a custom route for all the container IPs to the CoreOS IP
- Optional: Add alias domain(s) to your docker command or docker-compose.yml
Autostart dnsdock
with CoreOS
Edit the user-data
file in coreos-vagrant
and add the following under the units
section.
- name: dnsdock.service
enable: true
command: start
content: |
[Unit]
Description=dnsdock
After=docker.service
Requires=docker.service
[Service]
EnvironmentFile=/etc/environment
ExecStartPre=/bin/sh -c '/usr/bin/docker rm -f dnsdock || ls > /dev/null'
ExecStartPre=/bin/sh -c '/usr/bin/docker pull tonistiigi/dnsdock'
ExecStart=/usr/bin/docker run -v /var/run/docker.sock:/var/run/docker.sock --name dnsdock -p ${COREOS_PRIVATE_IPV4}:53:53/udp tonistiigi/dnsdock
ExecStop=/bin/sh -c '/usr/bin/docker stop dnsdock || ls > /dev/null'
Add nameserver entry in /etc/resolver/docker
This way Mac OS X will do a dns lookup
for all domains ending with .docker
.
It’s also possible to change this to a custom development domain, example: dev.jverdeyen.be
echo "nameserver 172.17.8.101" >> /etc/resolver/docker
Edit the Vagrantfile
This will enable promiscuity for some private network interfaces and accept all incoming packages.
...
if File.exist?(CLOUD_CONFIG_PATH)
config.vm.provision :file, :source => "#{CLOUD_CONFIG_PATH}", :destination => "/tmp/vagrantfile-user-data"
config.vm.provision :shell, :inline => "mv /tmp/vagrantfile-user-data /var/lib/coreos-vagrant/", :privileged => true
end
# add these 3 lines
config.vm.provider :virtualbox do |vb|
vb.customize ["modifyvm", :id, "--nicpromisc2", "allow-all"]
end
...
Add a custom route for all the container IPs to the CoreOS IP
Make sure Mac OS X routes all container traffic to the CoreOS VM.
sudo route -n add -net 10.1.0.0 172.17.8.101
Reload vagrant
Vagrant will re-provision the CoreOS settings and startup dnsdock
on boot.
vagrant reload --provision
Note: Sometimes I need to do this twice, because the user_data
changes were not applied properly.
Check dnsdock services
Visit http://dnsdock.docker/services
to see all discovered services.
You can access a running container on containername.imagename.docker
as hostname.
Custom domains
You can add a docker environment variable DNSDOCK_ALIAS
to a container.
docker run --name=nginxtesting -e DNSDOCK_ALIAS="alsohere.docker" yappabe/nginx
This allows you to access this container on: nginxtesting.docker
and alsohere.docker
.
The same can be done in a docker-compose.yml
file.
nginx:
image: yappabe/nginx
environment:
DNSDOCK_ALIAS: web1.docker,web2.docker
Footnote
There is so much more you can achieve with this dnsdock
service.
Thanks for reading
Feel free to leave a comment if you have remarks or like this post