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.