2018-02-03

Building a small Raspberry Pi cluster and configure Ansible to administer it



Lately, everybody has been talking about microservices, Docker, Kubernetes, Kafka, Pulsar, ...
All those subjects are highly appealing but to really be able to learn them, you have to eventually test them in some real conditions. By "real", I mean, you can for instance learn K8s with minikube, but to see how it reacts when a node is gone, is something you truly have to experiment to correctly apprehend it. VMs are cool but RPis are fun !

For that article, I was inspired by Alex Ellis' blogpost.

Gathering the hardware


As you can see in the first picture, my cluster is composed of 4 units. I bought two Raspberry Pi 3 and recycled two Raspberry Pi 2.
4 is the perfect number to me : if you take a RPi as the master, it leaves 3 units which offers multiple use cases to test.
Two is too limited. More is better but also more expensive.

As I already have too many cables running around, I also bought two WiFi dongles for my RPi2.



To power the whole stuff, I found a cool alim from RavPower



And of course, a pack of USB cables


Once your cluster is ready from a hardware point of view, it's time to proceed to the software part.

Prepare Raspbian



For that part, it's pretty much the same than Alex's.

First, just get the Raspbian Stretch Lite image :
https://www.raspberrypi.org/downloads/raspbian/

Then flash it with Etcher.io

Don't put it in your RPi yet ! First thing to do, before booting, is to create an empty "ssh" file in the boot partition. This will allow you to login remotely.
sudo touch /boot/ssh
Then put the card inside the RPi and boot it.

Configure Raspbian



Keyboard layout (optional) / hostname / WIFI



As I'm French, my keyboard layout is AZERTY. It's really easy to switch from QWERTY (default) to the desired layout.
In fact, the three next steps are all done in the Raspbian menu.
sudo raspi-config

4th item "Localisation Options" is the part where you will be able to select the keyboard layout you want.

Network 1/2


As you can guess from the screenshot above, the menu "Network Options" (second item) will allow you to configure the hostname, the WiFi network and change the user password.
Configuring the WiFi access will update the file /etc/wpa_supplicant/wpa_supplicant.conf with your configuration.

Once you're done, you'll be asked if you want to reboot, click "Yes".

Network 2/2


In order to make the administration of the cluster easier , we're going to set a fix IP to each node.
To do so, just update the file /etc/dhcpcd.conf following the example below, but pay attention to reflect your network configuration.
sudo vi /etc/dhcpcd.conf

interface wlan0
static ip_address=192.168.0.23X
static routers=192.168.0.1
static domain_name_servers=192.168.0.1
When complete, reboot once again (this is the last time).

SSH key-based authentication



To be able to let Ansible interact with your nodes, you have to set a SSH key-based authentication for each one.
ssh-copy-id pi@192.168.0.23X
Try to connect to your node(s), and you shouldn't be prompted any password.
ssh pi@192.168.0.23X
Okay, we're ready to let Ansible come join the party.
(I'm expecting you to have it already installed. If not, simply follow the official documentation.).

If you're using a Linux OS, your inventory file should be /etc/ansible/hosts and you may then skip the next part.
Since I'm working on a Mac, I configured it manually.

First, edit or create a file ~/.ansible.cfg
# config file for ansible -- https://ansible.com/
# ===============================================

# nearly all parameters can be overridden in ansible-playbook
# or with command line flags. ansible will read ANSIBLE_CONFIG,
# ansible.cfg in the current working directory, .ansible.cfg in
# the home directory or /etc/ansible/ansible.cfg, whichever it
# finds first

[defaults]

inventory=/your/path/to/ansible/hosts
Then, once you've defined where to find it, edit it, paste the following configuration and update the IP values.
[pi-cluster]
192.168.0.23[1:4]

[masters]
192.168.0.231

[slaves]
192.168.0.232
192.168.0.233
192.168.0.234
Create a playbook (a simple YAML file) test-cluster.yml with the following content.
---
- name: Test my raspberry cluster
  hosts: pi-cluster
  remote_user: pi

  tasks:
  - name: Check Rasp model
    command: cat /proc/device-tree/model
    register: piversion
  - name: Debug each entry of my hosts
    debug:
      msg: "System {{ inventory_hostname }} is a {{ piversion.stdout }}"
And then just execute it :
ansible-playbook test-cluster.yml 
You should have a result such as the one below.
PLAY [Test my raspberry cluster] ***************************************************

TASK [Gathering Facts] *************************************************************
ok: [192.168.0.233]
ok: [192.168.0.232]
ok: [192.168.0.234]
ok: [192.168.0.231]

TASK [Check Rasp model] ************************************************************
changed: [192.168.0.233]
changed: [192.168.0.232]
changed: [192.168.0.234]
changed: [192.168.0.231]

TASK [Debug each entry of my hosts] ************************************************
ok: [192.168.0.231] => {
    "msg": "System 192.168.0.231 is a Raspberry Pi 2 Model B Rev 1.1\u0000"
}
ok: [192.168.0.232] => {
    "msg": "System 192.168.0.232 is a Raspberry Pi 3 Model B Rev 1.2\u0000"
}
ok: [192.168.0.233] => {
    "msg": "System 192.168.0.233 is a Raspberry Pi 3 Model B Rev 1.2\u0000"
}
ok: [192.168.0.234] => {
    "msg": "System 192.168.0.234 is a Raspberry Pi 2 Model B Rev 1.1\u0000"
}

PLAY RECAP *************************************************************************
192.168.0.231              : ok=3    changed=1    unreachable=0    failed=0   
192.168.0.232              : ok=3    changed=1    unreachable=0    failed=0   
192.168.0.233              : ok=3    changed=1    unreachable=0    failed=0   
192.168.0.234              : ok=3    changed=1    unreachable=0    failed=0   
And you're done : your RPi cluster is all set up, and Ansible is ready to perform various actions on it.

No comments: