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 is1/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
isTrue
NAME VERSION READY REASON knative-serving 1.8.0 True
# Check the deployment status
kubectl get deployment -n knative-serving
Continue when
READY
are all1/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.