Running K3S on the RaspberryPi 4

Finally, I got my hands on a RaspberryPi 4 (4GB Edition) and I thought I'd write up a post on how to flash your Raspberry Pi with Raspbian OS and installing Rancher's Lightweight Kubernetes Distribution, K3S

This post is a quick run down on how I wanted to experiment with K3S (single node) on a Rpi4 and test out Traefik that comes out of the box. For much more in depth tutorial on k3s with clustering and deploying microservices using OpenFaas, have a look at Alex's Will it cluster? k3s on your Raspberry Pi blog post, its definitely worth the read.

On the To-Do List

This is what we will do during this post:

  • Download Raspbian
  • Flash with Etcher
  • Configure SSH and WiFi
  • Install K3S
  • Develop, Build and Deploy a Golang Web App to Kubernetes (next post)

Download Raspbian

Head over to Raspbian's Download Page and download the ISO of your choice, I went for Raspbian Buster Lite:

Raspbian Image Information

Once your download has finished, you should have a zip file located in your download directory.

Flash your Raspberry Pi

I will be using Etcher to flash my Raspberry Pi, but you can use any other utility of preference.

For more info or help on installing images, have a look at Raspberry Pi's Documentation

Using Etcher is quite easy, you select the image, the SD Card that you want to flash to, and select Flash:

Flashing with Etcher

Configure SSH and WiFi

Once the flash operation has been completed, re-insert your flash drive, and you should see your SD Card has been mounted using df -h

I am using a Mac, so in my case its mounted under /Volumes/boot . In order to allow SSH, we need to create a ssh file with no content in the root directory:

touch /Volumes/boot/ssh

For Linux, it could be: touch /media/${USER}/boot/ssh

To configure your raspberry pi to connect to your wireless network, we need to supply the wpa_supplicant.conf in the root directory of our SD Card:

Create the config file:

vim /Volumes/boot/wpa_supplicant.conf

Then the provide your SSID and PSK:

ctrl_interface=DIR=/var/run/wpa_supplicant GROUP=netdev  
update_config=1  
country=ZA

network={  
    ssid="your-wifi-name"
    psk="your-wifi-password"
    key_mgmt=WPA-PSK
}

Eject the SD Card, insert it into your Raspberry Pi and boot it

Finding your IP

You can use nmap to find the address, but in my case I was logged into my router, so having a look at the DHCP List, I was able to find my RaspberryPi's IP Address:

IP Address of my RaspberryPi

By default the username will be pi and the password will be raspberry:

$ ssh pi@192.168.0.111
Warning: Permanently added '192.168.0.111' (ECDSA) to the list of known hosts.
pi@192.168.0.111's password:
Linux raspberrypi 4.19.57-v7l+ #1244 SMP Thu Jul 4 18:48:07 BST 2019 armv7l


The programs included with the Debian GNU/Linux system are free software;
the exact distribution terms for each program are described in the
individual files in /usr/share/doc/*/copyright.


Debian GNU/Linux comes with ABSOLUTELY NO WARRANTY, to the extent
permitted by applicable law.

SSH is enabled and the default password for the 'pi' user has not been changed.
This is a security risk - please login as the 'pi' user and type 'passwd' to set a new password.


pi@raspberrypi:~ $

This will be a good time to reset your default password:

$ passwd
Changing password for pi.
Current password: 
New password: 
Retype new password: 
passwd: password updated successfully

Since this RaspberryPi comes with 4GB of memory, I just had to show this to the world :D

$ free -m
              total        used        free      shared  buff/cache   available
Mem:           3906          91        3590           8         223        3685
Swap:            99           0          99

Install K3S

Rancher released a super lightweight Certified Kubernetes distribution, called "K3S", which is optimized for ARM and super easy to install.

Have a look at their Documentation for more configuration options and detail.

Installing K3S is as easy as:

$ sudo su
$ curl -sfL https://get.k3s.io | sh -
[INFO]  Finding latest release
[INFO]  Using v0.8.0 as release
[INFO]  Downloading hash https://github.com/rancher/k3s/releases/download/v0.8.0/sha256sum-arm.txt
[INFO]  Downloading binary https://github.com/rancher/k3s/releases/download/v0.8.0/k3s-armhf
[INFO]  Verifying binary download
[INFO]  Installing k3s to /usr/local/bin/k3s
[INFO]  Creating /usr/local/bin/kubectl symlink to k3s
[INFO]  Creating /usr/local/bin/crictl symlink to k3s
[INFO]  Creating /usr/local/bin/ctr symlink to k3s
[INFO]  Creating killall script /usr/local/bin/k3s-killall.sh
[INFO]  Creating uninstall script /usr/local/bin/k3s-uninstall.sh
[INFO]  env: Creating environment file /etc/systemd/system/k3s.service.env
[INFO]  systemd: Creating service file /etc/systemd/system/k3s.service
[INFO]  systemd: Enabling k3s unit
Created symlink /etc/systemd/system/multi-user.target.wants/k3s.service → /etc/systemd/system/k3s.service.
[INFO]  systemd: Starting k3s

Boom! And about a minute later, kubernetes is running on my Raspberry Pi:

$ kubectl get nodes
NAME          STATUS   ROLES    AGE   VERSION
raspberrypi   Ready    master   27s   v1.14.5-k3s.1

By default, K3S provisions Traefik out of the box, and to confirm that, let's have a look at our deployments:

$ kubectl get deployments --all-namespaces
NAMESPACE     NAME      READY   UP-TO-DATE   AVAILABLE   AGE
kube-system   coredns   1/1     1            1           3m29s
kube-system   traefik   1/1     1            1           89s

Let's have a look at our pods from all our namespaces:

$ kubectl get pods --all-namespaces
NAMESPACE     NAME                         READY   STATUS      RESTARTS   AGE
kube-system   coredns-b7464766c-8mgzr      1/1     Running     0          3m12s
kube-system   helm-install-traefik-tqh92   0/1     Completed   0          3m12s
kube-system   svclb-traefik-t6jvz          2/2     Running     0          93s
kube-system   traefik-56688c4464-zvfxc     1/1     Running     0          92s

And viewing our services:

$ kubectl get service --all-namespaces
NAMESPACE     NAME         TYPE           CLUSTER-IP     EXTERNAL-IP     PORT(S)                      AGE
default       kubernetes   ClusterIP      10.43.0.1      <none>          443/TCP                      4m4s
kube-system   kube-dns     ClusterIP      10.43.0.10     <none>          53/UDP,53/TCP,9153/TCP       4m5s
kube-system   traefik      LoadBalancer   10.43.133.86   192.168.0.100   80:32543/TCP,443:30200/TCP   2m5s

Thank You

Thanks for reading, in the next post I will show you how to develop, build and deploy a golang webapp to kubernetes using K3S on a RaspberryPi

If you would like to check out more of my content, check out my website at ruan.dev or follow me on Twitter @ruanbekker