K3s Knative Ubuntu Raspberry Pi

Featured image

K3s Knative Ubuntu Raspberry Pi Link to heading

Knative is a super exciting solution for serverless and event driven applications. Personally, I have been using it as a part of my inner loop development. I can deploy dozens of workloads. All scaled down to zero when they aren’t being used. All responding and starting up quickly when they are needed.

I ran into a couple of problems with Envoy on Raspberry Pi OS. After investigating, it is a known issue in the Raspberry Pi OS kernel. In order to keep going forward with my project I had to choose between fixing the kernel or trying Ubuntu.

This is an overview of how to get Knative Serving working on a Raspberry Pi device with K3s and Ubuntu.

Install Ubuntu Server Link to heading

Use RPI Imager. Select Ubuntu Server 22.10 64-bit from the list of other distributions. Boot the new image.

I was happy to see that SSH and the default user were configured as expected by using the advanced settings options.

Upgrade the stuff Link to heading

# Grab the latest repository info
sudo apt update 
# Install one prerequisite package that isn't installed by default
sudo apt install linux-modules-extra-raspi -y
# Upgrade everything that can be upgraded
sudo apt dist-upgrade -y

Fix cgroup Link to heading

# Add this to the beginning of /boot/firmware/cmdline.txt
# cgroup_enable=cpuset cgroup_memory=1 cgroup_enable=memory
sudo nano -w /boot/firmware/cmdline.txt

Reboot after making this change.

sudo shutdown -r now

Install k3s via k3sup Link to heading

From my laptop, not one of the Raspberry Pi nodes, run k3sup, it’s super easy. If you haven’t figured it out by now, I’m a big fan of k3sup.

export CONTROL_NODE_IP=10.0.0.10
# Disable Traefik because we will use kourier for knative
k3sup install --ip $CONTROL_NODE_IP --user pi --k3s-extra-args '--disable traefik' --merge --local-path ~/.kube/config --context cluster00
# Knative-Serving with Kourier works on a single Raspberry Pi 4 with 8GB
# Optionally add other nodes
k3sup join --ip 10.0.0.11 --server-ip $CONTROL_NODE_IP --user pi
k3sup join --ip 10.0.0.12 --server-ip $CONTROL_NODE_IP --user pi

Deep breath Link to heading

This is where I struggled with how to deliver this example. The Knative install documentation is awesome. I’ve been through it dozens of times!

I tried to simplify this for you. I want to give you the ’easy button’ experience. I created a repository with all the YAML you need to deploy Knative Serving to this K3s cluster.

Knative Serving with Kourier Link to heading

git clone https://github.com/dashaun/knative-serving-raspberry-pi
cd knative-serving-raspberry-pi/operator-serving-kourier
# Use the `default` namespace in the Kubernetes cluster
kubectl config set-context --current --namespace=default
# Deploy the Knative operator
kubectl apply -f operator.yaml
# Check the deployment status
kubectl get deployment knative-operator

Continue when Ready status is 1/1

NAME               READY   UP-TO-DATE   AVAILABLE   AGE
knative-operator   1/1     1            1           19h
# Install Knative Serving custom resource and Kourier
kubectl apply -f knative-serving.yaml
# Check the custom resource status
kubectl get KnativeServing knative-serving -n knative-serving

Continue when READY is True

NAME              VERSION   READY   REASON
knative-serving   1.8.0     True
# Check the deployment status
kubectl get deployment -n knative-serving

Continue when READY are all 1/1

NAME                     READY   UP-TO-DATE   AVAILABLE   AGE
activator                1/1     1            1           23m
autoscaler               1/1     1            1           23m
controller               1/1     1            1           23m
domain-mapping           1/1     1            1           23m
domainmapping-webhook    1/1     1            1           23m
autoscaler-hpa           1/1     1            1           23m
3scale-kourier-gateway   1/1     1            1           23m
webhook                  1/1     1            1           23m
net-kourier-controller   1/1     1            1           23m

SSLIP.IO and a Spring Boot 3 native application Link to heading

# Install default domain
kubectl apply -f serving-default-domain.yaml
# Deploy a Spring Boot 3 `native` application
kubectl apply -f spring-boot-native-pi-service.yaml
# Get the address
kubectl get ksvc spring-boot-native-pi --output=custom-columns=NAME:.metadata.name,URL:.status.url
NAME                    URL
spring-boot-native-pi   http://spring-boot-native-pi.default.10.0.0.10.sslip.io
# Curl the address provided by knative with `/actuator/health` at the end
curl http://spring-boot-native-pi.default.default.10.0.0.10.sslip.io/actuator/health

Expected output:

{"status":"UP"}

Summary Link to heading

With the recent release of Spring Boot 3.0.0, my Raspberry Pi collection has become significantly more interesting. Knative Serving allows me to deploy dozens of Spring Boot / Spring Cloud workloads to a tiny, low power device, with very exciting capabilities.

Keep Learning Link to heading