Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to communicate between Docker containers via "hostname"

I plan to split my monolthic server up into many small docker containers but haven't found a good solution for "inter-container communication" yet. This is my target scenario:

Target scenario

I know how to link containers together and how to expose ports, but none of these solutions are satisfying to me.

Is there any solution to communicate via hostnames (container names) between the containers like in a traditional server network?

like image 891
Patrick Gotthard Avatar asked May 30 '15 10:05

Patrick Gotthard


People also ask

What are the two ways you can network containers in docker?

Docker includes support for networking containers through the use of network drivers. By default, Docker provides two network drivers for you, the bridge and the overlay drivers. You can also write a network driver plugin so that you can create your own drivers but that is an advanced task.

How do I make my docker container accessible from network?

To make a port available to services outside of Docker, or to Docker containers which are not connected to the container's network, use the --publish or -p flag. This creates a firewall rule which maps a container port to a port on the Docker host to the outside world.


2 Answers

The new networking feature allows you to connect to containers by their name, so if you create a new network, any container connected to that 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 ms 64 bytes from c1 (172.18.0.4): icmp_seq=2 ttl=64 time=0.073 ms 64 bytes from c1 (172.18.0.4): icmp_seq=3 ttl=64 time=0.074 ms 64 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

like image 167
Hemerson Varela Avatar answered Sep 22 '22 13:09

Hemerson Varela


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 default INTERVAL=${INTERVAL:-10}  # dnsmasq config directory DNSMASQ_CONFIG=${DNSMASQ_CONFIG:-.}  # commands used in this script DOCKER=${DOCKER:-docker} SLEEP=${SLEEP:-sleep} TAIL=${TAIL:-tail}  declare -A service_map  while true do     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} $INTERVAL done 

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

like image 26
xuhdev Avatar answered Sep 26 '22 13:09

xuhdev