Disclosure: we may earn a commission or referral reward from CloudCone, Contabo, DigitalOcean (account credit, not cash), Hostwinds, InterServer, RackNerd, VPSDime and Vultr if you sign up through our links. It does not change the price you pay. Every other provider pays us nothing. Prices in this guide are as of the date shown and may have changed; see the comparison pages for the latest checked prices.

Guides · BLOG

How to run k3s Kubernetes on cheap VPS providers in 2026

Some prices quoted in this guide are out of date. It is being rebuilt on our price index; for current prices use the comparison pages, which show when each price was checked.

Full Kubernetes (Kubernetes-in-a-box, KIB) on a $200/month EKS cluster is overkill for most people. k3s is a lightweight, single-binary Kubernetes distribution that runs comfortably on cheap VPS providers — you can spin up a three-node cluster on Hetzner CX22 boxes for $14/mo total. This guide walks through the setup.

Prices as of 2026-09-22.

When k3s makes sense

  • You want the Kubernetes API and ecosystem for a small team.
  • You have a workload that benefits from container orchestration (multiple services, want automated rollouts).
  • You want to learn Kubernetes on a real cluster without $200/mo bills.

When it doesn't:

  • You have one Docker container. Just run it.
  • You need production HA at scale. Use managed Kubernetes (EKS, GKE, DOKS).
  • You're allergic to orchestration complexity. Fair; a plain VPS with docker-compose is fine.

The plan

Three-node k3s cluster: 1 control-plane, 2 workers. Total cost: ~$14/mo on Hetzner CX22s.

Alternative for higher spec: three Hetzner CX32s at $22.80/mo total (4 vCPU / 8 GB each — real cluster).

Provision the three VPS

Hetzner Cloud Console → create three CX22 instances in the same datacenter, same private network.

Enable a private network so the nodes can talk to each other without going through the public internet:

  • Hetzner Console → Networks → Create Network → 10.0.0.0/16.
  • Attach all three servers to this network.

Note each server's private IP (e.g., 10.0.0.2, 10.0.0.3, 10.0.0.4).

Install k3s on the control-plane node

SSH into the first node (control-plane):

```bash

curl -sfL https://get.k3s.io | INSTALL_K3S_EXEC="--flannel-backend=wireguard-native --node-ip=10.0.0.2" sh -

```

Wait for it to complete. Verify:

```bash

kubectl get nodes

```

Should show one node in Ready state.

Get the join token for workers:

```bash

cat /var/lib/rancher/k3s/server/node-token

```

Copy the output.

Install k3s workers

SSH into each worker node:

```bash

curl -sfL https://get.k3s.io | K3S_URL=https://10.0.0.2:6443 K3S_TOKEN=<token-from-above> INSTALL_K3S_EXEC="--node-ip=10.0.0.3" sh -

```

Replace 10.0.0.3 with each worker's actual private IP.

Back on the control-plane, verify:

```bash

kubectl get nodes

```

Should show all three nodes.

Configure kubectl locally

Copy /etc/rancher/k3s/k3s.yaml from the control-plane to your local machine. Edit it to change server: from 127.0.0.1 to your control-plane's public IP. Set KUBECONFIG=/path/to/k3s.yaml.

Now kubectl get nodes from your local machine hits the cluster.

Ingress: Traefik (included by default)

k3s ships with Traefik as the default ingress controller. Access it at the control-plane's public IP on port 80/443.

For a custom domain: create an Ingress resource pointing at your service:

```yaml

apiVersion: networking.k8s.io/v1

kind: Ingress

metadata:

name: myapp

spec:

rules:

  • host: myapp.yourdomain.com

http:

paths:

  • path: /

pathType: Prefix

backend:

service:

name: myapp

port:

number: 80

```

Point DNS at your control-plane's public IP. Requests route through Traefik to your service.

SSL via cert-manager

Install cert-manager:

```bash

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

```

Create a ClusterIssuer for Let's Encrypt:

```yaml

apiVersion: cert-manager.io/v1

kind: ClusterIssuer

metadata:

name: letsencrypt-prod

spec:

acme:

server: https://acme-v02.api.letsencrypt.org/directory

email: [email protected]

privateKeySecretRef:

name: letsencrypt-prod

solvers:

  • http01:

ingress:

class: traefik

```

Add annotations to your Ingress to auto-issue certs:

```yaml

metadata:

annotations:

cert-manager.io/cluster-issuer: letsencrypt-prod

spec:

tls:

  • hosts:
  • myapp.yourdomain.com

secretName: myapp-tls

```

Storage: Longhorn for persistent volumes

k3s's default storage is local-path (each PV bound to one node). For real production, install Longhorn for replicated storage:

```bash

kubectl apply -f https://raw.githubusercontent.com/longhorn/longhorn/v1.6.0/deploy/longhorn.yaml

```

Longhorn creates a distributed block store across your nodes. Now PVCs get replicated storage.

Note: Longhorn is memory-hungry. On 4 GB CX22 nodes, it's tight. On 8 GB CX32 nodes, comfortable.

Deploy your first app

```yaml

apiVersion: apps/v1

kind: Deployment

metadata:

name: hello

spec:

replicas: 2

selector:

matchLabels:

app: hello

template:

metadata:

labels:

app: hello

spec:

containers:

  • name: hello

image: hashicorp/http-echo

args:

  • "-text=Hello k3s!"

ports:

  • containerPort: 5678

apiVersion: v1

kind: Service

metadata:

name: hello

spec:

selector:

app: hello

ports:

  • port: 80

targetPort: 5678

```

```bash

kubectl apply -f hello.yaml

kubectl port-forward svc/hello 8080:80

```

Visit http://localhost:8080/ and see "Hello k3s!".

Cost comparison

Setup Nodes Monthly cost
3-node CX22 cluster 3 × Hetzner CX22 $13.80
3-node CX32 cluster 3 × Hetzner CX32 $22.80
3-node Contabo Cloud VPS 4 3 × Contabo $23.37
DOKS (DO Managed K8s) control plane free + 3 × Basic 2 GB ~$36
GKE Autopilot pay per resource $30-100+
EKS control plane $73 + workers $150+

k3s on 3× CX22 is dramatically cheaper than any managed Kubernetes option.

What you give up vs managed

  • Automatic control plane HA. k3s single control plane; if that node dies, cluster is down.
  • Automatic upgrades. You upgrade k3s manually.
  • Managed etcd. k3s uses SQLite by default (fine for small clusters); for bigger, embedded etcd.
  • Cloud provider LoadBalancer integration. Traefik with Ingress works, but no automatic external LB provisioning.

For learning or non-critical workloads, all fine. For critical prod, use managed Kubernetes.

Related guides

Prices as of 2026-09-22.