Skip to content

Instantly share code, notes, and snippets.

@awood
Last active August 29, 2015 13:56
Show Gist options
  • Star 3 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save awood/9142555 to your computer and use it in GitHub Desktop.
Save awood/9142555 to your computer and use it in GitHub Desktop.
Auto-resolving your Docker containers

For development, I run Docker containers that start up running sshd. Then I ssh to those machines and do my development work. It works great but finding the host name to ssh into was always a chore. It usually involved something like docker inspect my_container | grep IPAddress and then copying the address. Very tedious. I'd rather just type ssh root@my_container. So I did some searching and came up with a solution similar to http://blog.oddbit.com/2013/10/04/automatic-dns-entries-for-libvirt-domains/

What we will do is have incrond create a hosts file every time a container is started or stopped. Then we will set NetworkManager to use dnsmasq and resolve names through that hosts file.

The below instructions work on Fedora 20. For other distributions, you're on your own, but the principles should be the same.

  1. Set NetworkManager to use dnsmasq by adding the following under the [main] block of /etc/NetworkManager/NetworkManager.conf

    dns=dnsmasq
    
  2. Add the following to /etc/sysconfig/network-scripts/ifcfg-em1

    DOMAIN="default.docker"
    
  3. yum install incrond

  4. systemctl enable incrond.service && systemctl start incrond.service

  5. Drop the docker_hosts shell script into /usr/bin and chmod 755 it

  6. Create a file under /etc/incron.d and add the text below. Now every time a file gets created, deleted, or modified in /var/lib/NetworkManager, incrond will run the docker_hosts script and send it the name of the applicable file (that's what the $# means). The docker_hosts script will in turn look for running containers, inspect them, and output a hosts file that is then written to /var/lib/dnsmasq/docker.addnhosts.

    /var/lib/NetworkManager IN_CREATE,IN_DELETE,IN_MODIFY /usr/bin/docker_hosts $# /var/lib/dnsmasq/docker.addnhosts
    
  7. Now we just need to make dnsmasq aware of the hosts file. Under /etc/NetworkManager/dnsmasq.d create a file and put this in it:

    addn-hosts=/var/lib/dnsmasq/docker.addnhosts
    
  8. systemctl restart NetworkManager

  9. Now you should be able to just ssh root@my_container.


If you want to add ssh settings unique to docker containers (like ForwardAgent or ForwardX11), you can do this:

Host *.default.docker
    ForwardX11 yes
    ForwardAgent yes

Please note however, that if you do add ssh settings, you must use the fully qualified host name. E.g. ssh root@my_container.default.docker (because ssh doesn't do DNS lookups)

#! /bin/bash
INTERFACE_FILE="$1"
HOSTS_FILE="$2"
usage() {
cat <<HELP
usage: docker_hosts [options] [NetworkManager interface conf file]
OPTIONS:
-f force hosts file regeneration
HELP
}
while getopts ":f" opt; do
case $opt in
f ) FORCE="1" ;;
? ) usage; exit;;
esac
done
if [[ "$INTERFACE_FILE" =~ dhclient-veth.*\.conf || -n "$FORCE" ]]; then
HOST_ENTRIES=$(docker ps -q | xargs docker inspect -format '{{ .NetworkSettings.IPAddress }} {{ .Config.Hostname }}.default.docker {{ .Name }}.default.docker')
HOST_ENTRIES=$(printf "%s\n" "$HOST_ENTRIES" | tr -d '/')
if [[ -n "$HOSTS_FILE" ]]; then
printf "%s\n" "$HOST_ENTRIES" > "$HOSTS_FILE"
else
printf "%s\n" "$HOST_ENTRIES"
fi
pkill --signal SIGHUP --pidfile /var/run/NetworkManager/dnsmasq.pid
fi
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment