k3s Setup¶
Overview¶
Installs a single-node k3s cluster on the VPS. k3s bundles containerd, CoreDNS, Traefik, ServiceLB, metrics-server, and the local-path storage provisioner, which is a good baseline for a small GitOps cluster.
Prerequisites¶
- VPS hardening is complete
- At least 2 vCPU, 4 GB RAM, and 30 GB free disk
- Ports
80and443are reachable; restrict6443to a trusted IP if remotekubectlis required
Procedure¶
1. Install k3s¶
Pin a tested release in production instead of following the newest release implicitly:
curl -sfL https://get.k3s.io | INSTALL_K3S_CHANNEL=stable sh -
sudo systemctl status k3s --no-pager
Keep bundled Traefik. Do not install ingress-nginx unless Traefik is disabled at install time; two ingress controllers make routing and ports harder to reason about.
2. Configure kubectl for the administrative user¶
mkdir -p ~/.kube
sudo cp /etc/rancher/k3s/k3s.yaml ~/.kube/config
sudo chown "$USER:$USER" ~/.kube/config
chmod 600 ~/.kube/config
For remote access, copy this file to the local machine and replace 127.0.0.1 with the VPS IP. Treat it as a secret because it contains cluster-admin credentials.
3. Handle UFW¶
k3s networking creates rules outside UFW. On a single node, keep public inbound access limited to SSH and HTTP(S), and allow the API only from the operator IP:
sudo ufw delete allow 6443/tcp
sudo ufw allow from <ADMIN_PUBLIC_IP> to any port 6443 proto tcp
Multi-node clusters require additional node-to-node rules and are outside this guide.
Verification¶
kubectl get nodes -o wide
kubectl get pods -A
kubectl get storageclass
Expected: one Ready node, system pods running, and local-path marked as the default StorageClass.
Operations¶
sudo journalctl -u k3s -f
sudo systemctl restart k3s
Back up /var/lib/rancher/k3s/server/token and application data. A local-path PersistentVolume is not a backup and is lost with the VPS disk.