176 lines
5.6 KiB
Org Mode
176 lines
5.6 KiB
Org Mode
#+NAME: Raspberry pi k3s cluster guide
|
|
#+AUTHOR: James Blair
|
|
#+EMAIL: mail@jamesblair.net
|
|
#+DATE: 24th December 2019
|
|
|
|
|
|
This file serves as a complete step by step guide for creating a bare
|
|
metal raspberry pi kubernetes cluster using [[https://k3s.io/][k3s]] from [[https://rancher.com/][Rancher]].
|
|
|
|
My goal for this build is to replace a server I currently run at home
|
|
that hosts several workloads via Docker with a scalable k8s cluster.
|
|
|
|
Additionally in future I would like the cluster to be portable and
|
|
operate via 3G-5G Cellular network and an array of batteries.
|
|
|
|
I chose k3s as it incredibly lightweight but still CNCF certified and
|
|
production grade software that is optimised for resource constraints of
|
|
raspberry pis.
|
|
|
|
|
|
* Pre-requisites
|
|
|
|
** Cluster machines
|
|
|
|
For this guide I am using three [[https://www.pishop.us/product/raspberry-pi-4-model-b-4gb/][Raspberry Pi 4 4GB]] machines.
|
|
|
|
The cluster will have one leader node and two worker nodes.
|
|
For resiliency puposes in future I will update the cluster to run
|
|
with two leader nodes.
|
|
|
|
*** TODO Migration to high availability control plane
|
|
|
|
For resiliency purposes in future I will update the cluster and this
|
|
documentation to support a control plane of more than one machine.
|
|
|
|
|
|
** Boot media
|
|
|
|
This guide requires each Raspberry Pi to have a removable SD card or
|
|
other removable boot media. I am use three 32GB SD Cards though any
|
|
USB or SD card at least 8GB in size should work fine.
|
|
|
|
*** TODO Migration to network booting
|
|
|
|
In future it would be preferable for the raspberry pi's to be able
|
|
to network boot and setup automatically without an SD card.
|
|
|
|
This is a nice to have that I will pursue at a later date once I
|
|
have a deployed cluster that allows me to migrate off the current
|
|
server setup I have deployed.
|
|
|
|
|
|
|
|
|
|
* Step 1 - Prepare boot media for master
|
|
|
|
** Download the latest release
|
|
|
|
Our first step is to create the bootable SD Card with a minimal install
|
|
of [[https://www.raspbian.org/][Raspbian]], which is a free operating system based on [[https://www.debian.org/][Debian]] and is
|
|
optimised for Raspberry Pi hardware.
|
|
|
|
Rather than doing an installation and configuration of an operating system
|
|
image from scratch I found [[https://github.com/FooDeas/raspberrypi-ua-netinst][this project]] on Github which automates the
|
|
install and configuration process nicely.
|
|
|
|
#+NAME: Download the latest release zip
|
|
#+begin_src shell :results output verbatim replace :wrap example
|
|
echo Downloading latest release zip from github
|
|
curl -s https://api.github.com/repos/foodeas/raspberrypi-ua-netinst/releases/latest \
|
|
| grep "browser_download_url.*zip" \
|
|
| cut -d : -f 2,3 \
|
|
| tr -d \" \
|
|
| wget -i -
|
|
|
|
echo Checking file is now present
|
|
ls -l | grep *.zip
|
|
|
|
echo Extracting the zip file
|
|
unzip -q -d installer *.zip
|
|
ls -l | grep installer
|
|
#+end_src
|
|
|
|
#+RESULTS: Download the latest release zip
|
|
#+begin_example
|
|
Downloading latest release zip from github
|
|
Checking file is now present
|
|
-rw-rw-rw- 1 james james 60299545 Aug 12 08:35 raspberrypi-ua-netinst-v2.4.0.zip
|
|
Extracting the zip file
|
|
#+end_example
|
|
|
|
|
|
** Apply custom configuration
|
|
|
|
Our next step after downloading the
|
|
|
|
|
|
* Step 2 - Write the image file to removable media
|
|
|
|
Our next step is to write the downloaded image file to our removable
|
|
media. This step needs to be repeated for each raspberry pi in the
|
|
cluster.
|
|
|
|
*Note:* As my development environment is based on [[https://docs.microsoft.com/en-us/windows/wsl/about][wsl]] I need to use
|
|
a third party tool to write the image. If you are on a standard linux
|
|
distribution you can use the ~dd~ utility to write the image.
|
|
|
|
The image writing utility I use is [[https://www.balena.io/etcher/][balena etcher]]. After downloading
|
|
the latest version:
|
|
- Insert your removable media.
|
|
- Select the image file you downloaded earlier.
|
|
- Select your removable media and start writing the image.
|
|
|
|
|
|
* Step 3 - Enable ssh at startup
|
|
|
|
As our cluster will be headless, i.e. have no screen keyboard or mouse
|
|
plugged in we need to ensure ssh is configured from boot so that we can
|
|
remotely connect.
|
|
|
|
To do this we just need to add an empty file named ~ssh~ to our newly
|
|
created sd card
|
|
|
|
#+NAME: Mount newly formatted sd card
|
|
#+BEGIN_SRC shell
|
|
sudo mkdir /media/sdcard
|
|
sudo mount /dev/[SDCARD] /media/sdcard -o umask=000
|
|
#+END_SRC
|
|
|
|
|
|
#+NAME: Create the blank ssh file in the boot directory
|
|
#+BEGIN_SRC shell
|
|
sudo touch /media/sdcard/ssh
|
|
#+END_SRC
|
|
|
|
|
|
* Step 4 - Enable wifi at startup
|
|
|
|
For this guide we are running our cluser wirelessly. To ensure we can
|
|
access our pi's once they boot we need to ensure they boot with a wifi
|
|
configuration that will connect to our desired network.
|
|
|
|
To achieve this we need to set a configuration for the [[https://en.wikipedia.org/wiki/Wpa_supplicant][wpa_supplicant]]
|
|
application that our raspberry pi's use for managing wireless.
|
|
|
|
For security reasons I don't store wireless access point details here.
|
|
Instead they are retrieved at runtime of the code block using the
|
|
[[https://bitwarden.com/][bitwarden]] command line utility.
|
|
|
|
#+NAME: Write the wireless configuration file
|
|
#+BEGIN_SRC shell
|
|
export WIRELESS_SSID=`bw get username wifi`
|
|
export WIRELESS_PASS=`bw get password wifi`
|
|
cat > /media/sdcard/wpa_supplicant.conf << EOF
|
|
country=nz
|
|
update_config=1
|
|
ctrl_interface=/var/run/wpa_supplicant
|
|
|
|
network={
|
|
scan_ssid=1
|
|
ssid=$WIRELESS_SSID
|
|
psk=$WIRELESS_PASS
|
|
}
|
|
EOF
|
|
#+END_SRC
|
|
|
|
After writing the file we will use ~cat~ to verify the details.
|
|
If all details are correct you can unmount and remove the media.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|