Docker networking

I spent some time this week working on building a Docker image using a Dockerfile. In the process I learned a little about networking with Docker that I wanted to record here before I forget about it.

One of the steps in building my image was to update the list of packages using apt-get update. Mysteriously during the build I would get these errors:

sudo docker build -t="build_2013-10-03" .
Uploading context 20480 bytes
Step 1 : FROM colinsurprenant/ruby-1.9.3-p448
 ---> 6d1e62cb5cff
Step 5 : RUN apt-get install --assume-yes software-properties-common sudo libmysqlclient-dev vim
 ---> Running in 481577d7acec
Err raring/main libapt-inst1.5 amd64
  Something wicked happened resolving '' (-11 - System error)

Logging in to the container gave me a pointer in the form of a warning and an confirmation of the problem:

sudo docker run -i -t colinsurprenant/ruby-1.9.3-p448 /usr/bin/env bash
WARNING: IPv4 forwarding is disabled.
root@0836328ec06a:/# ping
ping: unknown host

Since Docker containers are run inside a namespace and AuFS is used to hold their files, the only thing shared between the host OS and the container is the kernel. For IP traffic to move between guest and host the kernel must be set to do IP forwarding.

To enable this I needed to use the sysctl command and then restart the Docker daemon:

sudo sysctl -w net.ipv4.ip_forward=1

That little test solved my problem and so the next step was to ensure that the new setting would survive a reboot. As with almost all things on Linux, it just meant editing a configuration file:

sudo vim /etc/sysctl.conf

# Kernel sysctl configuration file for Red Hat Linux
# For binary values, 0 is disabled, 1 is enabled.  See sysctl(8) and
# sysctl.conf(5) for more details.

# Controls IP packet forwarding
net.ipv4.ip_forward = 1

My next learning about how networking works with Docker came from wanting the app in my container to access the MySQL database on the host. It turns out that docker creates a network interface:

mike@sleepycat:~☺  ifconfig
docker0   Link encap:Ethernet  HWaddr 9e:b5:ca:76:70:c3  
          inet addr:  Bcast:  Mask:
          inet6 addr: fe80::9cb5:caff:fe76:70c3/64 Scope:Link
          RX packets:0 errors:0 dropped:0 overruns:0 frame:0
          TX packets:65 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:0 
          RX bytes:0 (0.0 B)  TX bytes:10675 (10.6 KB)

So on the host side I need to get MySQL to bind to, and containers (which will all end up on the 172.x.x.x network) will just connect to that. Don’t forget that your MySQL user ‘x’@’localhost’ won’t be able to connect when its logging in from 172.x.x.x and that you will need to add the “host:” to your database.yml.

The only real down side to all this Docker stuff has been that the extra layer of abstraction can make things a little hard on the head. The potential for repeatable, self documenting app deployments using Dockerfiles is pretty exciting. I’m impressed with what I have seen and I know that what I am doing is still pretty primitive. We’ll see what’s next.


1 thought on “Docker networking”

  1. Thanks for the tip. It is annoying that you cannot connect to the host database using “localhost”.

    Just wanted to state that one can just comment out the “bind-address” option in the mysql my.cnf file in order to have your mysql databsase accept connections from any ip/interface, however this would leave you “open” to the world (still have mysql user authentication though, so set passwords for your mysql users and make sure there are none with no password). Also rightly pointed out that will not work with “localhost” users, but a user is only @localhost if specified, the default is to not be limited to localhost, so the following would work:
    E.g. GRANT ALL ON my-db.* TO my-docker-user IDENTIFIED BY ‘password-here’

Leave a Reply

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s