Inter-container communication in Docker without links

17 / Nov / 2015 by Ranvijay Jamwal 2 comments

As we know that Docker has released a newer version of their Docker Engine i.e. version 1.9. One major change is in the way we handle Docker networking and that is what we will be talking about in this blog. You can install the latest version of Docker from this link. It is supported in the newer version of Linux, for Ubuntu, Docker 1.9 is supported 14.04 onwards. Docker has somewhat integrated skydock into their Engine about which you can read here.

docker-logo

Use-case

I was really fed up using the traditional way of linking containers and communicating among them. The reason was that I was using the –link switch of the docker run command. Also, Docker Ambassador container did not seem to work very well for me. Then came the new release of Docker and this solved all my inter-container communication problems. So, the example use-case is basically the communication between Tomcat container (containing sample war) and the Nginx container (without links). Let’s see how we can do that. I will be using 2 Docker Images. One contains Tomcat and Grails and the other contains Nginx (installed Nginx on a base ubuntu image). Thereafter, I will run a sample Grails site without linking the containers manually. We know that Grails app runs on port 8080, so I will proxy that at 80 port through the Nginx container.

Demo

1. After installing the latest Docker version i.e. 1.9 and checking Docker version using:

docker --version

2. Now, let’s create a Docker network into which I will run the containers. First let’s, list the Docker networks by using the command:

 docker network ls

Screenshot from 2015-11-16 18:42:04
Above are the various networks available to Docker. You can now use one out of them or else create a new Docker network as follows:

Run the command:

docker network create test

Here “test” is the network name. You can use more switches like:


--aux-address=map[] auxiliary ipv4 or ipv6 addresses used by Network driver
-d, --driver=bridge Driver to manage the Network
--gateway=[] ipv4 or ipv6 Gateway for the master subnet
--help=false Print usage
--ip-range=[] allocate container ip from a sub-range
--ipam-driver=default IP Address Management Driver
-o, --opt=map[] set driver specific options
--subnet=[] subnet in CIDR format that represents a network segment

You can see these options by using command:

 docker network create --help

After you run the command it will return a hash code meaning the command was successfully run and the network was created:
Screenshot from 2015-11-16 18:54:23
If you now run “docker network ls” it will show you “test” as well.

Also, if you run command “ifconfig” you will see a new Bridge interface which is for the “test” network we created:
Edit Post ‹ TO THE NEW Blog — WordPress

3. Now, that the network has been created, let’s launch the containers in this network and see the magic. Run the following commands:

 docker run -itd -p 80:80 --name nginx --net test ubuntu
(inside this Nginx is installed)
Note: By using –net we are telling Docker inside which network the Docker container should be launched.

Now, I will run the tomcat-grails container that I have, mount the war directory to webapps folder where the .war file needs to be put in order for Tomcat to run the app (I have changed the directory according to a use-case I had earlier):

docker run -itd --name grails-tomcat -v /home/intelligrape/Downloads/war:/root/tomcat/webapps --net test tomcat-grails
Note: Remember to pass –name to the container else the automatic linking won’t happen as fancy names get changed on restart.

Now, that the containers are up, I will just enter this into the default virtual host file of the Nginx in the Nginx container which is self-explanatory and restart Nginx:

server{
 listen 80;
 
 server_name localhost;
 location / {
 proxy_pass http://tomcat-grails:8080;
 }
 }

 

4. Testing if the containers are in the same network. We can do that by using:

 docker network inspect test 

Edit Post ‹ TO THE NEW Blog — WordPress
It shows in JSON format the details of the network “test” and the various containers in the network.

Just to check what entries have automatically been made inside the containers in the /etc/hosts file. I am attaching to the Tomcat container and opening the hosts file:
Screenshot from 2015-11-17 15:50:34

A similar entry will be there in the Nginx container as well.
So, this is the magic. Now, you don’t need to worry about your containers being stopped, restarted etc. Docker will maintain the link and update the IPs automatically  (which changes if the container restarts).

Also, let’s see it the Grails site is up or not:
Screenshot from 2015-11-17 15:57:06

So, that is how simple it has become to communicate between containers. You just have to launch the containers in the same network and the rest will be taken care by Docker Engine. To do more testing you can just run a basic Ubuntu container with –net test switch and telnet or ping on the IP or name of the containers in the same network.

Two important points to note:

1. Docker containers in the same network can talk on any port irrespective of the post that is exposed. So, you don’t need to expose ports manually which is again a boon. Concerning thing here is restricting access to a container in the same network.
2. Another thing to remember here is these containers will be isolated from the containers running in a different network. I tried to telnet from a container running in default Docker network to the container running in “test” network and there was no response. To resolve this you can create a bridge between the two networks.

There will be a lot more to explore in Docker networking and I will be back with a blog on more details and use-cases.

FOUND THIS USEFUL? SHARE IT

comments (2)

  1. Just me

    Great article – am new to Docker, so I have no idea – can you comment on how the changes in 1.12 affect this approach? Do you believe this can (should) replace usage of Ambassador pattern?

    Reply

Leave a comment -