MK
·2 min read · K3s Series

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.

K3s logo on a dark gradient background

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.

Related posts

Comments

Giscus is not configured. Set the PUBLIC_GISCUS_* env vars (see .env.example) to enable GitHub Discussions comments.