Documentation menu

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

FieldTypeRequiredValue
apiVersionstringYesMust be exactly klimax.dev/v1alpha1.
kindstringYesMust be exactly Fleet.
metadataobjectNoSee metadata.
specobjectYesSee spec.

metadata

FieldTypeDefaultDescription
namestringOptional fleet name. When set, every cluster's nodes get the label klimax.dev/fleet=<name>. Validated as a Kubernetes label value.

spec

FieldTypeDefaultDescription
clusterslistrequiredThe fleet — at least one cluster entry. Each item is either a bare string (the name) or an object.
maxParallelint1Concurrent cluster creations. 0 or 1 = sequential. Independent clusters run up to this cap; dependsOn ordering is always respected. Must be ≥ 0.
strategystringFailFastFailFast stops scheduling after the first failure; ContinueOnError keeps going and reports failures at the end.
defaultsobject{}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.

FieldTypeDefaultDescription
nodeVersionstringconfig defaultkindest/node image tag (e.g. v1.35.0). ⚠ Overriding away from the version the bundled kind CLI is validated against is unsupported.
regionstringeurope-west<num>Default topology.kubernetes.io/region node label.
zonestringeurope-west<num>-bDefault topology.kubernetes.io/zone node label.
registriesobjectall mirrorsDefault registry selection. See registries.
addonsobjectnoneDefault addons. See addons.
labelsmap{}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:

FieldTypeDefaultDescription
namestringrequiredCluster name — the kubeconfig context and container-name suffix. Unique within the fleet; matches ^[a-z0-9]([a-z0-9.-]*[a-z0-9])?$.
dependsOnlist<string>[]Names of clusters that must finish before this one starts. Must reference clusters in the manifest; the graph must be acyclic.
numint0 (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.
nodeVersionstringfrom defaultsPer-cluster kindest/node tag override.
regionstringfrom defaultsPer-cluster region label.
zonestringfrom defaultsPer-cluster zone label.
registriesobjectfrom defaultsPer-cluster registry selection. See registries.
addonsobjectfrom defaultsPer-cluster addons. See addons.
labelsmap{}Extra node labels for this cluster, merged over defaults.labels.

registries

Valid under spec.defaults and per cluster.

FieldTypeDefaultDescription
mirrorslist<string>allWhich 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:

FieldTypeDefaultDescription
metricsServer.enabledboolfalseInstall metrics-server into the cluster.
metricsServer.versionstringlatestmetrics-server release tag (e.g. v0.7.2); empty = latest.
metricsServer.kubeletInsecureTLSbooltrueAdd --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.

LabelSourceApplies to
managed-by=klimaxAlwaysEvery klimax cluster
klimax.dev/fleet=<name>metadata.nameFleets with a name
topology.kubernetes.io/regionregion / defaultEvery cluster
topology.kubernetes.io/zonezone / defaultEvery cluster
ingress-ready=truekind defaultEvery cluster
your keyslabels / -lWhere specified

Validation

The whole manifest is validated before any cluster is created — --dry-run runs the same checks. A manifest is rejected when:

  • apiVersionklimax.dev/v1alpha1 or kindFleet.
  • strategy is not "", FailFast, or ContinueOnError.
  • maxParallel < 0, or spec.clusters is empty.
  • A cluster name is missing, duplicated, or not a valid DNS-style name.
  • A num is outside 1–99, or two clusters request the same explicit num.
  • A dependsOn entry 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