Back to blog
November 2025 6 min read

K3s in the Real World: Install, Break, Fix, Repeat

A practical field guide to K3s — installation on Linux and Windows, kubeconfig setup, Lens connectivity, force-deleting stuck namespaces, and certificate rotation when your cluster's TLS finally expires.

K3s Kubernetes Rancher DevOps Linux Windows Certificates

K3s is what Kubernetes looks like when you strip out everything that isn't essential — a single binary, sub-100MB memory footprint, and a cluster that's production-usable in under a minute. It's the go-to choice for edge deployments, small VMs, homelabs, and any environment where a full kubeadm cluster would be overkill.


Quick Install (Default)

The fastest path to a running cluster:

curl -sfL https://get.k3s.io | sh -
export KUBECONFIG=/etc/rancher/k3s/k3s.yaml

That's it — a single-node K3s cluster with a bundled Traefik ingress controller, local-path storage provisioner, and containerd runtime.


Production-Style Install

For anything beyond a throwaway VM, you'll usually want more control: disabling the bundled Traefik (if you're running your own), setting the correct TLS SAN for external access, and fixing kubeconfig permissions.

curl -sfL https://get.k3s.io | INSTALL_K3S_EXEC="--disable=traefik" sh -s - \
  server \
  --write-kubeconfig-mode 644 \
  --tls-san <your-vm-public-ip>

Replace <your-vm-public-ip> with the actual IP or hostname you'll use to reach the API server — this must be baked in at install time or the server certificate won't validate for that address.

Long-Lived Certificates

By default, K3s issues certs with a relatively short validity window. If you'd rather not deal with rotation for a decade, extend the signing duration at install time:

curl -sfL https://get.k3s.io | INSTALL_K3S_EXEC="--disable=traefik" sh -s - \
  server \
  --write-kubeconfig-mode 644 \
  --tls-san <your-vm-public-ip> \
  --kube-apiserver-arg=--experimental-cluster-signing-duration=87600h

Persist KUBECONFIG

Add it to your shell profile so it survives new sessions:

echo 'export KUBECONFIG=/etc/rancher/k3s/k3s.yaml' >> ~/.bashrc
source ~/.bashrc

Firewall Ports (RHEL / RHEL10)

K3s needs a specific set of ports open for API access, etcd (if used), VXLAN overlay networking, kubelet, NodePort services, and WireGuard (if enabled as the CNI backend):

for p in 6443/tcp 2379-2380/tcp 8472/udp 10250/tcp 30000-32767/tcp 51820/udp 51821/udp; do
  firewall-cmd --permanent --add-port=$p
done
firewall-cmd --reload
firewall-cmd --list-ports

Connecting Lens (or Other GUI Clients)

Lens and similar tools authenticate against the cluster using a serving certificate. If Lens can't connect, check the k3s-serving secret:

kubectl edit secret k3s-serving -n kube-system

Make sure the SANs in that secret actually include the address you're connecting from — if you didn't set --tls-san at install time, this is usually where the mismatch shows up.


Force-Deleting a Stuck Namespace

Namespaces occasionally get stuck in Terminating because a resource inside still has a finalizer blocking cleanup. Here's how to clear it manually:

Step 1 — Dump the namespace as JSON:

kubectl get namespace <namespace-name> -o json > ns.json

Step 2 — Edit ns.json and empty the finalizers list:

"spec": {
  "finalizers": []
}

Step 3 — Push the modified spec directly to the finalize subresource:

kubectl replace --raw "/api/v1/namespaces/<namespace-name>/finalize" -f ns.json

Use this as a last resort — a finalizer usually exists because something (a controller, an operator, a webhook) needs to run cleanup logic first. Force-deleting can leave orphaned cloud resources or dangling records behind.


Certificate Management

Check Certificate Expiry

openssl x509 -in /var/lib/rancher/k3s/server/tls/server-ca.crt -text -noout | grep "Not After"

