Fleet resource
The manifest consumed by
klimax fleet create -f and
klimax fleet delete -f. It's a Kubernetes-style resource:
apiVersion: klimax.dev/v1alpha1, kind: Fleet.
Every field below is optional except spec.clusters.
Full example
The annotated reference manifest — the same one shipped as
examples/fleet.yaml:
apiVersion: klimax.dev/v1alpha1
kind: Fleet
metadata:
name: dev-fleet
spec:
# Concurrent cluster creations. 0/1 = sequential (default). Independent
# clusters run in parallel up to this cap; dependsOn ordering is always honoured.
maxParallel: 2
# FailFast (default): stop scheduling new clusters after the first failure.
# ContinueOnError: keep creating independent clusters and report failures at the end.
strategy: FailFast
# Applied to every cluster below that does not set the field itself.
defaults:
registries:
mirrors: ["*"] # all mirrors from ~/.klimax/config.yaml
labels: # merged into every cluster (entry labels win on conflict)
owner: platform-team
# Every cluster always gets node labels: managed-by=klimax, plus
# klimax.dev/fleet=<metadata.name> and topology.kubernetes.io/region + zone.
clusters:
# A bare string is shorthand for "just create a cluster with this name".
- hub
# An object entry can override any per-cluster option.
- name: spoke-a
dependsOn: [hub] # created only after "hub" is ready
# num: 7 # pin the cluster num (1-99); omit to auto-assign a free slot
# nodeVersion: v1.35.0 # ⚠ overriding is unsupported; see 'klimax cluster create' warning
region: europe-west4
zone: europe-west4-b
registries:
mirrors: ["registry-dockerio", "registry-quayio"] # cherry-pick by name
labels: # extra node labels on this cluster's nodes
team: search
env: dev
addons:
metricsServer:
enabled: true
# version: v0.7.2 # omit for the latest release
# kubeletInsecureTLS: true # default true (required on kind)
- name: spoke-b
dependsOn: [hub]
registries:
mirrors: [] # no pull-through mirrors (pull straight from upstream)
Envelope
| Field | Type | Required | Value |
|---|---|---|---|
apiVersion | string | Yes | Must be exactly klimax.dev/v1alpha1. |
kind | string | Yes | Must be exactly Fleet. |
metadata | object | No | See metadata. |
spec | object | Yes | See spec. |
metadata
| Field | Type | Default | Description |
|---|---|---|---|
name | string | — | Optional fleet name. When set, every cluster's nodes get the label klimax.dev/fleet=<name>. Validated as a Kubernetes label value. |
spec
| Field | Type | Default | Description |
|---|---|---|---|
clusters | list | required | The fleet — at least one cluster entry. Each item is either a bare string (the name) or an object. |
maxParallel | int | 1 | Concurrent cluster creations. 0 or 1 = sequential. Independent clusters run up to this cap; dependsOn ordering is always respected. Must be ≥ 0. |
strategy | string | FailFast | FailFast stops scheduling after the first failure; ContinueOnError keeps going and reports failures at the end. |
defaults | object | {} | Field values inherited by every cluster entry that doesn't set them. See defaults. |
spec.defaults
Every field here is also a per-cluster field; a value set on a cluster entry wins over the default.
| Field | Type | Default | Description |
|---|---|---|---|
nodeVersion | string | config default | kindest/node image tag (e.g. v1.35.0). ⚠ Overriding away from the version the bundled kind CLI is validated against is unsupported. |
region | string | europe-west<num> | Default topology.kubernetes.io/region node label. |
zone | string | europe-west<num>-b | Default topology.kubernetes.io/zone node label. |
registries | object | all mirrors | Default registry selection. See registries. |
addons | object | none | Default addons. See addons. |
labels | map | {} | Default node labels, merged into every cluster (per-cluster labels win on key conflicts). |
spec.clusters[] — cluster entry
A bare string (- dev) is shorthand for an object with only
name set. Object form:
| Field | Type | Default | Description |
|---|---|---|---|
name | string | required | Cluster name — the kubeconfig context and container-name suffix. Unique within the fleet; matches ^[a-z0-9]([a-z0-9.-]*[a-z0-9])?$. |
dependsOn | list<string> | [] | Names of clusters that must finish before this one starts. Must reference clusters in the manifest; the graph must be acyclic. |
num | int | 0 (auto) | Explicit cluster number (1–99) driving subnet, API port, and MetalLB pool. 0 auto-assigns the lowest free slot. No two entries may request the same num. |
nodeVersion | string | from defaults | Per-cluster kindest/node tag override. |
region | string | from defaults | Per-cluster region label. |
zone | string | from defaults | Per-cluster zone label. |
registries | object | from defaults | Per-cluster registry selection. See registries. |
addons | object | from defaults | Per-cluster addons. See addons. |
labels | map | {} | Extra node labels for this cluster, merged over defaults.labels. |
registries
Valid under spec.defaults and per cluster.
| Field | Type | Default | Description |
|---|---|---|---|
mirrors | list<string> | all | Which pull-through mirrors to wire up, by name from ~/.klimax/config.yaml. Omit or ["*"] = all configured mirrors; [] = none; a list = exactly those. Unknown names fail validation early. |
addons
Valid under spec.defaults and per cluster. Currently one
addon:
| Field | Type | Default | Description |
|---|---|---|---|
metricsServer.enabled | bool | false | Install metrics-server into the cluster. |
metricsServer.version | string | latest | metrics-server release tag (e.g. v0.7.2); empty = latest. |
metricsServer.kubeletInsecureTLS | bool | true | Add --kubelet-insecure-tls (required on kind's self-signed kubelet). |
Node labels
Every cluster klimax creates has its nodes labelled with
kubectl label nodes --all after creation; topology labels are
set even earlier, at node registration. See
Fleet management → Node labels
for how to set custom ones.
| Label | Source | Applies to |
|---|---|---|
managed-by=klimax | Always | Every klimax cluster |
klimax.dev/fleet=<name> | metadata.name | Fleets with a name |
topology.kubernetes.io/region | region / default | Every cluster |
topology.kubernetes.io/zone | zone / default | Every cluster |
ingress-ready=true | kind default | Every cluster |
| your keys | labels / -l | Where specified |
Validation
The whole manifest is validated before any cluster is created —
--dry-run runs the same checks. A manifest is rejected when:
apiVersion≠klimax.dev/v1alpha1orkind≠Fleet.strategyis not"",FailFast, orContinueOnError.maxParallel< 0, orspec.clustersis empty.- A cluster
nameis missing, duplicated, or not a valid DNS-style name. - A
numis outside 1–99, or two clusters request the same explicit num. - A
dependsOnentry names a cluster not in the manifest, or a cluster depends on itself. - The dependency graph contains a cycle.
- A selected mirror name isn't defined in
~/.klimax/config.yaml, or a label key/value isn't a valid Kubernetes label.
See also
- Fleet management — the how-to guide with worked examples.
- CLI reference — Clusters —
applyanddelete -fflags. - Configuration — the mirrors and defaults a fleet draws on.