infrastructure/skills/k3s-agent/SKILL.md
k3s worker (agent) node — joins an existing k3s-server via pre-shared token. Fully declarative: same charly secrets set once + env K3S_SERVER_URL per agent deploy.
npx skillsauth add overthinkos/overthink-plugins k3s-agentInstall this skill globally with one command. Works with Claude Code, Cursor, and Windsurf.
3 of 9 scanners reported clean
Some scanners were skipped, did not run, or reported a non-clean status. Review each row below.
| Property | Value |
|----------|-------|
| Install files | charly.yml, task:, service:, secret_require:, env_require: |
| Depends on | /charly-infrastructure:k3s |
| Service | k3s-agent.service (system scope, enabled) |
K3S_CLUSTER_TOKEN from the credential store (same secret the
server consumes — auto-generated on the first server-or-agent
deploy via ensureCandySecret; subsequent deploys read the
persisted value, so agents and server automatically share the
token without operator setup).K3S_SERVER_URL from charly.yml env (e.g.,
https://k3s-srv.lan:6443)./etc/rancher/k3s/config.yaml with server: and token:./etc/systemd/system/k3s-agent.service running k3s agent.No join-token handoff, no kubeconfig retricheck — agents only need the server URL (declarative, known at author time) and the pre-shared token (from the credential store).
# charly.yml (assumes k3s-srv already up; see /charly-infrastructure:k3s-server)
vm:
k3s-ag1:
source: { kind: cloud_image, url: "…" }
disposable: true
ram: 4G
cpus: 2
deployments:
box:
"vm:k3s-ag1":
target: vm
vm_source: k3s-ag1
add_candy: [k3s-agent]
env:
- K3S_SERVER_URL=https://k3s-srv.lan:6443
# K3S_CLUSTER fed in for the agent-joined test below — must
# match the cluster profile name registered by the server.
- K3S_CLUSTER=k3s-srv
charly bundle add vm:k3s-ag1
The agent registers; a server-side kube: wait-nodes check step confirms the
join — the declarative kube: verb served out-of-process by candy/plugin-kube
(there is no host charly check kube command):
confirm-join:
check: both nodes reach Ready once the agent joins
kube: wait-nodes
cluster: k3s-srv
kube_count: 2
timeout: 3m
context: [deploy]
Build-scope:
/etc/rancher/k3s/config.yaml exists, mode 0600./etc/systemd/system/k3s-agent.service exists.Deploy-scope (uses /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 name=${HOSTNAME} — this node reaches Ready on the
server./charly-infrastructure:k3s — Base candy installing the k3s binary (required dep)/charly-infrastructure:k3s-server — Control-plane node this agent joins/charly-kubernetes:check-k8s — Test verb used by the agent-joined checktools
Use when authoring or modifying a charly PLUGIN — a candy with a `plugin:` block that contributes Providers (verbs/kinds/deploy-targets/steps/builders/commands), its own CUE schema, builtin (compiled-in) or external (out-of-tree git repo). Covers the unified Provider model, the per-plugin CUE-schema contract (single source → Go params for dev + schema-over-Describe RPC for runtime), the SDK, and the loader.
tools
The CUE data-validation / configuration CLI (cue), pinned to v0.16.1. Use when working with the cue candy, installing the cue binary into a box or onto a target:local dev host, or running the offline schema-vendoring pipeline that feeds charly's egress validation.
tools
CUE EGRESS validation — validating (and, where it adds value, generating) the config files charly WRITES to a system BEFORE the bytes hit disk. MUST be invoked before working on charly/egress.go, the vendored schemas under candy/plugin-egress/egress-schemas/vendor/, the ValidateEgress / registerVendoredEgressKind path, the offline `task cue:vendor` pipeline, or adding an egress schema for any written artifact (cloud-init, k8s manifests, traefik routes, runtime config, install ledger, systemd/quadlet units, ssh_config, libvirt XML).
tools
Kubernetes cluster-probe declarative check verb — the `kube:` check verb (nodes, pods, ingress, storage class, addon health, apply/delete, and arbitrary resource GETs) served out-of-process by the candy/plugin-kube plugin (vendored client-go; no external kubectl required).