How to Set Up a Kubernetes Cluster on VPS (K3s Lightweight Guide)

How to Set Up a Kubernetes Cluster on VPS (K3s Lightweight Guide)

Kubernetes is the industry standard for container orchestration — but its full installation is notoriously complex and resource-hungry. K3s changes that equation completely. Developed by Rancher, K3s is a certified, production-ready Kubernetes distribution that installs in under 2 minutes, uses less than 512 MB of RAM, and runs comfortably on a single VPS.

This guide sets up a K3s cluster on Ubuntu VPS, deploys your first application, configures Traefik as an Ingress controller with SSL, and gives you a fully functional Kubernetes environment for development and small-scale production.

K3s vs Full Kubernetes

K3s kubeadm (full K8s)
Install time ~2 minutes 30–60 minutes
Binary size ~100 MB Multiple GB
RAM usage (idle) ~300–500 MB 1–2 GB+
etcd SQLite (default) or etcd etcd required
Kubernetes certified ✅ Yes ✅ Yes
ARM support ✅ Yes Partial
Best for VPS, edge, IoT, dev Large production clusters

K3s is 100% Kubernetes API compatible — every kubectl command, every Helm chart, and every YAML manifest works exactly as it would on a full cluster.

💡 VPS.DO Recommendation: K3s works on 2 GB RAM, but 4 GB gives comfortable headroom for running multiple workloads. VPS.DO’s USA VPS 500SSD (2 vCPU / 4 GB RAM) is a solid single-node K3s host. View Plans →


Step 1: Prepare Your VPS

sudo apt update && sudo apt upgrade -y

# Disable swap (Kubernetes requires this)
sudo swapoff -a
sudo sed -i '/ swap / s/^/#/' /etc/fstab

# Verify swap is off
free -h  # Swap should show 0

Step 2: Install K3s (Single-Node)

# Official one-line installer
curl -sfL https://get.k3s.io | sh -

That’s it. K3s installs, starts, and enables itself as a systemd service automatically.

# Verify K3s is running
sudo systemctl status k3s

# Check node status
sudo kubectl get nodes

You should see your node listed as Ready. ✅

Step 3: Configure kubectl Access

# Copy the kubeconfig to your user's home directory
mkdir -p ~/.kube
sudo cp /etc/rancher/k3s/k3s.yaml ~/.kube/config
sudo chown $USER:$USER ~/.kube/config

# Set KUBECONFIG environment variable
echo 'export KUBECONFIG=~/.kube/config' >> ~/.bashrc
source ~/.bashrc

# Now use kubectl without sudo
kubectl get nodes
kubectl get pods --all-namespaces

Access from your local machine

# On your VPS, get the kubeconfig
cat ~/.kube/config
# On your local machine, save the config and replace the server IP
mkdir -p ~/.kube
# Copy the content above to ~/.kube/config-vps
# Edit the server line: server: https://YOUR_VPS_IP:6443
export KUBECONFIG=~/.kube/config-vps
kubectl get nodes

Step 4: Deploy Your First Application

nano nginx-deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx-demo
  labels:
    app: nginx-demo
spec:
  replicas: 2
  selector:
    matchLabels:
      app: nginx-demo
  template:
    metadata:
      labels:
        app: nginx-demo
    spec:
      containers:
      - name: nginx
        image: nginx:latest
        ports:
        - containerPort: 80
        resources:
          requests:
            memory: "64Mi"
            cpu: "50m"
          limits:
            memory: "128Mi"
            cpu: "200m"
---
apiVersion: v1
kind: Service
metadata:
  name: nginx-demo-service
spec:
  selector:
    app: nginx-demo
  ports:
  - protocol: TCP
    port: 80
    targetPort: 80
  type: ClusterIP
kubectl apply -f nginx-deployment.yaml

# Watch pods start
kubectl get pods -w

# Check deployment status
kubectl get deployments
kubectl get services

Step 5: Configure Ingress with SSL (Traefik)

K3s ships with Traefik as the built-in Ingress controller. Configure it to route external traffic to your services with automatic Let’s Encrypt SSL.

Configure Traefik for Let’s Encrypt

sudo nano /var/lib/rancher/k3s/server/manifests/traefik-config.yaml
apiVersion: helm.cattle.io/v1
kind: HelmChartConfig
metadata:
  name: traefik
  namespace: kube-system
