k3s-server
Recipe card from the charly-infrastructure plugin (Images — the deployable catalog).
k3s-server – k3s control-plane node
Section titled “k3s-server – k3s control-plane node”Candy Properties
Section titled “Candy Properties”| Property | Value |
|---|---|
| Install files | charly.yml, task:, service:, artifact:, secret_require: |
| Depends on | /charly-infrastructure:k3s |
| Service | k3s.service (system scope, enabled) |
What this candy does
Section titled “What this candy does”- Reads
K3S_CLUSTER_TOKENfrom the credential store (secret_require:). - Writes
/etc/rancher/k3s/config.yamlwith:token:— the pre-shared cluster tokenwrite-kubeconfig-mode: "0644"— so the operator can scp the kubeconfig backtls-san:—${K3S_SERVER_HOSTNAME}(orhostname -nfallback)disable: []— explicitly empty, so ServiceLB, Traefik v2, and local-path-provisioner all install as default k3s addons.
- Emits
/etc/systemd/system/k3s.servicerunningk3s server. - After setup, the runtime publishes
/etc/rancher/k3s/k3s.yamlback to the operator via the newartifact:candy-schema feature. The retrieved file lands at~/.cache/charly/clusters/<deploy_name>/kubeconfig.yamlwith127.0.0.1rewritten to${K3S_SERVER_HOSTNAME}so the operator cankubectlthe cluster from their machine. - The
K3sPostProvisionhook (Go, runs after artifact retricheck) merges the kubeconfig into~/.kube/configunder context<deploy_name>and writes a matching ClusterProfile to~/.config/charly/clusters/<deploy_name>.yamlwithingress.class=traefikandstorage.class_default=local-path.
Operator setup — none required (auto-generated)
Section titled “Operator setup — none required (auto-generated)”K3S_CLUSTER_TOKEN auto-generates on first deploy. The resolver
(charly/layer_secrets.go — ensureCandySecret) detects the missing
secret_require: entry, generates a 32-byte hex token via
generateAndStoreSecret, and persists it to the active credential
backend (keyring / config-file fallback). Every subsequent
k3s-server and k3s-agent deploy reads the same persisted value —
zero operator setup, server and agents automatically share the token.
Override with a specific value (uncommon — only when reproducing a specific cluster identity, e.g., disaster recovery):
charly secrets set charly/secret/K3S_CLUSTER_TOKEN $(openssl rand -hex 32)Retrieve the auto-generated token (for debugging or out-of-band agent join):
charly secrets get charly/secret K3S_CLUSTER_TOKEN# The VM hardware template (a kind: vm entity — name-first node form).k3s-srv-vm: vm: source: { kind: cloud_image, url: "…" } ram: 4G cpu: 2
# The disposable deploy: overlay the k3s-server candy into the VM. `from:`# selects the template; disposable / add_candy / env live on the deploy node.k3s-srv: vm: from: k3s-srv-vm disposable: true add_candy: [k3s-server] env: K3S_SERVER_HOSTNAME: k3s-srv.lan # optional but recommendedcharly vm create k3s-srvcharly bundle add vm:k3s-srv# → kubeconfig auto-retrieved + ClusterProfile writtenkubectl --context k3s-srv get nodes# addon health is asserted by the candy's declarative `kube: addons` check step# (served out-of-process by candy/plugin-kube — see Deploy-scope below); there is# no host `charly check kube` command.Build-scope:
/etc/rancher/k3s/config.yamlexists, mode 0600./etc/systemd/system/k3s.serviceexists.
Deploy-scope (using the declarative kube: check verb — see /charly-kubernetes:check-k8s).
The cluster-probe verb is the declarative kube: check verb (served out-of-process by
candy/plugin-kube — there is no host charly check kube command); the k8s spelling is
reserved for the deploy KIND only:
kube: wait-nodes— at least 1 node Ready.kube: ingressclass—traefikpresent.kube: storageclass—local-pathpresent.kube: addons— Traefik + ServiceLB + local-path-provisioner all Ready.
Related Candies
Section titled “Related Candies”/charly-infrastructure:k3s— Base candy installing the k3s binary (required dep)/charly-infrastructure:k3s-agent— Worker nodes joining this server/charly-coder:kubernetes-layer—kubectl/helmon the operator side (not needed in the cluster)/charly-kubernetes:check-k8s— The test verb used by this candy’s deploy-scope checks