Accessing the Docker Host Server Within a Container
Jun 29 2014Docker links are a great way to link two containers together but sometimes you want to know more about the host and network from within a container. You have a couple of options:
- You can access the Docker host by the container’s gateway.
- You can access the Docker host by its ip address from within a container.
The Gateway Approach
This GitHub Issue outlines the solution. Essentially you’re using netstat to parse the gateway the docker container uses to access the outside world. This is the docker0 bridge on the host.
As an example, we’ll run a simple docker container which returns the hostname of the container on port 8080:
docker run -d -p 8080:8080 mhamrah/mesos-sample
Next we’ll run /bin/bash in another container to do some discovery:
docker run -i -t ubuntu /bin/bash #once in, install curl: apt-get update apt-get install -y curl
We can use the following command to pull out the gateway from netstat:
netstat -nr | grep '^0\.0\.0\.0' | awk '{print $2}' #returns 172.17.42.1 for me.
We can then curl our other docker container, and we should get that docker container’s hostname:
curl 172.17.42.1:8080 # returns 00b019ce188c
Nothing exciting, but you get the picture: it doesn’t matter that the service is inside another container, we’re accessing it via the host, and we didn’t need to use links. We just needed to know the port the other service was listening on. If you had a service running on some other port–say Postgres on 5432–not running in a Docker container–you can access it via 172.17.42.1:5432
.
If you have docker installed in your container you can also query the docker host:
# In a container with docker installed list other containers running on the host for other containers: docker -H tcp://172.17.42.1:2375 ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 09d035054988 ubuntu:14.04 /bin/bash About a minute ago Up About a minute 0.0.0.0:49153->8080/tcp angry_bardeen 00b019ce188c mhamrah/mesos-sample:latest /opt/delivery/bin/de 8 minutes ago Up 8 minutes 0.0.0.0:8080->8080/tcp suspicious_colden
You can use this for some hakky service-discovery.
The IP Approach
The gateway approach is great because you can figure out a way to access a host from entirely within a container. You also have the same access via the host’s ip address. I’m using boot2docker, and the boot2docker ip address is 192.168.59.103
and I can accomplish the same tasks as the gateway approach:
# Docker processes, via ip: docker -H tcp://192.168.59.103:2375 ps # Other docker containers, via ip: curl 192.168.59.103:8080
Although there’s no way to introspect the host’s ip address (AFAIK) you can pass this in via an environment variable:
docker@boot2docker:~$ docker run -i -t -e DOCKER_HOST=192.168.59.103 ubuntu /bin/bash root@07561b0607f4:/# env HOSTNAME=07561b0607f4 DOCKER_HOST=192.168.59.103 PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin PWD=/
If the container knows the ip address of its host, you can broadcast this out to other services via the container’s application. Useful for service discovery tools run from within a container where you want to tell others the host IP so others can find you.