#cloud-config hostname: ${hostname} manage_etc_hosts: true users: - name: k3s groups: sudo shell: /bin/bash sudo: ALL=(ALL) NOPASSWD:ALL ssh_authorized_keys: - ${ssh_public_key} package_update: true packages: - curl # k3s reads /etc/rancher/k3s/config.yaml automatically on install — this # is the file, not command-line flags, specifically so the token never # shows up in `ps`/process listings or shell history on the node, and # `runcmd` below can stay a one-liner with no secrets in it. 0600 so only # root can read it. write_files: - path: /etc/rancher/k3s/config.yaml permissions: '0600' content: | token: "${k3s_token}" # Every hostname a client might use to reach this server needs to be # in the API server's TLS certificate up front, or that client's TLS # handshake fails outright — it can't be added after the fact # without regenerating the cert. `${hostname}` covers this node's # own name; `${k8s_api_hostname}` is the LAN-only name # docs/04-tofu.md step 5 sets up for kubectl access from elsewhere on # the network — both need to be here even though nothing uses the # second one yet at boot time. tls-san: - "${hostname}" - "${k8s_api_hostname}" runcmd: - curl -sfL https://get.k3s.io | sh -s - server # k3s's own kubeconfig is generated readable only by root (it grants # full cluster-admin access) — this copies it somewhere the unprivileged # `k3s` user can read, so docs/04-tofu.md step 3 can fetch it over SSH # without needing root on the node. - mkdir -p /home/k3s/.kube - k3s kubectl config view --raw > /home/k3s/.kube/config - chown -R k3s:k3s /home/k3s/.kube