Raspberry Pi's made simple!
- Install Ubuntu Server on Raspberry Pi 3/4/5
- Install Kubernetes (MicroK8s) on Raspberry Pi 3/4/5
- Install Knative on Kubernetes (MicroK8s) on Raspberry Pi 3/4/5
- Deploy WebAssembly (Wasm) Serverless Applications with Knative and Kubernetes (MicroK8s) on Raspberry Pi 3/4/5
Warning: Following these steps will erase all existing content on the microSD card.
- Insert the microSD card into your computer.
- Install the Raspberry Pi Imager for your operating system:
- Raspberry Pi Imager for Ubuntu
- Raspberry Pi Imager for Windows
- Raspberry Pi Imager for macOS
- Or, on Ubuntu:
sudo snap install rpi-imager
- Start the Imager and open the "CHOOSE OS" menu.
- Select "Other general-purpose OS" > "Ubuntu" and choose the latest Ubuntu 24.04 LTS server for 64-bit architectures.
- Select the image, open the "Choose Storage" menu, and select your microSD card.
- Before clicking 'Write', click the cog icon for advanced options.
In the Advanced Options menu, you can:
- Set the hostname.
- Enable SSH for remote access.
- Configure Wi-Fi (SSID and password) for automatic connection.
After entering your details, click 'Save' and then 'Write' to flash the SD card. Eject the SD card and insert it into your Raspberry Pi.
- Connect an HDMI screen and USB keyboard, then power on the Pi.
- Warning: Wait for cloud-init to finish before logging in (typically less than 2 minutes).
- Login using the username and password set in Advanced Options. If not set, the default is
ubuntu
for both.
-
Find the Raspberry Pi’s IP address:
- Check the router’s dashboard for connected devices.
- Or, temporarily connect a monitor and run:
hostname -I
-
Use an SSH client:
- On Ubuntu/macOS (pre-installed) or Windows Terminal, run:
ssh <username>@<Raspberry Pi’s IP address>
- Or use the hostname set in Advanced Options.
- On Ubuntu/macOS (pre-installed) or Windows Terminal, run:
-
Confirm the connection and log in.
For more details, visit the source: Ubuntu Raspberry Pi Installation Tutorial
To run MicroK8s on ARM hardware (like Raspberry Pi), you must enable cgroups. Edit the boot parameters by running:
sudo vi /boot/firmware/cmdline.txt
Note: In some Raspberry Pi distributions, the boot parameters are located in /boot/firmware/nobtcmd.txt
.
Add the following to the file:
cgroup_enable=memory cgroup_memory=1
If you are using Ubuntu 21.10 or later, install the extra kernel modules:
sudo apt install linux-modules-extra-raspi
You can install MicroK8s using the snap package:
sudo snap install microk8s --classic
MicroK8s creates a group to enable seamless usage of commands that require admin privilege. To add your current user to the group and gain access to the .kube caching directory, run the following three commands:
sudo usermod -a -G microk8s $USER
mkdir -p ~/.kube
chmod 0700 ~/.kube
You will also need to re-enter the session for the group update to take place:
su - $USER
MicroK8s has a built-in command to display its status. During installation you can use the --wait-ready
flag to wait for the Kubernetes services to initialize:
microk8s status --wait-ready
MicroK8s bundles its own version of kubectl for accessing Kubernetes. Use it to run commands to monitor and control your Kubernetes. For example, to view your node:
microk8s kubectl get nodes
…or to see the running services:
microk8s kubectl get services
MicroK8s uses a namespaced kubectl command to prevent conflicts with any existing installs of kubectl. If you don’t have an existing install, it is easier to add an alias (append to ~/.bash_aliases
) like this:
alias kubectl='microk8s kubectl'
Kubernetes is meant for deploying apps and services. You can use the kubectl command to do that as with any Kubernetes. Try installing a demo app:
microk8s kubectl create deployment nginx --image=nginx
It may take a minute or two to install, but you can check the status:
microk8s kubectl get pods
Before installing Knative on MicroK8s, ensure you have the following:
Knative is part of the MicroK8s community add-ons. To enable Knative, you must first enable the community add-ons repository:
microk8s enable community
After enabling the community repository, you can now install Knative using MicroK8s:
microk8s enable knative
This will install both the Knative Serving and Knative Eventing components to manage your serverless workloads.
To verify that Knative has been successfully installed, you can run:
microk8s kubectl get pods -n knative-serving
microk8s kubectl get pods -n knative-eventing
Check that all pods are running and that Knative is ready to serve your serverless applications.
cat <<EOF | kubectl apply -f -
apiVersion: serving.knative.dev/v1
kind: Service
metadata:
name: hello
spec:
template:
spec:
containers:
- image: csantanapr/helloworld-go:latest
ports:
- containerPort: 8080
env:
- name: TARGET
value: "Knative"
EOF
This will deploy a simple Knative service that returns a "Hello Knative" message.
kubectl get service.serving.knative.dev
kubectl get service.serving.knative.dev
First, you'll need to get the IP address of your Ingress:
microk8s kubectl get service kourier-internal -n knative-serving -o wide
Example:
microk8s kubectl get service kourier-internal -n knative-serving -o wide
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE SELECTOR
kourier-internal ClusterIP 10.152.183.42 <none> 80/TCP,443/TCP 15d app=3scale-kourier-gateway
Next, you need the URL of the Knative service. You can retrieve the service’s internal URL using:
microk8s kubectl get service.serving.knative.dev
You’ll see output like this:
NAME URL LATESTCREATED LATESTREADY READY REASON
hello http://hello.default.svc.cluster.local hello-xyz hello-xyz True
You can now curl the service by using the Cluster-IP address and full URL:
curl -v -H "Host: hello.default.svc.cluster.local" http://10.152.183.42 -d "Hello World!"
This will invoke the Knative service directly without requiring DNS.
Deploy WebAssembly (Wasm) Serverless Applications with Knative and Kubernetes(Microk8s) on Raspberry Pi 3/4/5
Before installing Knative on MicroK8s, ensure you have the following:
To enable WebAssembly support on MicroK8s, you first need to enable the kwasm addon. Run the following command:
microk8s enable kwasm
This will enable the required components to support WebAssembly applications in Kubernetes.
Now that you have the WebAssembly runtime installed on the nodes via kwasm operator, you can deploy a runtime class for your Wasm applications. Use the following YAML to create the RuntimeClass
for wasmedge
:
cat <<EOF | microk8s kubectl apply -f -
apiVersion: node.k8s.io/v1
kind: RuntimeClass
metadata:
name: wasmedge
handler: wasmedge
EOF
This will set up wasmedge
as the runtime for running Wasm-based serverless applications on Kubernetes with MicroK8s. More runtime examples (spin,wasmtime,wasmer) in the file examples/runtimeclass.yml.
Knative does not allow deploying resources with runtimeClassName
, which is required to run WebAssembly workloads using wasmedge
. To bypass this limitation, you need to delete the Knative Validating Webhook that enforces this restriction.
Check validations
kubectl get ValidatingWebhookConfiguration
Removing serving validation
kubectl delete ValidatingWebhookConfiguration validation.webhook.serving.knative.dev
cat <<EOF | kubectl apply -f -
apiVersion: serving.knative.dev/v1
kind: Service
metadata:
name: wasm-http-server
namespace: default
spec:
template:
metadata:
annotations:
module.wasm.image/variant: compat-smart
spec:
runtimeClassName: wasmedge
containers:
- name: funcb
image: docker.io/keniack/wasm-http-server:latest
ports:
- containerPort: 8080
EOF
This will deploy a simple Knative service that returns a "Hello World" message.
kubectl get service.serving.knative.dev
kubectl get service.serving.knative.dev
First, you'll need to get the IP address of your Ingress:
microk8s kubectl get service kourier-internal -n knative-serving -o wide
Example:
microk8s kubectl get service kourier-internal -n knative-serving -o wide
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE SELECTOR
kourier-internal ClusterIP 10.152.183.42 <none> 80/TCP,443/TCP 15d app=3scale-kourier-gateway
Next, you need the URL of the Knative service. You can retrieve the service’s internal URL using:
microk8s kubectl get service.serving.knative.dev
You’ll see output like this:
NAME URL LATESTCREATED LATESTREADY READY REASON
hello http://wasm-http-server.default.svc.cluster.local wasm-http-server-xyz wasm-http-server-xyz True
You can now curl the service by using the Cluster-IP address and full URL:
curl -v -H "Host: wasm-http-server.default.svc.cluster.local" http://10.152.183.42 -d "Hello World!"
This will invoke the Knative service directly without requiring DNS.