Monday, 16 February 2015

How to connect your docker container to a service on the parent host

Recently I needed a docker container to access a service running on the parent host.  A lot of the examples on the internet were very close to what I needed, but not quite.

First off, docker's documentation provided an example that (as far as I can see) doesn't actually work.  The following (I think) is meant to inject the src ip address of the parent host's default interface:

$ alias hostip="ip route show | grep -Eo 'via \S+' | awk '{ print \$2 }'"
$ docker run  --add-host=docker:$(hostip) --rm -it debian

What it actually does is inject the ip of the default gateway on the parent host which doesn't help us.

Michael Hamrah's blog details the "gateway approach" of getting the parent's host ip from within the docker container.  This works great, although I wanted to inject the ip on container run and not have that logic within my docker image.

Inject the src ip of the docker interface

I think the best way is to get the source ip address of the docker0 interface which as described here is a "virtual Ethernet bridge that... lets containers communicate both with the host machine and with each other."  This interface has been created by docker for this purpose so it seems a good choice.  This does however assume that you are using the default docker0 interface and have not configured docker to use your own bridge.

To get the src IP of the docker0 interface, run the following in bash:

$ ip route show | grep docker0 | awk '{print $9}'

So, we run our docker image as follows:

$ docker run -d --add-host=parent-host:`ip route show | grep docker0 | awk '{print \$9}'` myusername/mydockerimage

Now, in your docker container, an entry in the /etc/hosts file will appear as follows:    parent-host

Tell docker not to containerise your networking

An alternative approach is to use --net="host", this works fine.  You can then access your service running on the parent host using localhost.  However this option does not allow you to also --link containers as you get the following error:

Conflicting options: --net=host can't be used with links. This would result in undefined behavior.

Further Reading

Networking is not my strong point.  I have learnt a lot about networking in Linux recently from Martin A. Brown's awesome Guide to IP Layer Network Administration with Linux.

I also came across a project called Pipework from Jérôme Petazzoni

(creator of docker in docker) that allows even more network customisation than docker allows out of the box.

1 comment:

  1. Thanks for this article. While I can see that containers can talk to docker0 ip on the docker host in bridge mode, I want to know whether the containers can also talk to the public (LAN) ip of the docker host (for example eth0 ip of the host) ? Appreciate reply!