Skip to content
Products
AI Website Builder New VPS Hosting Cloud Servers Web Hosting Dedicated Servers Domains
Company
About Documentation Support Center Contact Get Started Login Client Area
ALL SYSTEMS OPERATIONAL
VPS

Set Up K3s (Lightweight Kubernetes) on a Single VPS

Getwebup 6 min read

You don't need a three-node cluster and a platform team to run Kubernetes. If you've outgrown a single Docker container but full-blown Kubernetes still feels like overkill for your traffic, k3s gets you a real, API-compatible cluster on one VPS — with a single binary and none of the etcd/control-plane baggage. Here's how to bring it up cleanly, reach it from your laptop, and get past the errors that trip people up on the first boot.

Why k3s instead of full Kubernetes

Upstream Kubernetes wants etcd, multiple control-plane components, and generally more RAM than a single VPS wants to give it. k3s, built by Rancher, strips that down: it ships as one binary, uses SQLite (or an external DB if you scale later) instead of etcd, and runs comfortably in under 512MB of control-plane overhead. It's still real Kubernetes — same kubectl, same manifests, same CRDs — so anything you learn here carries over if you outgrow a single node later.

Before you start

  • 2GB RAM minimum, 4GB if you're running more than three or four small services. K3s itself is light, but your workloads aren't.
  • A 64-bit distro — Ubuntu 22.04/24.04 or Debian 12 are the most tested. Rocky/AlmaLinux work too, just watch the firewalld vs iptables difference below.
  • Root or sudo access, and a non-root user you're comfortable running kubectl as day to day.
  • A domain (optional but recommended) pointed at the VPS's A record if you want TLS via Let's Encrypt on the ingress.

Step 1: Open the ports k3s actually needs

If you're running UFW or CSF, open these before you install — k3s will still start without them, but pods won't schedule properly and you'll waste an hour blaming the wrong thing:

sudo ufw allow 6443/tcp   # Kubernetes API server
sudo ufw allow 80/tcp     # HTTP (Traefik ingress)
sudo ufw allow 443/tcp    # HTTPS (Traefik ingress)
sudo ufw allow from 10.42.0.0/16   # pod network, if using UFW strictly
sudo ufw allow from 10.43.0.0/16   # service network
sudo ufw reload

Those 10.42.0.0/16 and 10.43.0.0/16 ranges are k3s's default pod and service CIDRs. On a single node they mostly matter for pods talking to each other and to the API server — skip the internal rules only if your firewall already trusts loopback and internal bridges.

Step 2: Install k3s

The official install script handles the binary, systemd service, and a working default config in one shot:

curl -sfL https://get.k3s.io | sh -

That's genuinely it for a single-node cluster. It starts a k3s.service, installs kubectl (aliased as k3s kubectl), and writes a kubeconfig to /etc/rancher/k3s/k3s.yaml. Check it came up clean:

sudo systemctl status k3s
sudo k3s kubectl get nodes

You should see one node in Ready state. If it's stuck on NotReady for more than a minute or two, jump to the troubleshooting table below.