spec:
  valuesContent: |-
    globalArguments:
      - "--global.sendanonymoususage=false"
    additionalArguments:
      - "--certificatesresolvers.letsencrypt.acme.email=your@email.com"
      - "--certificatesresolvers.letsencrypt.acme.storage=/data/acme.json"
      - "--certificatesresolvers.letsencrypt.acme.tlschallenge=true"
    ports:
      web:
        redirectTo:
          port: websecure
      websecure:
        tls:
          certResolver: letsencrypt
# Restart K3s to apply Traefik config
sudo systemctl restart k3s
sleep 30
kubectl get pods -n kube-system | grep traefik

Create an Ingress resource

nano nginx-ingress.yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: nginx-ingress
  annotations:
    traefik.ingress.kubernetes.io/router.entrypoints: websecure
    traefik.ingress.kubernetes.io/router.tls.certresolver: letsencrypt
spec:
  rules:
  - host: app.yourdomain.com
    http:
      paths:
      - path: /
        pathType: Prefix
        backend:
          service:
            name: nginx-demo-service
            port:
              number: 80
  tls:
  - hosts:
    - app.yourdomain.com
kubectl apply -f nginx-ingress.yaml

# Check ingress
kubectl get ingress

Point your domain’s DNS A record to your VPS IP and wait for propagation. Your app will be accessible at https://app.yourdomain.com with automatic SSL. ✅


Step 6: Persistent Storage with Local Path Provisioner

K3s includes the Local Path Provisioner for PersistentVolumes backed by the VPS filesystem:

nano postgres-with-pv.yaml
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: postgres-pvc
spec:
  accessModes:
    - ReadWriteOnce
  storageClassName: local-path
  resources:
    requests:
      storage: 5Gi
---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: postgres
spec:
  replicas: 1
  selector:
    matchLabels:
      app: postgres
  template:
    metadata:
      labels:
        app: postgres
    spec:
      containers:
      - name: postgres
        image: postgres:16
        env:
        - name: POSTGRES_PASSWORD
          value: "SecurePass123!"
        - name: POSTGRES_DB
          value: "myapp"
        ports:
        - containerPort: 5432
        volumeMounts:
        - name: postgres-storage
          mountPath: /var/lib/postgresql/data
      volumes:
      - name: postgres-storage
        persistentVolumeClaim:
          claimName: postgres-pvc
kubectl apply -f postgres-with-pv.yaml
kubectl get pods,pvc

Step 7: Install Helm (Kubernetes Package Manager)

curl https://raw.githubusercontent.com/helm/helm/main/scripts/get-helm-3 | bash
helm version

Deploy applications with Helm

# Add popular repositories
helm repo add stable https://charts.helm.sh/stable
helm repo add bitnami https://charts.bitnami.com/bitnami
helm repo update

# Install WordPress with Helm
helm install my-wordpress bitnami/wordpress \
  --set wordpressUsername=admin \
  --set wordpressPassword=SecurePass123! \
  --set ingress.enabled=true \
  --set ingress.hostname=wp.yourdomain.com

Step 8: Multi-Node Cluster (Agent Nodes)

Add worker nodes to your cluster from additional VPS instances:

# On the server (master) VPS, get the node token
sudo cat /var/lib/rancher/k3s/server/node-token
# On each agent (worker) VPS:
curl -sfL https://get.k3s.io | K3S_URL=https://MASTER_VPS_IP:6443 \
  K3S_TOKEN=YOUR_NODE_TOKEN sh -
# Verify on master
kubectl get nodes
# Should now show multiple nodes

Essential kubectl Commands

Command Action
kubectl get pods -A List all pods across namespaces
kubectl describe pod POD_NAME Detailed pod info and events
kubectl logs POD_NAME -f Stream pod logs
kubectl exec -it POD_NAME -- bash Shell into a running pod
kubectl apply -f file.yaml Apply manifest
kubectl delete -f file.yaml Delete resources from manifest
kubectl scale deploy NAME --replicas=3 Scale a deployment
kubectl rollout restart deploy NAME Rolling restart

Final Thoughts

K3s makes Kubernetes accessible on a VPS without the complexity and resource overhead of a full cluster. For developers learning Kubernetes, teams running internal tools, or small-scale production workloads, K3s on a VPS.DO KVM VPS delivers a complete Kubernetes environment at minimal cost.

Related articles:

Fast • Reliable • Affordable VPS - DO It Now!

Get top VPS hosting with VPS.DO’s fast, low-cost plans. Try risk-free with our 7-day no-questions-asked refund and start today!