Regenerate Expired Certificates (Manual Method)

If the cluster CA has already expired and the API server won't come back up:

# 1. Stop K3s
sudo systemctl stop k3s

# 2. Remove only the certs — leave the raft/db and kubeconfig alone
sudo rm -f /var/lib/rancher/k3s/server/tls/*.crt
sudo rm -f /var/lib/rancher/k3s/server/tls/*.key

# 3. Start K3s — it regenerates missing certs automatically
sudo systemctl start k3s

Do not delete /var/lib/rancher/k3s/server/db/ — that's your cluster state. And leave /etc/rancher/k3s/k3s.yaml alone unless you're resetting the entire cluster.

If the API server address changed and your local kubeconfig still points at 127.0.0.1:

sudo sed -i 's/127.0.0.1/<your-node-ip>/g' /etc/rancher/k3s/k3s.yaml

Then copy the updated file to your workstation and point kubectl/Lens at it.

Certificate Rotation (Built-in Command)

Newer K3s versions ship a proper rotate command instead of manual deletion — safer, since it backs up nothing for you, so back it up yourself first:

# 1. Stop K3s
systemctl stop k3s

# 2. Back up existing certs before touching anything
cp -r /var/lib/rancher/k3s/server/tls /opt/k3s-cert-backup/tls.bak.$(date +%F)

# 3. Remove old certs
rm -f /var/lib/rancher/k3s/server/tls/*.crt
rm -f /var/lib/rancher/k3s/server/tls/*.key

# 4. Rotate
k3s certificate rotate

# 5. Verify new validity dates
openssl x509 -in /var/lib/rancher/k3s/server/tls/server-ca.crt -noout -dates

# 6. Start K3s back up
systemctl start k3s

Running K3s on Windows (WSL + Rancher Desktop)

K3s itself is Linux-only, but Rancher Desktop gives you a fully managed K3s cluster inside WSL2 — kubeconfig handled automatically, no manual cert wrangling.

Step 1 — Install WSL and a Debian Distro

wsl --install -d Debian

Already have WSL? Just make sure it defaults to v2:

wsl --set-default-version 2

Reboot if prompted, then launch Debian from the Start Menu to finish first-time user setup.

Step 2 — Install Rancher Desktop

Download from rancherdesktop.io, run the installer, then in Kubernetes Settings:

  • Kubernetes distribution: K3s
  • Container Runtime: containerd (or dockerd)
  • Version: latest is fine

Click Apply & Restart — Rancher Desktop provisions and manages the K3s cluster inside WSL for you.

Step 3 — Install kubectl.exe

mkdir %USERPROFILE%\kubectl-tools
curl.exe -Lo %USERPROFILE%\kubectl-tools\kubectl.exe "https://dl.k8s.io/release/v1.33.0/bin/windows/amd64/kubectl.exe"
setx PATH "%PATH%;%USERPROFILE%\kubectl-tools"

Restart your shell to pick up the updated PATH.

Step 4 — Verify

kubectl version --client
kubectl get nodes

A node listed from Rancher Desktop confirms everything is wired up correctly. Rancher Desktop manages KUBECONFIG automatically — you'll typically find it at %USERPROFILE%\.kube\config.


Summary

| Task | Command | |---|---| | Install K3s | curl -sfL https://get.k3s.io \| sh - | | Set kubeconfig | export KUBECONFIG=/etc/rancher/k3s/k3s.yaml | | Check cert expiry | openssl x509 -in .../server-ca.crt -noout -dates | | Rotate certs | k3s certificate rotate | | Force-delete namespace | kubectl replace --raw ".../finalize" -f ns.json | | Windows cluster | Rancher Desktop (K3s backend) via WSL2 |

Golden rule: back up /var/lib/rancher/k3s/server/tls and never touch /var/lib/rancher/k3s/server/db/ when troubleshooting certificates — the database is your cluster's memory; the certs are just its ID card.