ov-foundation/skills/k3s-server/SKILL.md
k3s control-plane (server) node with ServiceLB, Traefik v2, and local-path-provisioner enabled by default. Publishes kubeconfig back to the operator via layer artifacts and registers a ClusterProfile on first boot.
npx skillsauth add overthinkos/overthink-plugins k3s-serverInstall 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 | layer.yml, tasks:, service:, artifacts:, secret_requires: |
| Depends on | /ov-foundation:k3s |
| Service | k3s.service (system scope, enabled) |
K3S_CLUSTER_TOKEN from the credential store (secret_requires:)./etc/rancher/k3s/config.yaml with:
token: — the pre-shared cluster tokenwrite-kubeconfig-mode: "0644" — so the operator can scp the kubeconfig backtls-san: — ${K3S_SERVER_HOSTNAME} (or hostname -n fallback)disable: [] — explicitly empty, so ServiceLB, Traefik v2, and
local-path-provisioner all install as default k3s addons./etc/systemd/system/k3s.service running k3s server./etc/rancher/k3s/k3s.yaml back to
the operator via the new artifacts: layer-schema feature. The
retrieved file lands at ~/.cache/ov/clusters/<deploy_name>/kubeconfig.yaml
with 127.0.0.1 rewritten to ${K3S_SERVER_HOSTNAME} so the operator
can kubectl the cluster from their machine.K3sPostProvision hook (Go, runs after artifact retrieval)
merges the kubeconfig into ~/.kube/config under context
<deploy_name> and writes a matching ClusterProfile to
~/.config/ov/clusters/<deploy_name>.yaml with ingress.class=traefik
and storage.class_default=local-path.K3S_CLUSTER_TOKEN auto-generates on first deploy. The resolver
(ov/layer_secrets.go — ensureLayerSecret) detects the missing
secret_requires: entry, generates a 32-byte hex token via
generateAndStoreSecret, and persists it to the active credential
backend (keyring / kdbx / 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):
ov secrets set ov/secret/K3S_CLUSTER_TOKEN $(openssl rand -hex 32)
Retrieve the auto-generated token (for debugging or out-of-band agent join):
ov secrets get ov/secret K3S_CLUSTER_TOKEN
# overthink.yml
vm:
k3s-srv:
source: { kind: cloud_image, url: "…" }
disposable: true
ram: 4G
cpus: 2
deployments:
images:
"vm:k3s-srv":
target: vm
vm_source: k3s-srv
add_layers: [k3s-server]
env:
- K3S_SERVER_HOSTNAME=k3s-srv.lan # optional but recommended
ov vm create k3s-srv
ov deploy add vm:k3s-srv
# → kubeconfig auto-retrieved + ClusterProfile written
kubectl --context k3s-srv get nodes
ov eval k8s addons --cluster k3s-srv
Build-scope:
/etc/rancher/k3s/config.yaml exists, mode 0600./etc/systemd/system/k3s.service exists.Deploy-scope (using the new ov eval k8s verb — see /ov-advanced:eval-k8s):
k8s: wait-nodes — at least 1 node Ready.k8s: ingressclass — traefik present.k8s: storageclass — local-path present.k8s: addons — Traefik + ServiceLB + local-path-provisioner all Ready./ov-foundation:k3s — Base layer installing the k3s binary (required dep)/ov-foundation:k3s-agent — Worker nodes joining this server/ov-coder:kubernetes-layer — kubectl/helm on the operator side (not needed in the cluster)/ov-advanced:eval-k8s — The test verb used by this layer's deploy-scope checkstools
OpenCharly CLI (charly) binary installed into container/VM images for in-container use. Use when working with charly binary deployment inside containers, native D-Bus support, or the full charly toolchain (charly binary + virtualization + gocryptfs + socat).
development
Operator CachyOS workstation profile — a kind:local template + target:local deploy that installs the full dev stack (30 candies) onto a CachyOS host via ShellExecutor. Lives in the overthinkos/cachyos submodule. MUST be invoked before editing or applying the charly-cachyos workstation profile.
tools
Fedora box with the full charly toolchain using shared candies. Rootless-first — runs as uid=1000 with passwordless sudo (no root, no cap_add: ALL). Same candy list as charly-arch. Includes NVIDIA GPU runtime. MUST be invoked before building, deploying, configuring, or troubleshooting the charly-fedora box.
tools
Arch Linux box with the full charly toolchain. Rootless-first — runs as uid=1000 with passwordless sudo (no root, no cap_add: ALL). Composes /charly-coder:charly-mcp so the box is reachable as an MCP gateway on port 18765. NVIDIA GPU runtime composed in. MUST be invoked before building, deploying, configuring, or troubleshooting the charly-arch box.