Skip to content

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

3 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

clusterctl

clusterctl provisions and manages Talos Linux Kubernetes clusters on OpenStack from a single declarative file. You describe the cluster you want in cluster.yaml; clusterctl converge makes reality match it — create, scale up, scale down (drain first), and rolling Talos/Kubernetes upgrades are all the same command. Re-running is always safe.

There is no state file. Every resource is named deterministically and tagged (managed-by=clusterctl, cluster=<name>); converge discovers what exists by tag, creates what's missing, and never touches resources it didn't create.

Install

Requires talosctl and kubectl on PATH. With uv nothing else is needed:

uv tool install git+https://github.com/ncsa/clusterctl   # install
uv tool upgrade clusterctl                                # update

Or run it without installing:

uvx --from git+https://github.com/ncsa/clusterctl clusterctl --help

From a checkout of this repo: uv run clusterctl --help, or with pip: python3 -m venv .venv && . .venv/bin/activate && pip install -e .

Quick start

clusterctl init mycluster   # scaffold cluster.yaml, secrets.yaml, .gitignore
vi secrets.yaml             # openstack application credential + tailscale key
vi cluster.yaml             # versions, pools, openstack endpoint, allowlists
clusterctl plan             # dry-run: print every action, change nothing
clusterctl converge         # build the cluster

The machine running clusterctl must be on the tailnet — the initial bootstrap reaches the first controlplane node by its tailscale name.

Commands

command what it does
init [NAME] scaffold cluster.yaml / secrets.yaml / .gitignore; never overwrites existing files
plan dry-run converge: print every create/update/delete
converge make the cluster match cluster.yaml (phases: image → secrets → network/SG → discover → scale-down → upgrade → compute → bootstrap → kubeconfig → health)
status list managed OpenStack resources + kubectl get nodes
dashboard [NODE...] talosctl dashboard on all (reachable) nodes, or just the ones given
env print export OS_* lines for the openstack CLI: eval "$(clusterctl env)"
image download|remove build/upload the Glance boot image, or delete it (converge never deletes it)
destroy delete every managed resource + local state; the shared boot image is kept

Options: every command takes -C DIR to operate on another cluster directory. converge, image and destroy take --dry-run (print, don't do) and --yes (skip the confirmation that any deletion otherwise requires).

Typical cluster.yaml edits and what converge does with them: bump a pool count to add nodes; lower it to drain + remove them; bump talos.version or kubernetes.version for a rolling upgrade (existing nodes are upgraded before new ones are added); edit a security allowlist to reconcile the security-group rules.

The three files

  1. cluster.yaml — desired state: versions, node pools, network, allowlists, extensions. Committable, but note the security allowlists reveal which source addresses may reach your APIs.
  2. secrets.yaml — OpenStack application credential + tailscale pre-auth key. Gitignored; restorable by reissuing credentials.
  3. talossecrets.yaml⚠️ the cluster's cryptographic identity (cluster CA, etcd CA, join tokens). Generated on the first converge, gitignored, mode 0600. It cannot be regenerated for a running cluster — back it up out-of-band like a private CA key. destroy deletes it on purpose, so the next converge starts a brand-new cluster.

(talosconfig and kubeconfig are derived from these and regenerated by converge; safe to delete.)

Versions & upgrades

cluster.yaml pins both versions; nothing auto-upgrades. Find targets with:

curl -s https://api.github.com/repos/siderolabs/talos/releases/latest | jq -r .tag_name
talosctl gen config --help | grep kubernetes-version   # k8s pairing Talos tested

Two rules: upgrade Kubernetes one minor at a time, and bump Talos before Kubernetes when moving both (converge already orders it that way within a run). Bumping talos.version builds a new ~1 GB boot image via factory.talos.dev on the next converge.

Extensions

Every node boots from one shared image per Talos version (talos-<version>-tailscale, baked with tailscale + qemu-guest-agent). Tailscale only authenticates if a key is present in secrets.yaml. Extra extensions (e.g. nvidia for a GPU pool) and freeform machine-config patches go in cluster.yaml, cluster-wide under talos: or per worker pool:

workers:
  gpu:
    count: 2
    flavor: gpu.a100
    disk: 100
    extensions:
      - siderolabs/nonfree-kmod-nvidia
      - siderolabs/nvidia-container-toolkit
    config_patches:
      - |
        machine:
          sysctls: {...}

Extra extensions take effect on the node's first upgrade pass (on OpenStack the boot image is the first-boot system; the factory installer image applies on talosctl upgrade), which converge handles automatically.

About

Script to create a talos cluster in openstack. Uses tailscale to be able to reach all nodes.

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages