Skip to content
Back

Docker, boot2docker and DNS resolution of containers

Dockerboot2dockerCloud

... or how to setup a full development environment with docker (on Mac OS X)

This tutorial should help to setup a development environment on Mac OS X that relies heavily on docker and boot2docker. Based on my experience, docker is an excellent tool to create and run applications very effectively during dev, test and production. However, not having great development environment where docker can be used effectively slows you down and requires a lot of hand-tuning each an every time during the development process.

Goal of this tutorial

The goal is to have the following capabilities available after you complete this guide.

  1. Run docker containers from your dev machine and have seamless access to all container using their IPs.
  2. Enable DNS capabilities for all containers and being able to resolve them from your dev machine.
  3. Ensure that this will also work if you have to use a corporate VPN client (like Cisco AnyConnect).
  4. Being able to quickly set this up and tear it down with a simple script.

Prerequisites

  • Mac OS X (this guide is not required for Linux because it can run docker natively)
  • boot2docker v1.1.1
  • docker v1.1.1
  • git for checking out the git repo with the scripts

What is the current problem?

If you start a docker container on MacOS, it will actually be running inside a VirtualBox VM that boot2docker is setting up for you under the cover. The consequence is that each docker container cannot be pinged or resolved from the Mac which makes it hard to use during development.

Start a docker container and run a server with nc

$ docker run -i -t ubuntu bash
root@4cb806d8ddab:/# ifconfig eth0
eth0      Link encap:Ethernet  HWaddr be:70:6a:45:22:ee
          inet addr:172.17.0.4  Bcast:0.0.0.0  Mask:255.255.0.0
root@4cb806d8ddab:/# nc -l 7777

Try to connect to the server

$ telnet 172.17.0.4 7777
Trying 172.17.0.4...
telnet: connect to address 172.17.0.4: Operation timed out

It will timeout because the IP cannot be resolved. So let's fix that...

Setting up boot2docker

Initialize the boot2docker-vm

$ boot2docker init --dhcp=false --hostip=172.16.0.1

Start boot2docker-vm

$ boot2docker up

Configure host-only network adapter

$ boot2docker ssh "sudo ifconfig eth1 172.16.0.11 netmask 255.255.0.0"

Setting up a route

$ sudo route -n add 172.17.0.0/16 172.16.0.11

This will ensure that all containers which get a 172.17/16 address can be resolved via the host-only adapter.

Setup DNS for Docker

Now that we are able to ping docker containers seamlessly from our Mac, it would be great to have DNS names automatically registered whenever a docker container comes up. SkyDock and SkyDNS fill this gap.

Changing the arguments of the docker daemon

$ boot2docker ssh
docker@boot2docker:~$ sudo pkill bin/docker
docker@boot2docker:~$ sudo /usr/local/bin/docker -d -g /var/lib/docker \
  -H unix:// -H tcp://0.0.0.0:2375 \
  --bip=172.17.42.1/16 --dns=172.17.42.1 &

Launching SkyDNS and SkyDock

$ docker run -d -p 172.17.42.1:53:53/udp --name skydns \
  crosbymichael/skydns -nameserver 8.8.8.8:53 -domain docker
$ docker run -d -v /var/run/docker.sock:/docker.sock --name skydock \
  crosbymichael/skydock -ttl 30 -environment dev \
  -s /docker.sock -domain docker -name skydns

Testing the DNS server

$ docker run -i -t --name u1 ubuntu bash
$ dig @172.17.42.1 +short u1.ubuntu.dev.docker
172.17.0.8

Connecting to VPN will break things

If you have to use Cisco VPN to connect to your corporate network, you will soon realize that once you do that, pinging the docker containers will no longer work. The fix:

$ sudo ipfw -a list | grep "deny ip from any to any"
00411       94       10039 deny ip from any to any
$ sudo ipfw delete 00411

Scripts

I provided two scripts in my git repo. The enable-docker-dns.sh implements the whole procedure described in this blog. The vpn-fix.sh script can be run every time you reconnect to your corporate VPN.