If you want a specific version pinned (sensible for anything you'll run in production), set it explicitly instead of pulling latest:

curl -sfL https://get.k3s.io | INSTALL_K3S_VERSION="v1.30.4+k3s1" sh -

Step 3: Reach the cluster from your own machine

Running kubectl over SSH every time gets old fast. Copy the kubeconfig down and point kubectl at the VPS's public IP instead of 127.0.0.1:

# on your laptop
scp root@your-vps-ip:/etc/rancher/k3s/k3s.yaml ~/.kube/k3s-vps.yaml
sed -i '' 's/127.0.0.1/your-vps-ip/' ~/.kube/k3s-vps.yaml   # macOS sed
export KUBECONFIG=~/.kube/k3s-vps.yaml
kubectl get nodes

The kubeconfig file has full cluster-admin rights baked in, so treat it like a root password — don't commit it, don't email it, and rotate the node token if you think it's leaked (/var/lib/rancher/k3s/server/node-token on the VPS).

Step 4: Deploy something and expose it

K3s ships with Traefik as its ingress controller by default, so you don't need to install one separately. A minimal deploy-and-expose looks like this:

kubectl create deployment hello --image=nginxdemos/hello --port=80
kubectl expose deployment hello --port=80
kubectl apply -f - <

Point hello.yourdomain.com at the VPS's A record and it should resolve within a few minutes. For TLS, the simplest route on k3s is installing cert-manager and letting it issue Let's Encrypt certs against your Traefik ingress — worth its own setup, but a five-minute Helm install once you're at this point:

kubectl apply -f https://github.com/cert-manager/cert-manager/releases/latest/download/cert-manager.yaml

Common startup errors and how to fix them

SymptomLikely causeFix
Node stuck on NotReadyCNI (flannel) can't bind, usually a firewall or swap issueCheck sudo journalctl -u k3s -f for flannel errors; confirm ports above are open
connection refused on port 6443UFW/CSF blocking the API port, or k3s still initializingRe-check firewall rules; give it 60–90 seconds on first boot before panicking
Pods stuck in PendingNot enough memory/CPU requests available, or a taint on the nodekubectl describe pod <name> to see the scheduler's actual complaint
Traefik ingress not routingDNS not pointed at the VPS yet, or wrong ingress.class annotationConfirm dig hello.yourdomain.com resolves to the VPS IP; re-check the annotation matches your k3s version's default class
k3s.yaml permission deniedTrying to read the kubeconfig as a non-root usersudo chmod 644 /etc/rancher/k3s/k3s.yaml, or better, copy it out and lock it down locally

Backups and upgrades

Single-node k3s uses an embedded SQLite database by default, which lives at /var/lib/rancher/k3s/server/db. Back that directory up the same way you'd back up any other stateful directory on the VPS — a nightly rsync or snapshot job covers it. K3s also takes automatic etcd-style snapshots if you switch to its embedded etcd mode later, but for a single node the filesystem backup is simpler and sufficient.

Upgrades are a re-run of the install script with a pinned version:

curl -sfL https://get.k3s.io | INSTALL_K3S_VERSION="v1.31.2+k3s1" sh -

Take a VPS snapshot first. A failed upgrade on a single-node cluster means downtime for everything on it, not just the one app you were touching.

Prevention checklist

  • Pin your k3s version in production instead of tracking latest — surprise upgrades break ingress annotations more often than you'd think.
  • Set resource requests/limits on every deployment; without them, one runaway pod can starve everything else on the node.
  • Keep the kubeconfig off any machine that isn't yours — it's cluster-admin by default, with no scoping.
  • Monitor disk space separately from Kubernetes metrics. A full disk takes down k3s's SQLite store just as fast as any other database.
  • If you're running anything customer-facing, put a second VPS in the mix before you need it — k3s supports multi-server HA mode, and migrating early is a lot less stressful than migrating during an outage.

Frequently asked questions

Is k3s good enough for production, or just for testing?

Plenty of small production workloads run on single-node k3s just fine — it's the same Kubernetes API underneath. The tradeoff is that a single node is a single point of failure, so it suits side projects, internal tools, and low-traffic apps better than anything that can't tolerate downtime during a VPS reboot.

Do I need Docker installed separately to use k3s?

No. K3s bundles containerd as its container runtime, so you don't need Docker on the host at all. If you already have Docker running for other things, k3s runs alongside it without conflict.

How much RAM does k3s actually need?

The control plane itself is comfortable in 512MB–1GB. What eats RAM is your workloads — budget for those on top, so 2GB total is a realistic floor for anything beyond a demo.

Can I run k3s across more than one VPS later?

Yes — k3s supports adding agent nodes to an existing server with a join token, and has an HA mode with an embedded etcd datastore for multiple server nodes. Starting single-node and expanding later is a normal path.

How is this different from just using Docker Compose on a VPS?

Docker Compose is simpler and fine for a handful of containers on one host. K3s buys you real orchestration — self-healing restarts, rolling updates, declarative manifests, and a path to multiple nodes — at the cost of a steeper learning curve and more moving parts to keep an eye on.

#k3s #kubernetes #vps #containers #devops #linux

Keep reading

Chat with Support