k3s is a lightweight, certified Kubernetes distribution designed for resource-constrained environments, edge computing, IoT devices, and development workstations. Created by Rancher (now SUSE), k3s packages the entire Kubernetes control plane into a single binary under 100 MB, removing cloud-provider integrations, storage drivers, and alpha features that are not needed in most deployments. k3s uses SQLite as the default datastore (instead of etcd), uses Traefik as the built-in ingress controller, and provides a built-in load balancer and local-path storage provisioner. This makes a functional Kubernetes cluster available in under 60 seconds on RHEL 9, compared to the multi-step kubeadm setup. This guide covers installing k3s on RHEL 9 as a single-node cluster and as a multi-node setup with worker nodes.
Prerequisites
- RHEL 9 with sudo/root access
- Minimum 512 MB RAM (1 GB recommended for multi-workload use)
Step 1 — Install k3s (Single Node)
# Install the latest stable k3s release
curl -sfL https://get.k3s.io | sh -
# k3s automatically:
# - Installs as a systemd service
# - Installs kubectl, crictl, ctr
# - Creates /etc/rancher/k3s/k3s.yaml (kubeconfig)
# Verify installation
systemctl status k3s
kubectl get nodes
Step 2 — Configure kubectl Access
# k3s kubeconfig is owned by root — copy for non-root user access
mkdir -p ~/.kube
cp /etc/rancher/k3s/k3s.yaml ~/.kube/config
chown $USER:$USER ~/.kube/config
# Or set environment variable
export KUBECONFIG=/etc/rancher/k3s/k3s.yaml
# Verify cluster is healthy
kubectl get nodes
kubectl get pods --all-namespaces
Step 3 — Add Worker Nodes
# On the control plane, get the node token
cat /var/lib/rancher/k3s/server/node-token
# On each worker node, install k3s as an agent
# Replace K3S_URL with your control plane IP and K3S_TOKEN with the token
curl -sfL https://get.k3s.io | K3S_URL=https://192.168.1.100:6443
K3S_TOKEN=K10abc123::server:xyz789 sh -
# Back on the control plane, verify all nodes joined
kubectl get nodes
Step 4 — Deploy a Test Application
# Deploy Nginx
kubectl create deployment nginx --image=nginx:alpine --replicas=2
kubectl expose deployment nginx --port=80 --type=LoadBalancer
# k3s includes klipper-lb (ServiceLB) which assigns an external IP
kubectl get service nginx
# For NodePort access (always works)
kubectl expose deployment nginx --port=80 --type=NodePort --name=nginx-np
kubectl get service nginx-np
# Access: http://server-ip:NODEPORT
Step 5 — Uninstall k3s
# Uninstall k3s server (control plane)
/usr/local/bin/k3s-uninstall.sh
# Uninstall k3s agent (worker node)
/usr/local/bin/k3s-agent-uninstall.sh
Conclusion
k3s on RHEL 9 provides a production-ready Kubernetes distribution that starts in under 30 seconds and requires minimal system resources. It is the recommended choice for edge deployments, development environments, and small-scale production clusters where full Kubernetes is over-engineered. The built-in Traefik ingress controller, local-path provisioner, and ServiceLB load balancer mean a new k3s cluster is immediately functional without additional configuration — unlike kubeadm clusters that require separate CNI, ingress, and storage provisioner installation.
Next steps: How to Install Kubernetes with kubeadm on RHEL 9, How to Install Helm on RHEL 9, and How to Deploy Applications to Kubernetes on RHEL 9.