A common problem I face on a daily basis is a lack of hardware / resource in order to test things out to the fullest. For example, in days gone by I’d have needed 3 servers for what i’m about to do – and in more recent times, 3 virtual machines. I dont have the time to continuously build these items, nor the resource if we were going physical. This is where my new found interest in Docker can help me out!

What I want to do on my Ubuntu ‘host’ server is create 3 Docker containers running Redis, and link them all together so that I can then develop and test the best way to monitor h-scaled Redis. Below I will show you how i’ve done it, and the benefits (even beauty) of it!

1. Download and configure our base image

For my base images, I use the excellent ‘phusion’ image which adds in a lot features that Docker omits (by design or not), including ordered startup of services and more. For more information on the phusion-base image, click here.

First, lets pull the phusion image as below, using Docker:

Shell

1

root@server:/home/sam# docker pull phusion/baseimage

On completion, you should be able to run ‘docker’ images and see the new image as below:

Shell

1

2

3

4

root@server:/home/sam# docker images

REPOSITORY TAG IMAGE IDCREATED VIRTUAL SIZE

phusion/baseimage0.9.15cf39b476aeec3months ago289.4MB

phusion/baseimage latest cf39b476aeec3months ago289.4MB

This image is great as you can tell it easily to startup certain services on start of the container, which is a bit of a pain in the arse otherwise (in my other blog i outlined how when using a standard base image you need to use bash to essentially start things!). One of the things I wanted to ADD to this image is the ability to login via SSH using a password instead of keys; given this is only going to be running on a locally contained box im not too worried around security!

To do this on phusion, we need to create an instance of phusion, login via SSH and modify the config, then restart SSH. We will then be able to login using the root user.

Warning:Permanently added'172.17.0.52'(ECDSA)tothe list of known hosts.

root@c36b4bba7dd4:~#

Congratulations, you are now ssh’d into the container! Next we need to modify SSH so we dont need to use the insecure key in the future. To do this, open up /etc/ssh/sshd_config and find and uncomment the following line:

Shell

1

PermitRootLogin yes

Then save the file and exit the text editor. Finally, we need to give our root user a password. To do this run ‘passwd’ as below:

Shell

1

2

3

4

5

root@c36b4bba7dd4:~# passwd

Enter newUNIX password:

Retype newUNIX password:

passwd:password updated successfully

root@c36b4bba7dd4:~#

And thats that for SSH on our base image. Next we will install redis on the container.

2. Install Redis

Now that we have our base image configured, we will need to download and install Redis. For my example I am using the latest version of redis, which can be downloaded from the page here. For my example i will be using Redis 3.0.0 RC1 from this link – https://github.com/antirez/redis/archive/3.0.0-rc1.tar.gz .

Note: You will need to install wget, gcc, make and a few other tools – these are properly base images 🙂

And thats that – Redis is now installed and running on your container, using the config file at /etc/redis/redis.conf!

3. Tell Docker to start services on boot

Now that our container is running redis and has SSH access, we need to tell it to start redis automatically on ‘start’ of the container.

To do this using the phusion base image, its actually remarkably simple. First, because we are starting docker using /sbin/my_init it will run anything we put in /etc/service/* on start which is excellent. SO, for our situation we need to create a new folder and ‘run’ file for docker here, as below:

Shell

1

2

3

4

root@e3919192d9e3:/etc/service# cd /etc/service

root@e3919192d9e3:/etc/service# mkdir redis

root@e3919192d9e3:/etc/service# cd redis

root@e3919192d9e3:/etc/service/redis# nano run

Within run, we need to paste the following:

Shell

1

2

3

#!/bin/sh

set-e

exec/usr/bin/redis-server/etc/redis/redis.conf

Finally, remember to set the run file to be executable:

Shell

1

root@e3919192d9e3:/etc/service/redis# chmod +x run

And thats all we need to do! Now, lets commit this image to our local library so we can start deploying it en-mass!

4. Commit your image so you can re-use it

Now that our ‘redis’ container is working a treat, we want to save it as a pseudo ‘template’ so we can deploy it over and over again on Docker – VERY quickly.

To do this is remarkably simple: we just ‘docker commit ..’ the image to our local library, as below:

Here we can see 3 redis containers, named node1, node2 and node3 – all with a dedicated ‘7001-7003’ port that maps straight to the Redis servers port.

To test this is working, we can use ‘redis-cli’ on another server and try and login to the ‘host server’ using the port 7001 and the host servers 192.168.x.x IP, as below:

Shell

1

2

3

4

5

6

7

8

9

root@server:/home/sam# redis-cli -h 192.168.0.2 -p 7001

redis192.168.0.16:7001>

root@server:/home/sam# redis-cli -h 192.168.0.2 -p 7002

redis192.168.0.16:7002>

root@server:/home/sam# redis-cli -h 192.168.0.2 -p 7003

redis192.168.0.16:7003>

root@server:/home/sam# redis-cli -h 192.168.0.2 -p 7005

Could notconnect toRedis at192.168.0.2:7005:Connection refused

notconnected>

As you can see, I can connect through to the 3 instances using their port + the host servers IP (all docker IPs’ are on 172.17.0.0/24 range). When i try an incorrect port it fails (just to prove that ALL ports dont end up in a redis server!!).

6. Configure Redis slaves

Now we have 3 individual redis servers, we want to link them together so that we can test scalability/monitoring of clusters or whatever our reason is for setting this all up! 🙂

We will need to configure node2 and node3 to be slaves of node1 which will be our master; we can do this easily by modifying /etc/redis/redis.conf.

To do this we will take advantage of our SSH configuration earlier – simply find out the IP address of the containers for node2 and node3, SSH into them, modify the config and then restart the container, as below:

Shell

1

2

3

4

5

6

7

8

root@server:/home/sam# docker inspect node1 | grep IPA

"IPAddress":"172.17.0.46",

root@server:/home/sam# docker inspect node2 | grep IPA

"IPAddress":"172.17.0.47",

root@server:/home/sam# ssh root@172.17.0.47

root@172.17.0.47'spassword:

Last login:Tue Jan1311:47:312015from172.17.42.1

root@6c8a87a0a76a:~# nano /etc/redis/redis.conf

In this config file we need to find the line ‘slaveof’ and uncomment and modify it to the IP address of node1 – similar to below:

Shell

1

2

3

4

root@6c8a87a0a76a:~# cat /etc/redis/redis.conf | grep slaveof

# Master-Slave replication. Use slaveof to make a Redis instance a copy of

slaveof172.17.0.466379

root@6c8a87a0a76a:~#

Finally, restart the container using ‘docker restart node2’ (for example), and it should now be a slave of the master Redis server on node1. To verify this, use redis-cli to login to node1 and node2 on seperate terminals and use ‘set hello world’ on node1, and ‘get hello’ on node2. If it works it should look like the following:

Shell

1

2

3

4

5

6

7

8

9

root@server:/home/sam# redis-cli -h 192.168.0.16 -p 7001

redis192.168.0.12:7001>set hello world

OK

redis192.168.0.12:7001>exit

root@server:/home/sam# redis-cli -h 192.168.0.16 -p 7002

redis192.168.0.12:7002>gethello

"world"

redis192.168.0.12:7002>exit

root@server:/home/sam#

And there you have it! 3 redis servers setup in a h-scale fashion (well, using slaves!) in docker – using your own phusion-based image. Marvellous!

Next steps

In my next blog, I will show you how to monitor your Redis cluster using Opsview so that you can get a nice pretty dashboard for your Redis stats, as below: