K3s Homelab: Adding a Worker Node and Backing Up etcd
Scale your k3s cluster to two nodes, pick a datastore, and set up a cron-based backup you can actually restore from.
In part 1 we got a single-node cluster running. Now we add a worker and make the control plane survivable.
Joining a worker node
On the server, read the node token:
cat /var/lib/rancher/k3s/server/node-token
On the worker, install with the server URL and that token:
curl -sfL https://get.k3s.io | K3S_URL=https://SERVER_IP:6443 \
K3S_TOKEN=<node-token> sh -
Back on the server:
kubectl get nodes
Two nodes now. The worker shows ROLES empty — that’s expected, it’s an agent.
Picking a datastore
k3s defaults to SQLite for a single server, and etcd (embedded) when you pass
--cluster-init. For a homelab with one server and N workers, SQLite is fine.
The moment you add a second server, switch to embedded etcd:
curl -sfL https://get.k3s.io | INSTALL_K3S_EXEC="--cluster-init" sh -
Backups
Embedded etcd means you can snapshot the whole cluster state to one file:
k3s etcd-snapshot save --name homelab-$(date +%F)
Snapshots land in /var/lib/rancher/k3s/server/db/snapshots. Put it on cron:
0 3 * * * /usr/local/bin/k3s etcd-snapshot save --name auto
And copy the latest snapshot somewhere off-box (S3, a NAS, even a git repo with LFS). A backup that lives on the machine it’s backing up is not a backup.
Restore
k3s server --cluster-reset --cluster-reset-restore-path=/path/to/snapshot.db
--cluster-reset is destructive: it wipes local etcd and boots fresh from the
snapshot. Use it on a stopped cluster, then restart k3s.
Wrap-up
You now have a two-node cluster with a real backup strategy. In part 3 we’ll wire up the Traefik ingress that ships with k3s and terminate TLS with a real certificate.