Dynamic DNS with docker

May 22, 2017

I’ve been fiddling with dockers lately and have become a little lazy about the IP addresses of the containers. As lazy as the programmer that I am, I decided to configure DDNS with Bind.

This way, I could simply reach out container.sea instead of 172.17.0.22.

To make it work I used the docker Python bindings. The script listens to events and when a container is started, it adds its address to the DNS server using the dnspython module.

First thing first, we need to install the docker and dns python modules :

pip install docker dnspython

Then we can listen on docker events using this snippet :

import docker
client = docker.DockerClient(base_url='unix://var/run/docker.sock')
for event in client.events():
    print(event)

If you start/stop a container you should see events appear !

To dynamically update a DNS zone, you have to configure Bind to allow DDNS, Julien Valroff wrote a good article about this on his blog.

Then you can use this snippet to update a zone :

import dns.query
import dns.tsigkeyring
import dns.update
import sys

keyring = dns.tsigkeyring.from_text({
    'sea.' : 'XXXXXXXXXXXXXXXXXXXXXX=='
})

update = dns.update.Update('container.sea', keyring=keyring)
update.replace('container', 300, 'a', "172.17.0.22")

response = dns.query.tcp(update, '10.0.0.1')

With this code, I put together this little script that creates my domain names as I start/stop my containers : [As a little bonus, I added the systemd service file :)]

Feel free to contact me if you want any more explanations or have a suggestion :)


The blog of an IT and security enthusiast.