Raspberry Pi hobby cluster
In this tutorial we are gonna try to setup a cluster in our home server built with raspberries.
In another post I'll describe how to configure a Kubernetes cluster in our raspberries.
Kubernetes is a container orchestration tool, it can do all of this:
Automatic bin packing
Self-healing
Horizontal scaling
Service discovery and Load balancing
Automated rollouts and rollbacks
Secrets and configuration management
Storage orchestration
Long running jobs
Batch execution
Hardware
Requirements
unix system (linux or mac)
flash v2.2.0 installation
hypriot OS v1.9.0 download
SSH keys
We need a SSH key in order to connect to the cluster without having to type the password every time we access.
In case you don't have any, run this command and follow the steps.
Add the key to your ssh agent, assuming our keys generated are id_rsa
and id_rsa.pub
.
You can find a more in depth explanation in this tutorial
Creating cloud-init-config
The flash
command line utility, uses a cloud-init-conf in order to configure the
debian system that it's going to be installed. We are gonna use hypriot debian,
which is optimized for containers.
Let's generate the conf using a template I've created, remember to update the environment variables with your values.
Variable |
Description |
---|---|
|
Username to login into the os |
|
A public key to log in without typing the password. |
|
The name of your wifi |
|
Use
|
export USERNAME=willy export WIFI_SSID_NAME="Bla bla" export WIFI_PASSWORD="longandsecurepassword" export WIFI_COUNTRY=NL export TIMEZONE=$(curl -s https://ipapi.co/timezone) export SSH_PUBLIC_KEY=$(cat ~/.ssh/id_rsa.pub) curl -s https://gist.githubusercontent.com/Woile/51eca58047b6bd51c60eeae80d60ec14/raw/db05664b5e90a28472f139bc8757562c2ed13026/cloud-init-config-template.yaml | \ sed -e "s/\${USERNAME}/$USERNAME/" \ -e "s/\${WIFI_SSID_NAME}/$WIFI_SSID_NAME/" \ -e "s/\${WIFI_PASSWORD}/$WIFI_PASSWORD/" \ -e "s/\${WIFI_COUNTRY}/$WIFI_COUNTRY/" \ -e "s|\${TIMEZONE}|$TIMEZONE|" \ -e "s|\${SSH_PUBLIC_KEY}|$SSH_PUBLIC_KEY|" > cloud-init-config.yaml
Flashing SD cards
Insert the SD card and find it with df
.
Flash the cloud-init-conf.yaml
in all of your SD cards.
It's important to change the hostname per raspberry. Pay attention to param
--hostname
.
For my 4 raspberries I am going to use these hostnames:
flash -f --hostname willy-1 --device <device_found_using_df> -u cloud-init-config.yaml hypriotos-rpi-v1.9.0.img pv
Example:
flash -f --hostname willy-1 --device /dev/mmcblk0 -u cloud-init-config.yaml hypriotos-rpi-v1.9.0.img pv
Plug the SD card on each raspberry and connect them to the wall.
Setting up the nodes
To find the IPs of your raspberries run:
Connect to each one of them using ssh <username>@<hostname>
, because
we previosuly added the ssh key, we should not need to type a passsword.
Execute on each node the next steps.
Reset password
Update your user’s password with passwd
. Remember that by default is hypriot
.
Configure Firewall
For simplicity and in case you want to have a multi master cluster, we are gonna allow ports for master kubernetes and for kubernetes workers.
Run this as root typing sudo su
ufw --force reset # ok ufw allow ssh ufw allow 6443 # Kubernetes API (master) ufw allow 80 # HTTP ufw allow 443 # HTTPS ufw allow 8443 # kubectl proxy ufw allow 10250 # Kubelet API (master and worker) ufw allow 10251 # kube-scheduler (master) ufw allow 10252 # kube-controller-manager (master) ufw allow 2379:2380/tcp # etcd server client API (master) ufw allow 30000:32767/tcp # NodePort Services** (worker) ufw default deny incoming yes | ufw enable
Configuring master node
Choose one of the raspberries as the master, I use willy-1
as
master.
Set static IP
Edit /etc/network/interfaces.d/eth0
and set it to
allow-hotplug eth0 iface eth0 inet static address 10.0.0.1 netmask 255.255.255.0 broadcast 10.0.0.255 gateway 10.0.0.1
Reboot to claim the IP 10.0.0.1
in your internal cluster’s network
(the switch network)
Allocate addresses to the worker nodes using DHCP
The cloud-init template already includes isc-dhcp-server
Edit /etc/default/isc-dhcp-server
, comment out # INTERFACESv6=""
and set INTERFACESv4="eth0"
Or run this
sudo sed -e '/INTERFACESv6=/ s/^#*/#/' -e 's/INTERFACESv4=""/INTERFACESv4="eth0"/g' -i /etc/default/isc-dhcp-server
Backup and edit /etc/dhcp/dhcpd.conf
. Set it like this:
option domain-name "willy.home"; # Set a domain name, can be anything option domain-name-servers 8.8.8.8, 8.8.4.4; # Use Google DNS by default, you can substitute ISP-supplied values here subnet 10.0.0.0 netmask 255.255.255.0 { # We'll use 10.0.0.X for our subnet range 10.0.0.1 10.0.0.50; option subnet-mask 255.255.255.0; option broadcast-address 10.0.0.255; option routers 10.0.0.1; } default-lease-time 600; max-lease-time 7200; authoritative;
Restart service sudo systemctl restart dhcpcd.service
Now our master will start assigning addresses to the other nodes.
In case it’s not assigning IPs, try unplugging from the switch and
restarting all the other nodes but the master. You can check the IPs by
doing ip a
or hostname -I
, remember that this is the range
range 10.0.0.1 10.0.0.50
Our cluster is set up now.
Credits
This tutorial is based on Kubernetes: Up and Running, Hypriot | Setup Kubernetes on a Raspberry Pi Cluster easily the official way! and Production Hobby Cluster.