Building a Raspberry Pi Cluster
Building a Raspberry Pi Cluster
I came across a presentation by Ray Tsang et al. that showcased a Raspberry Pi cluster with Docker and Kubernetes support 1. It is very useful to have a personal Raspberry Pi cluster to explore concepts of distributed systems and create proof of concept prototypes. This post will be updated with my experiences on how to create and maintain a Raspberry Pi cluster, so I will add content over time.
My cluster is based on Raspberry Pi 3 Model B. I tried to follow the list of parts presented in 1. Below I list the parts and links to each part in amazon (USA).
|Raspberry Pi 3 Model B Motherboard||link|
|Anker 60W 6-Port USB Wall Charger||link|
|Samsung 32GB 95MB/s (U1) MicroSD EVO Select Memory Card||link|
|Cat 6 Ethernet Cable 5 ft (5 PACK) Flat Internet Network Cable||link|
|NETGEAR N300 Wi-Fi Router with High Power 5dBi External Antennas (WNR2020v2)||link|
|Kingston Digital USB 3.0 Portable Card Reader for SD, microSD.||link|
I 3D printed the cluster rack using the files Raspberry Cluster Frame.
2. Operating System
I selected Hypriot OS since it already has support for docker. Also, with HypriotOS 1.7 and up, it is possible to use cloud-init to automatically change some settings on first boot. The version of
cloud-init that it seems to support is v0.7.9.
Since my cluster is based on Raspberry PI 3 model B which includes a Quad Core 1.2GHz Broadcom BCM2837 64bit CPU 2, then I use the releases of Hypriot OS provided by the github repo
DieterReuter/image-builder-rpi64 (64 bit distribution) instead of the ones provided by the repo
hypriot/image-builder-rpi (32-bit distribution) 3.
2.1. Flashing the OS
First, I decided to use the command line script developed by hypriot and hosted on github
hypriot/flash 4. The advantage of this over a more simple method such as
sudo dd if=image.img of=/dev/rdisk2 bs=1m. After installing the dependencies as described in the
hypriot/flash repo, I installed the command line utility in
$ # get the release $ curl -O https://raw.githubusercontent.com/hypriot/flash/master/flash $ # add executable permissions $ chmod +x flash $ # move to ~/bin $ mv flash $HOME/bin/ $ # export $HOME/bin to the path $ export PATH=$HOME/bin:$PATH
Second, I got the OS image from
$ wget https://github.com/DieterReuter/image-builder-rpi64/releases/download/v20180429-184538/hypriotos-rpi64-v20180429-184538.img.zip $ wget https://github.com/DieterReuter/image-builder-rpi64/releases/download/v20180429-184538/hypriotos-rpi64-v20180429-184538.img.zip.sha256 $ # Verify the image with sha-256 $ shasum -a 256 hypriotos-rpi64-v20180429-184538.img.zip
Flashing the sd-card:
$ # Setting nodeX and with the user-data.yml $ flash --hostname nodeX --userdata ./user-data.yml hypriotos-rpi64-v20180429-184538.img
You can find an example of the user-data.yml
2.1. Network configuration
I decided to configure the network interface using static IPs. The idea is to modify the file for
eth0 which is located at
sudo vim /etc/network/interfaces.d/eth0. As an example this is the setup for node1.
allow-hotplug eth0 iface eth0 inet static address 192.168.2.11 network 192.168.2.0 netmask 255.255.255.0 broadcast 192.168.2.255 gateway 192.168.2.1
I have a small Netgear WNR2020 wireless router dedicated to the Pi cluster, which is connected to another router that provides internet to it. I found useful to modify the DNS routes by adding the google DNS servers. Thus, I modified the file
/etc/resolv.conf to look like (you need
sudo to write to it):
$ cat /etc/resolv.conf nameserver 18.104.22.168 nameserver 22.214.171.124 nameserver 192.168.2.1
2.2. Setting up passwordless
I followed the guide by Mathias Kettner 6 to setup ssh login without password. Basically, this is a two part process. First, create the key in your local machine.
$ # generating a key that has not the default filename $ ssh-keygen -t rsa Enter file in which to save the key (<user_path>/.ssh/id_rsa): <user_path>/.ssh/pic_id_rsa Enter passphrase (empty for no passphrase): Enter same passphrase again: Your identification has been saved in <user_path>/.ssh/pic_id_rsa. Your public key has been saved in <user_path>/.ssh/pic_id_rsa.pub. The key fingerprint is: ...
Second, setup the public key on the remote host.
$ # Create .ssh folder in remote machine $ ssh ruser@remote 'mkdir -p ~/.ssh' ruser@remote's password: $ # Send key.pub to remote machine $ cat ~/.ssh/pic_id_rsa.pub | ssh ruser@remote 'cat >> ~/.ssh/authorized_keys' ruser@remote's password: $ # Changing permissions in the remote machine of both .ssh and .ssh/authorized_keys $ ssh ruser@remote 'chmod 700 ~/.ssh' $ ssh ruser@remote 'chmod 640 ~/.ssh/authorized_keys'
Now, you can ssh to
remote without password. I’m using a Mac laptop so I had to add the key to the ssh agent by
$ ssh-add $HOME/.ssh/pic_id_rsa.
There are several docker images for arm64v8 in the docker registry.