How to communicate between Docker containers via "hostname" How to communicate between Docker containers via "hostname" docker docker

How to communicate between Docker containers via "hostname"


The new networking feature allows you to connect to containers bytheir name, so if you create a new network, any container connected tothat network can reach other containers by their name. Example:

1) Create new network

$ docker network create <network-name>       

2) Connect containers to network

$ docker run --net=<network-name> ...

or

$ docker network connect <network-name> <container-name>

3) Ping container by name

docker exec -ti <container-name-A> ping <container-name-B> 64 bytes from c1 (172.18.0.4): icmp_seq=1 ttl=64 time=0.137 ms64 bytes from c1 (172.18.0.4): icmp_seq=2 ttl=64 time=0.073 ms64 bytes from c1 (172.18.0.4): icmp_seq=3 ttl=64 time=0.074 ms64 bytes from c1 (172.18.0.4): icmp_seq=4 ttl=64 time=0.074 ms

See this section of the documentation;

Note: Unlike legacy links the new networking will not create environment variables, nor share environment variables with other containers.

This feature currently doesn't support aliases


Edit: After Docker 1.9, the docker network command (see below https://stackoverflow.com/a/35184695/977939) is the recommended way to achieve this.


My solution is to set up a dnsmasq on the host to have DNS record automatically updated: "A" records have the names of containers and point to the IP addresses of the containers automatically (every 10 sec). The automatic updating script is pasted here:

#!/bin/bash# 10 seconds interval time by defaultINTERVAL=${INTERVAL:-10}# dnsmasq config directoryDNSMASQ_CONFIG=${DNSMASQ_CONFIG:-.}# commands used in this scriptDOCKER=${DOCKER:-docker}SLEEP=${SLEEP:-sleep}TAIL=${TAIL:-tail}declare -A service_mapwhile truedo    changed=false    while read line    do        name=${line##* }        ip=$(${DOCKER} inspect --format '{{.NetworkSettings.IPAddress}}' $name)        if [ -z ${service_map[$name]} ] || [ ${service_map[$name]} != $ip ] # IP addr changed        then            service_map[$name]=$ip            # write to file            echo $name has a new IP Address $ip >&2            echo "host-record=$name,$ip"  > "${DNSMASQ_CONFIG}/docker-$name"            changed=true        fi    done < <(${DOCKER} ps | ${TAIL} -n +2)    # a change of IP address occured, restart dnsmasq    if [ $changed = true ]    then        systemctl restart dnsmasq    fi    ${SLEEP} $INTERVALdone

Make sure your dnsmasq service is available on docker0. Then, start your container with --dns HOST_ADDRESS to use this mini dns service.

Reference: http://docs.blowb.org/setup-host/dnsmasq.html


That should be what --link is for, at least for the hostname part.
With docker 1.10, and PR 19242, that would be:

docker network create --net-alias=[]: Add network-scoped alias for the container

(see last section below)

That is what Updating the /etc/hosts file details

In addition to the environment variables, Docker adds a host entry for the source container to the /etc/hosts file.

For instance, launch an LDAP server:

docker run -t  --name openldap -d -p 389:389 larrycai/openldap

And define an image to test that LDAP server:

FROM ubuntuRUN apt-get -y install ldap-utilsRUN touch /root/.bash_aliasesRUN echo "alias lds='ldapsearch -H ldap://internalopenldap -LL -bou=Users,dc=openstack,dc=org -D cn=admin,dc=openstack,dc=org -wpassword'" > /root/.bash_aliasesENTRYPOINT bash

You can expose the 'openldap' container as 'internalopenldap' within the test image with --link:

 docker run -it --rm --name ldp --link openldap:internalopenldap ldaptest

Then, if you type 'lds', that alias will work:

ldapsearch -H ldap://internalopenldap ...

That would return people. Meaning internalopenldap is correctly reached from the ldaptest image.


Of course, docker 1.7 will add libnetwork, which provides a native Go implementation for connecting containers. See the blog post.
It introduced a more complete architecture, with the Container Network Model (CNM)

https://blog.docker.com/media/2015/04/cnm-model.jpg

That will Update the Docker CLI with new “network” commands, and document how the “-net” flag is used to assign containers to networks.


docker 1.10 has a new section Network-scoped alias, now officially documented in network connect:

While links provide private name resolution that is localized within a container, the network-scoped alias provides a way for a container to be discovered by an alternate name by any other container within the scope of a particular network.
Unlike the link alias, which is defined by the consumer of a service, the network-scoped alias is defined by the container that is offering the service to the network.

Continuing with the above example, create another container in isolated_nw with a network alias.

$ docker run --net=isolated_nw -itd --name=container6 -alias app busybox8ebe6767c1e0361f27433090060b33200aac054a68476c3be87ef4005eb1df17--alias=[]         

Add network-scoped alias for the container

You can use --link option to link another container with a preferred alias

You can pause, restart, and stop containers that are connected to a network. Paused containers remain connected and can be revealed by a network inspect. When the container is stopped, it does not appear on the network until you restart it.

If specified, the container's IP address(es) is reapplied when a stopped container is restarted. If the IP address is no longer available, the container fails to start.

One way to guarantee that the IP address is available is to specify an --ip-range when creating the network, and choose the static IP address(es) from outside that range. This ensures that the IP address is not given to another container while this container is not on the network.

$ docker network create --subnet 172.20.0.0/16 --ip-range 172.20.240.0/20 multi-host-network$ docker network connect --ip 172.20.128.2 multi-host-network container2$ docker network connect --link container1:c1 multi-host-network container2