Connecting containers with links

(Optional)

graph
Figure 81 : graph

Objectives

Links were the "legacy" way of connecting containers (before the implementation of the CNM).

They are still useful in some scenarios.

  • Links are created between two containers
  • Links are created from the client to the server
  • Links associate an arbitrary name to an existing container
  • Links exist only in the context of the client

The plan

  • We will create the redis container first.
  • Then, we will create the www container, with a link to the previous container.
  • We don't need to use a custom network for this to work.

Create the redis container

Let's launch a container from the redis image.

$ docker run -d --name datastore redis
<yourContainerID>

Let's check the container is running:

$ docker ps -l
CONTAINER ID   IMAGE          COMMAND        ...   PORTS      NAMES
9efd72a4f320   redis:latest   redis-server   ...   6379/tcp   datastore
  • Our container is launched and running an instance of Redis.
  • We used the --name flag to reference our container easily later.
  • We could have used any name we wanted.

Create the www container

If we create the web container without any extra option, it will not be able to connect to redis.

$ docker run -dP jpetazzo/trainingwheels

Check the port number with docker ps, and connect to it.

We get the same red error page as before.

How our app connects to Redis

Remember, in the code, we connect to the name redis:

redis = redis.Redis("redis")
  • This means "try to connect to 'redis'".
  • Not 192.168.123.234.
  • Not redis.prod.mycompany.net.

Obviously it doesn't work.

Creating a linked container

Docker allows to specify links.

Links indicate an intent: "this container will connect to this other container."

Here is how to create our first link:

$ docker run -ti --link datastore:redis alpine sh

In this container, we can communicate with datastore using the redis DNS alias.

DNS

Docker has created a DNS entry for the container, resolving to its internal IP address.

$ docker run -it --link datastore:redis alpine ping redis
PING redis (172.17.0.29): 56 data bytes
64 bytes from 172.17.0.29: icmp_seq=0 ttl=64 time=0.164 ms
64 bytes from 172.17.0.29: icmp_seq=1 ttl=64 time=0.122 ms
64 bytes from 172.17.0.29: icmp_seq=2 ttl=64 time=0.086 ms
^C--- redis ping statistics ---
3 packets transmitted, 3 packets received, 0% packet loss
round-trip min/avg/max/stddev = 0.086/0.124/0.164/0.032 ms
  • The --link flag connects one container to another.
  • We specify the name of the container to link to, datastore, and an alias for the link, redis, in the format name:alias.

Starting our application

Now that we've poked around a bit let's start the application itself in a fresh container:

$ docker run -d -P --link datastore:redis jpetazzo/trainingwheels

Now let's check the port number associated to the container.

$ docker ps -l

Confirming that our application works properly

Finally, let's browse to our application and confirm it's working.

https://<yourHostIP>:<port>

In addition to the DNS information, Docker will automatically set environment variables in our container, giving extra details about the linked container.

$ docker run --link datastore:redis alpine env
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
HOSTNAME=0738e57b771e
REDIS_PORT=tcp://172.17.0.120:6379
REDIS_PORT_6379_TCP=tcp://172.17.0.120:6379
REDIS_PORT_6379_TCP_ADDR=172.17.0.120
REDIS_PORT_6379_TCP_PORT=6379
REDIS_PORT_6379_TCP_PROTO=tcp
REDIS_NAME=/dreamy_wilson/redis
REDIS_ENV_REDIS_VERSION=2.8.13
REDIS_ENV_REDIS_DOWNLOAD_URL=https://download.redis.io/releases/redis-2.8.13.tar.gz
REDIS_ENV_REDIS_DOWNLOAD_SHA1=a72925a35849eb2d38a1ea076a3db82072d4ee43
HOME=/
RUBY_MAJOR=2.1
RUBY_VERSION=2.1.2
  • Each variables is prefixed with the link alias: redis.
  • Includes connection information PLUS any environment variables set in the datastore container via ENV instructions.
  • With network aliases, you can start containers in any order.
  • With links, you have to start the server (in our example: Redis) first.
  • With network aliases, you cannot change the name of the server once it is running. If you want to add a name, you have to create a new container.
  • With links, you can give new names to an existing container.
  • Network aliases require the use of a custom network.
  • Links can be used on the default bridge network.
  • Network aliases work across multi-host networking.
  • Links (as of Engine 1.11) only work with local containers (but this might be changed in the future).
  • Network aliases don't populate environment variables.
  • Links give access to the environment of the target container.

Section summary

We've learned how to:

  • Create links between containers.
  • Use names and links to communicate across containers.