Housekeeping
Basic housekeeping tasks to perform on each node before installing k3s. These apply after the Raspberry Pi prerequisites are complete.
Change passwords
The default pi user password must be changed before the node is connected to the network. Also change the root password:
passwd
passwd root
System update
Bring the system fully up to date before installing anything:
sudo apt update && sudo apt upgrade -y
Reboot after the upgrade if the kernel was updated:
sudo reboot
Install useful tools
A few tools are useful throughout the setup process:
sudo apt install -y curl jq nano
curl— used for downloading manifests and testing endpointsjq— used to parse JSON output (e.g. when fetching kube-vip release versions)nano— for editing config files on the node
Set the hostname
Give each node a meaningful hostname that matches its role. This makes it easier to identify nodes in kubectl get nodes output:
sudo hostnamectl set-hostname rpi-1
Repeat on each node with an appropriate name (rpi-1, rpi-2, etc.).
Update /etc/hosts on each node to include all other nodes:
sudo nano /etc/hosts
Add entries such as:
192.168.1.11 rpi-1
192.168.1.12 rpi-2
Verify time sync
k3s is sensitive to clock drift between nodes. Confirm NTP is running:
timedatectl status
System clock synchronized: yes and NTP service: active should both be present.
Make the journal persistent
Raspberry Pi OS ships /usr/lib/systemd/journald.conf.d/40-rpi-volatile-storage.conf, which forces Storage=volatile: the journal lives in /run/log/journal (RAM, capped at about 10% of RAM), rotates away after a few weeks, and is lost on every reboot. On a node whose disk fails that means the evidence of the failure dies with the reboot that recovers it. The /var/log/journal directory alone does not help, because the vendor drop-in still wins.
Override it with a drop-in that sorts after the vendor file (the zz- prefix matters), and sync to disk every 30 seconds instead of the 5-minute default so the last minutes before a crash usually survive:
sudo mkdir -p /etc/systemd/journald.conf.d /var/log/journal
sudo tee /etc/systemd/journald.conf.d/zz-persistent.conf >/dev/null <<'EOF'
[Journal]
Storage=persistent
SyncIntervalSec=30s
EOF
sudo systemd-tmpfiles --create --prefix /var/log/journal
sudo systemctl restart systemd-journald
sudo journalctl --flush
Verify that the active journal file is under /var/log/journal and that the persistent setting is the last Storage= line in the effective configuration:
journalctl --header | grep -m1 'File path'
systemd-analyze cat-config systemd/journald.conf | grep -E '^Storage='
journalctl --list-boots
journalctl --list-boots grows a line per boot from now on. Disk use stays bounded by journald's default cap (10% of the filesystem, at most 4 GiB).