RPi Kubernetes
RPI Kubernetes
A quick overview of how to build a Raspberry Pi Cluster using Linux.
Bill of materials
- Raspberry Pi (Minimum x 2) - recommend RPi v4
- MicroSDHC Card (Minimum capacity 8GB)
- USB Charging Cable (Same number as RPi devices)
- Machine to create an RPi Disk Image
Which disk image?
The 64bit Ubuntu image is currently my preferred choice as it just works! Raspberry Buster image comes in multiple flavors.
- If you dont need the Kubernetes dashboard, use the Lite version.
- If you need the Kubernetes dashboard, use the Desktop version.
Rpi | Image |
---|---|
32 bit | Download a Raspbian Buster (Desktop/Lite version) Image |
64 bit | Download a 64bit Ubuntu Raspberry Pi Image |
- Download either image file to your machine
Note: the location where the file has being downloaded
Create the Disk Image
Use a utility such as Etcher
or ChromeOS recovery
to write the memory card.
- Insert the memory card into your host machine and confirm it is recognised.
- Take note of how the memory card is labelled as we will use this information later
- Locate the downloaded file on your host.
- Extract the file to an image file
- Right click on the downloaded image to show the
- Open with Disk Image Writer option.
- In the image writer, select the memory card inserted to be used to write the image. Once the image has been written to the memory card there will be two volumes available:
Folders |
---|
boot |
rootfs |
- Select the BOOT from the file manager:
-
Click on the
boot
folder to mount the image. -
Then right click in the folder window and select the “open in terminal” option.
-
In the Terminal window for the boot folder add a SSH file to the root of the boot folder
1touch ssh
The above command creates a SSH file in the
boot
folder and ensures the SSH service is started on boot up
-
Close the open terminal window
-
Select the
rootfs
folder from the file manager:
-
Click on the
rootfs
folder to mount the image. -
Then right click on the folder window and select the “open in terminal” option
-
In the Terminal window for the rootfs folder. Enter the config directory
1cd etc
- Edit the hostname file (use whatever editor you like)
1sudo vi hostname
- Change the hostname from the default raspberrypi
e.g. k8s-master-01 k8s-worker-01
- Edit the hosts file (use whatever editor you like) e.g.
1sudo vi hosts
- Amend the host file to use the updated hostname used above e.g.
Before | After |
---|---|
raspberrypi | k8s-master-01 |
raspberrypi | k8s-worker-01 |
- You can now eject the rpi filesystem (i.e. boot & rootfs) mounts using the file manager
Configuring the RPi
- Connect the devices via ethernet cables and power them on They should now be accessible via DHCP - check router
Note: Optional - reserve an IP based on the mac address of the RPi
Name | Mac Address | Device IP |
---|---|---|
k8s-master-01 | xx:xx:xx:xx:xx:xx | 192.168.86.180 |
k8s-worker-01 | xx:xx:xx:xx:xx:xx | 192.168.86:181 |
- To connect to the devices, use an SSH connection from a device on the same network
1ssh pi@[device ip]
Note: The default password for RPI is "raspberry"
- Update the device ( do this for each device)
1sudo apt update && sudo apt upgrade
- Edit the
/boot/cmdline.txt
and append the following to the end of the line
1cgroup_enable=cpuset cgroup_memory=1 cgroup_enable=memory
- Amend the swap setting to off
1sudo dphys-swapfile swapoff
- Uninstall the swapfile command
1sudo dphys-swapfile uninstall -y && sudo apt purge -y dphys-swapfile
- Reboot the device
1sudo reboot
Installing Docker on the RPi
- Install Docker
1curl -sSL get.docker.com | sh
- Add the pi user to the Docker group
1sudo usermod -aG docker pi
Press ctrl-d
to disconnect from the RPi
- Update the docker daemon - edit
/etc/docker/daemon.json
, add the following:
1{
2 "exec-opts": ["native.cgroupdriver=systemd"],
3 "log-driver": "json-file",
4 "log-opts": {
5 "max-size": "100m"
6 },
7 "storage-driver": "overlay2"
8}
- Reboot the device
1sudo reboot
Configure Kubernetes on the RPi
- Add the required packages
1sudo apt update && sudo apt install -y apt-transport-https curl
- Add the GPG key
1curl -s https://packages.cloud.google.com/apt/doc/apt-key.gpg | sudo apt-key add -
- Create the Kubernetes package list - /etc/apt/sources.list.d/kubernetes.list
1cat <<EOF | sudo tee /etc/apt/sources.list.d/kubernetes.list
2deb https://apt.kubernetes.io/ kubernetes-xenial main
3EOF
- Update the device packages
1sudo apt update
- Install the Kubernetes specific packages
1sudo apt-get install -y kubelet kubeadm kubectl
- Optional: Pin the packages
1sudo apt-mark hold kubelet kubeadm kubectl
Configure a kubernetes image
- On the master node - Pull the images
1kubeadm config images pull
The following images will be pulled to the device:
- [config/images] Pulled k8s.gcr.io/kube-apiserver:v1.18.3
- [config/images] Pulled k8s.gcr.io/kube-controller-manager:v1.18.3
- [config/images] Pulled k8s.gcr.io/kube-scheduler:v1.18.3
- [config/images] Pulled k8s.gcr.io/kube-proxy:v1.18.3
- [config/images] Pulled k8s.gcr.io/pause:3.2
- [config/images] Pulled k8s.gcr.io/etcd:3.4.3-0
- [config/images] Pulled k8s.gcr.io/coredns:1.6.
Initialise Kubernetes Master
- On the master node i.e. k8s-master-01
1sudo kubeadm init --pod-network-cidr=10.17.0.0/16 --service-cidr=10.18.0.0/24 --service-dns-domain=mydomain.com
Capture the Example join command from the above command: e.g.
1kubeadm join 192.168.86.183:6443 --token 9hj1ar.zko79d0pldz3x1x6 \
2 --discovery-token-ca-cert-hash sha256:47cb858687610945e8b781eaf2daa361d464eb1f857ea9ca0cab927770f433e4
- On the worker node use the join command shown on the master node
1sudo kubeadm join 192.168.86.180:6443 --token 14cdv5.5m2npm147k0kqtuz \
2 --discovery-token-ca-cert-hash sha256:c1640d15af659b9ed4d658b927f7358dd8e6e78a9bd0e3bc44c5caf95e159791
- On the master node kubectl will not be working at this stage and return an error as we have a bit more configuration to do. Try running kubectl get nodes will result in the following error:
The connection to the server localhost:8080 was refused - did you specify the right host or port?
- Make a directory for kubernetes configurations
1mkdir -p $HOME/.kube
- Copy across a configuration
1sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
- Amend the owner permissions for the directory e.g. current USER/GROUP
1sudo chown $(id -u):$(id -g) $HOME/.kube/config
- At this point the nodes will be available but in a NotReady state. They lack a network overlay.
1NAME STATUS ROLES AGE VERSION
2k8s-master-01 NotReady master 10m v1.19.0
3k8s-worker-01 NotReady <none> 6m59s v1.19.0
Configure a network overlay on RPI
- On the Master Node apply a Flannel Pod network
1kubectl apply -f https://raw.githubusercontent.com/coreos/flannel/master/Documentation/kube-flannel.yml
- Confirm the Pod network is running
1kubectl get pods --all-namespaces
- Check the available nodes
1kubectl get nodes
- At this point the Cluster should be up and running as per below:
1NAME STATUS ROLES AGE VERSION
2k8s-master-01 Ready master 15m v1.19.0
3k8s-worker-01 Ready <none> 12m v1.19.0