← All TILs · kubernetes

Installing a single-node RKE2 server for a lab

kubernetes - 2026-09-18

Third entry in the RKE2/Kubernetes series. A lab needs the minimum viable cluster: one machine running rke2-server, which acts as both control plane and worker — no separate node to join, no agent install at all for this size.

The install script, and one default worth knowing

curl -sfL https://get.rke2.io | sh -

Per the install script's own source, two defaults matter if you don't set anything: INSTALL_RKE2_TYPE defaults to server (an agent install — a worker joining an existing cluster — is a different, later step, not something a lab node needs), and INSTALL_RKE2_CHANNEL defaults to stable, not latest. If you actually want the newest release rather than the last one that's been out long enough to be called stable, that's INSTALL_RKE2_CHANNEL=latest sh -s - explicitly — the plain command doesn't give you it by default.

Enable it, then start it

systemctl enable rke2-server.service
systemctl start rke2-server.service

Two separate commands because enable and start do different things: enable makes it come back on the next boot, start makes it run now. Per RKE2's own quickstart docs, the service is also configured to restart itself automatically after a crash or a kill — the same systemd behavior the earlier node-maintenance TIL relies on to bring a node back up after a reboot without a manual step.

Where everything actually lands

Worth setting in config.yaml before the first start

# /etc/rancher/rke2/config.yaml
write-kubeconfig-mode: "0644"

The generated kubeconfig at /etc/rancher/rke2/rke2.yaml is root-owned and root-only by default — it embeds full cluster-admin credentials, so that's a sensible default, not an oversight. But it also means kubectl fails with a permissions error the moment you try it as your own user. write-kubeconfig-mode (confirmed as a real, current flag in RKE2's own server command source) is the config-file way to loosen that from install time, rather than hand-editing the file's permissions after every regeneration.

Where this series goes next

This gets a node running; it doesn't get kubectl pointed at it from anywhere but the node itself. The next entry covers why — the generated kubeconfig's server URL points at 127.0.0.1, which works fine logged into the node directly and breaks the moment you copy that file to your own workstation.

Created 2026-09-18T01:20:46+02:00 · Edit