A few months ago, we wrote about using Serf with Docker to create a service registry so that your app could talk to your database indirectly. Then just a couple weeks ago, we wrote about using the Docker ambassadors model.

But in the Docker ambassadors post, we just setup a proxy ambassador, it didn't do anything but forward TCP traffic.

This week, we are going to use Docker ambassadors to do something more interesting: the ambassador will register the app container and the database container into the Serf network for us. This could just as easily be using ambassadors to register into etcd for us (in fact, I will show how at the end of this post). But for now, let's start with Serf.

Setup Serf With Docker

First, let's setup a serf agent on a Docker container.

$ SERF_ID=$(docker run -d --name serf_1 -p 7946 -p 7373 ctlc/serf /run.sh)

Well that was easy! Now let's connect to the Serf agent with a Serf client container that will print out any members added to the network automatically.

$ docker run -i -t --link serf_1:serf_1 ctlc/serf-members
67ffbe3dba95 172.17.0.3:7946 alive role=serf-members
f5af7d9dbc3c 172.17.0.2:7946 alive role=serf-agent

So now we can see our progress as we continue.

Setup a Random MySQL Container

Now we need to setup a MySQL database. I will pick a completely random MySQL database container from the Docker index:

$ docker run --name mysql -p 3306 -d brice/mysql
$ docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
385c51c9de5a brice/mysql:latest /bin/sh -c mysqld 18 minutes ago Up 18 minutes 0.0.0.0:49169->3306/tcp mysql
67ffbe3dba95 ctlc/serf-members:latest /run.sh 51 minutes ago Up 51 minutes 7373/tcp, 7946/tcp sleepy_brown
f5af7d9dbc3c ctlc/serf:latest /run.sh 51 minutes ago Up 51 minutes 0.0.0.0:49159->7373/tcp, 0.0.0.0:49160->7946/tcp ...

This is not a trusted image, so we actually have no idea what code we are running. However, brice/mysql is probably pretty unlikely to be running Serf since I picked it randomly from the index. So how do we get this database registered into Serf? Using the ambassador model of course.

$ docker run -d --link mysql:mysql --link serf_1:serf_1 --name mysql_ambassador -p 3306:3306 ctlc/amb-serf

Now look back at your other terminal window running the ctlc/serf-members container.

67ffbe3dba95 172.17.0.3:7946 alive role=serf-members
f5af7d9dbc3c 172.17.0.2:7946 alive role=serf-agent
31aa2ce79322 172.17.0.5:7946 alive role=3306

Now you can see that Serf now knows the internal IP address of the host running MySQL. We are almost done!

Setup a WordPress Container

Now all we need is a WordPress container that can consume the information from Serf. We can do this two ways:

  1. We can build Serf-logic into the container
  2. We can create another ambassador container to bridge to the MySQL ambassador and link to the WordPress container (which kinda defeats the purpose of using Serf in the first place, unless your new container uses Serf instead of environment variables to figure out where to bridge to)

In this case, we will pick option 1 and leave option 2 as an exercise for the reader.

$ docker run -d --link serf_1:serf_1 -p 80:80 -e "DB_USER=root" -e "DB_NAME=mysql" ctlc/wordpress-serf

Now look back at your other terminal window running the ctlc/serf-members container.

67ffbe3dba95 172.17.0.3:7946 alive role=serf-members
f5af7d9dbc3c 172.17.0.2:7946 alive role=serf-agent
31aa2ce79322 172.17.0.5:7946 alive role=3306
ffa1b001a1b7 172.17.0.6:7946 alive role=web

Success.

$ curl -s -L localhost | head
<meta name="viewport" content="width=device-width" /><meta http-equiv="Content-Type" content="text/html; charset=utf-8" />WordPress › Installation <link id="buttons-css" href="http://localhost/wp-includes/css/buttons.min.css?ver=3.9-beta3-27857" rel="stylesheet" media="all" type="text/css" /> <link id="open-sans-css" href="//fonts.googleapis.com/css?family=Open+Sans%3A300italic%2C400italic%2C600italic%2C300%2C400%2C600&subset=latin%2Clatin-ext&ver=3.9-beta3-27857" rel="stylesheet" media="all" type="text/css" /> <link id="install-css" href="http://localhost/wp-admin/css/install.min.css?ver=3.9-beta3-27857" rel="stylesheet" media="all" type="text/css" />

Ambassadors for Etcd and CoreOS

I promised I would show you how to register your database into Etcd instead of Serf at the beginning of this article. If you've made it this far, you deserve to see more. Ready for it? Instead of this:

$ docker run -d --link mysql:mysql --link serf_1:serf_1 --name mysql_ambassador -p 3306:3306 ctlc/amb-serf

Run this:

$ docker run -d --link mysql:mysql --link serf_1:serf_1 --name mysql_ambassador -p 3306:3306 ctlc/amb-etcd

The ctlc/amb-etcd container will register with etcd instead of serf automatically. Of course you will need to put this in systemd formatted file and deploy using fleetctl for this to actually work, but the idea is the same.

Conclusion

There is a lot you can do with the Docker ambassador model. This is just scratching the surface. In upcoming posts, we will show you how to do things like centralized transparent network logging and other fun stuff you can do with ambassadors.