Skip to content

kMetal Installation

This guide covers the installation of kMetal on a prepared under cluster.

Prerequisites

  • Under cluster — see Under Cluster Setup.
  • Registry credentials for ghcr.io/clastix (Clastix-supplied).
  • Reserved IP ranges for the tenant control-plane and management address pools.

Step 1: Log in to the OCI registry

helm registry login ghcr.io -u <username> -p <token>

Step 2: Create the registry pull secret

The chart pulls images from a private registry. Create a pull secret in the namespace the chart will install into:

kubectl create namespace kmetal-operator-system

kubectl create secret docker-registry clastix-ghcr \
  --docker-server=ghcr.io \
  --docker-username=<username> \
  --docker-password=<token> \
  --namespace=kmetal-operator-system

Similarly, an OCI token as secret must be created in the same namespace.

kubectl create secret generic clastix-ghcr-oci \
  --from-literal=OCI_USERNAME=<username> \
  --from-literal=OCI_PASSWORD=<token> \
  --namespace=kmetal-operator-system

Step 3: Prepare the values

The chart carries the KMetal spec verbatim under kmetal.spec, and that spec is the platform's definition: the overlay interface and its central nodes, the provider networks tenants egress through, the service CIDR, the address pools, and the StorageClasses kMetal consumes.

Two ready-to-adapt shapes — one lab, one production — are in Configuration Templates. Every field, with its defaults and constraints, is in Platform Configuration Reference, and Configuration Best Practices covers what to settle before the first install.

Leaving kmetal.spec empty installs the operator alone, with nothing to reconcile — the right shape when the platform is described in a GitOps tree and applied separately.

Step 4: Install the chart

helm install kmetal-operator oci://ghcr.io/clastix/charts/kmetal-operator \
  --namespace kmetal-operator-system \
  --values values.yaml \
  --wait \
  --timeout=15m

Verify the release status:

helm status kmetal-operator -n kmetal-operator-system

Step 5: Monitor installation

The chart installs the operator; the operator installs the platform. Progress is therefore read off the KMetal object rather than by hunting for pods:

# Overall: the release reconciled, Flux's version, and the Ready condition
kubectl get km

# Per component, in install order
kubectl get km kmetal -o jsonpath='{range .status.components[*]}{.name}{"\t"}{.phase}{"\t"}{.message}{"\n"}{end}'

The reconciler walks the install order front to back and halts at the first component that is not Ready; everything after it reports Pending naming what it waits on. status.version only advances once every component is ready at the version this release pins, so a partially applied install never reports as complete.

See Component Reference for the components, their phases, and what each category costs you when it stalls.

Upgrade

helm upgrade kmetal-operator oci://ghcr.io/clastix/charts/kmetal-operator \
  --namespace kmetal-operator-system \
  --values values.yaml \
  --wait \
  --timeout=15m

helm history kmetal-operator -n kmetal-operator-system

Uninstall

Uninstalling the operator and uninstalling the platform are two different operations, and the chart keeps them apart on purpose.

helm uninstall removes the operator. The KMetal object is annotated helm.sh/resource-policy: keep, and the CustomResourceDefinitions are never deleted, so the platform keeps running with nothing reconciling it:

helm uninstall kmetal-operator -n kmetal-operator-system

That is what you want for replacing the operator, and it is reversible — reinstall the chart and reconciliation resumes.

Deleting the KMetal object uninstalls the whole platform

Every component the operator installs is owned by the KMetal object, and that ownership includes the CustomResourceDefinitions of everything it installed.

Deleting it therefore removes the platform and every custom resource those definitions serve — tenant Clusters, hosted control planes, Kube-OVN VPCs and subnets, and the VMs and volumes behind them.

Delete every tenant Cluster first, and confirm the tenants are gone, before going anywhere near it:

kubectl get clusters -A
kubectl delete cluster <name> -n <namespace>      # for each, and wait for it to finish

Do not delete the CustomResourceDefinition to "clean up" instead — that deletes the KMetal object, with the same result.

Next Steps