Cluster Mastery: Multi-Node K3s Cluster on Raspberry Pi 5¶
Running a containerized infrastructure across multiple nodes provides redundancy, load-balancing, and resource scaling. While a single-node setup is great, a multi-node Kubernetes cluster is the ultimate endpoint for a serious home lab.
Using K3s (a highly optimized, lightweight Kubernetes distribution by Rancher) on Raspberry Pi 5, we can build a production-grade cluster with very low overhead.
This guide walks you through: 1. System-level prerequisites (configuring kernel cgroups). 2. Setting up the K3s Control Plane (Master Node). 3. Joining Worker Nodes (Agent Nodes). 4. Setting up ingress routing with Traefik and mapping it to a local DNS domain.
Hardware Architecture¶
Step 1: System Configuration (Execute on ALL Nodes)¶
Kubernetes requires kernel-level resource control mechanisms (cgroups) to restrict CPU and memory allocation for individual containers. Raspberry Pi OS disables these by default.
1. Enable Cgroups in the Boot Command Line¶
On every Raspberry Pi that will be part of the cluster, edit the boot command-line parameters:
Append the following parameters to the end of the existing single line (do not create a new line!):
2. Disable Swap¶
Kubernetes schedulers perform optimally when swap space is disabled entirely, avoiding performance degradation when nodes run out of memory.
Step 2: Set Up the Control Plane (Master Node)¶
Select your primary Raspberry Pi 5 to act as the master node. This node will host the Kubernetes control plane API database (kine/SQLite) and scheduler.
1. Install K3s Control Plane¶
Run the K3s installation script. We will tell it to install with Traefik enabled, but we will bind the local storage resolver:
Note: We disableservicelb because we will routing traffic using Traefik and host ports, or you can later add MetalLB for actual IP management.
2. Retrieve the Cluster Token and Node IP¶
Worker nodes require a secure token generated by the master node to join the cluster.
Print the token:
K10a7216a...::server:a45e...)
Find the IP address of the master node (e.g., 192.168.1.100):
Step 3: Join the Worker Nodes (Agent Nodes)¶
SSH into your second (and third) Raspberry Pi 5 and execute the join command.
Replace <MASTER_IP> with your master node's IP, and <NODE_TOKEN> with the token value you copied in the previous step:
Verify Cluster Status¶
Go back to the master node and verify that all nodes have successfully joined and are in the Ready state:
Step 4: Deploying a Test Application with Traefik Ingress¶
Now that the cluster is healthy, let's deploy a simple web application, expose it via a Kubernetes Service, and configure Traefik Ingress to route requests to it based on a custom local domain: webapp.local.
Create a deployment manifest:
Add the following Kubernetes configuration containing a Deployment, a Service, and an Ingress:
Deploy the application:
Check the status of the pods:
Step 5: Local DNS Mapping¶
To access http://webapp.local from your local devices:
Option A: Local DNS Server (AdGuard Home / Pi-hole)¶
If you run a local DNS server (e.g., our AdGuard Home Guide):
1. Navigate to the DNS server dashboard.
2. Go to Filters -> DNS Rewrites.
3. Map webapp.local to the IP address of any node in your K3s cluster (Traefik listens on host port 80 across all nodes and automatically routes the traffic inside the cluster).
Option B: Local Hosts File¶
On your desktop machine, edit your /etc/hosts (macOS/Linux) or C:\Windows\System32\drivers\etc\hosts (Windows):
Open your browser and load http://webapp.local. You will see the default Nginx welcome page, served directly from your Raspberry Pi 5 Kubernetes cluster!
By implementing this configuration, you have built a powerful, resilient multi-node K3s cluster on Raspberry Pi 5, ready for production homelab application deployment.