Building a Raspberry Pi Cluster with Docker

May 2 · 7 min read

From configuring the cluster to the 3D rack printing.

The Raspberry Pi is a great piece of hardware and thanks to its price (just 35$ for the Model 3 B+ and 10$ for the Model Zero W) enables everyone and everything to the world of computing. However, the price is not the only advantage. Indeed, size and technical specifications matter. The Raspberry Pi is a perfect IoT and/or micro-server enabler.

In this article, we will be looking at micro-servers and the exercise will consist of building a Web Server cluster with 3 Raspberry Pi Zero W. For the Web Server deployment we’ll leverage the power of Docker. For those who don’t know about it, Docker is a platform that allows running software into “containers”. Containers are a method to package software and they do not contain just the code, but also libraries, services, and even a file system. The beautiful thing is that you can run those containers on multiple machines as well, which is exactly what we are looking for. This mode is called Docker Swarm. By definition, a Docker Swarm is a group of machines that are running Docker and are joined into a cluster.

Last, but not least, we need to put the 3 Raspberry Pi somewhere, hence, we’ll be printing some 3D stackable racks for them.

1. Bill of Materials

1.1 Raspberry Pi

1.2 3D Printing

  • A 3D Printer (seriously!?). I am currently using an Ender 3;
  • I have used this stack mount 3D model;
  • Your favorite polymer to print. I’ve used white PLA.

2. Flashing the Operating System

For this exercise, we are using Raspbian (a Debian-based OS) that is the recommended official OS for Raspberry Pi, but it is also supporting other operating systems such as Windows IoT Core, FreeBSD, Chromium OS, and others.

To flash the SD Card I’ve used Balena Etcher.

After flashing we have to configure the WiFi connection and the SSH access before booting our Raspberry Pi for the very first time.

2.1 Enabling SSH

Create an empty file named ssh inside the root of your SD card. It’ll enable the SSH interface.

2.2 Setting WiFi

Create an empty file named wpa_supplicant.conf inside the root of your SD card and put the following content:

ctrl_interface=DIR=/var/run/wpa_supplicant GROUP=netdev
country=YOUR_COUNTRY_ISO_CODE
update_config=1
network={
ssid=”Your SSID”
psk=”Your Password”
}

Of course, we have to repeat the operation for each Raspberry Pi we want to prepare for the cluster.

2.3 Time to boot!

OK, now that the initial configuration has been completed we can put the SD inside the Raspberry Pi and power it up.

2.4 Finding the Devices

In order to access our Raspberry Pi’s, we have to find them, on the network. The best way is to go on the gateway/access point and look for the new devices connected from a few minutes. Alternatively, we can leverage some IP scanner app and look for devices with “raspberrypi” as a hostname. Once found we can connect to them via SSH.

3. Configuring the Devices

3.1 Setting a Static IP

To make the cluster work correctly we need to set a static IP to each Raspberry Pi. The IP address can be changed by modifying the file dhcpcd.conf

sudo nano /etc/dhcpcd.conf

and adding this content

interface wlan0static ip_address=x.x.x.x/subnet expressed with CIDR notation
static routers=z.z.z.z
static domain_name_servers=y.y.y.y

3.2 Changing the Hostname

We have to modify two files in order to change the hostname.

sudo nano /etc/hostname

Inside this file, we have to replace the hostname “raspberrypi” with the one we prefer.

sudo nano /etc/hosts

Inside the hosts file, we have to change the hostname “raspberrypi” in the line with the IP 127.0.1.1.

We have to reboot the system to let the configurations apply.

sudo reboot

3.3 Upgrading Raspbian

Let’s update the operating system before installing Docker.

sudo apt-get update
sudo apt-get upgrade -y

4. Docker

4.1 Installing Docker

There is an issue in the version 18.09 with the Raspberry Pi Zero W, so if it has been solved in the latest version you can use it. Alternatively, you have to downgrade Docker to the version 18.06.

# Latest version.
curl -sSL https://get.docker.com | sh
# Version 18.06
sudo apt-get install docker-ce=18.06.1~ce~3-0~raspbian
# Granting permissions
sudo usermod pi -aG docker

Let’s reboot the system once again to complete the installation.

sudo reboot

4.2 Initializing Swarm

We have to connect via SSH to the device we want to make the manager of the Swarm cluster. The device that initiates the Swarm node will be the manager by default and the output of the init command will give you the instructions for how to make other devices join the node. Save it.

docker swarm init

4.3 Joining the other devices to the Swarm node

In order to make the other Raspberry Pi’s join the Swarm node, we have to connect to them via SSH and run the join command.

docker swarm join --token [the token you have received in the Swarm initialization] [Swarm node manager IP]:2377

5. Deploying the Web Server

Alright guys, our Raspberry Pi’s are baked and our Docker Swarm node as well. It’s definitely time to put something into this cluster and we’ll be deploying an nginx (a lightweight Web Server/Proxy/Load Balancer) container into it.

5.1 Preparing the application

For this example, I’ve used a simple Angular application, but of course, you can use whatever technology runs on nginx.

The repository of the example is here.

The most important thing is to prepare the Dockerfile in order to pack our Docker Image that’ll be deployed on our cluster.

5.2 Build and Publish the Docker Image

It’s time to build the Docker Image.

docker build -t [image-name]
# In our case the image-name will be "docker-cluster-rpi-example".

5.3 Docker Compose

The Docker Compose is the file that contains the directives to deploy the image with Docker. It is all we need to deploy our nginx Web Server, with our Angular application, into the Docker Swarm node.

We have to connect via SSH to our master Raspberry Pi, create a file named docker-compose.yml and add the following content.

#
# Building a Raspberry Pi Cluster with Docker.
#
version: "3.7"services:
nginx:
image: simonedicicco/docker-cluster-rpi-example
restart: always
deploy:
mode: replicated
replicas: 3
expose:
- 80
ports:
- 80:80
networks:
picluster0:
driver: overlay
ipam:
driver: default
config:
- subnet: 172.16.238.0/24

5.4 Time to deploy!

That’s all we have left to do.

docker stack deploy --compose-file docker-compose.yml pi-cluster

This command will deploy and replicate the image among the whole Docker Swarm node. To check if the image has been replicated successfully in the cluster we can use this command:

docker service ps [container-name]

6. Load Balancer

But wait… We need a Load Balancer to access the cluster otherwise, we don’t know where to go! The good news is that we can leverage nginx for this purpose too.

6.1 Configuring the Load Balancer

Where to prepare this nginx instance it’s really up to you. Personally, I’ve put it into another Raspberry Pi.

sudo apt-get install nginx

In order to configure nginx as a load balancer, we have to edit its config file.

sudo nano /etc/nginx/nginx.conf

And put the default load balancing configuration. The following is the easiest configuration for load balancing with nginx.

http {
upstream picluster {
server picluster1.domain.com; # or put the IP instead.
server picluster2.domain.com; # or put the IP instead.
server picluster3.domain.com; # or put the IP instead.
}

server {
listen 80;

location / {
proxy_pass http://picluster;
}
}
}

7. Printing the Stackable rack

Now that we have our Raspberry Pi’s ready it’s time to assemble them on the stackable rack, but first we have to 3D print the units. I personally use Ultimaker Cura to prepare the G-Code for my 3D printer.

8. Final Product

All set up and running!

Links

Welcome to a place where words matter. On Medium, smart voices and original ideas take center stage - with no ads in sight. Watch
Follow all the topics you care about, and we’ll deliver the best stories for you to your homepage and inbox. Explore
Get unlimited access to the best stories on Medium — and support writers while you’re at it. Just $5/month. Upgrade