Skip to content

Install kMetal

This page covers the basic install of kMetal on a prepared under cluster. Ensure you have completed Setup Under Cluster and have credentials from Clastix.

Start Your Evaluation

Don't have credentials yet? Clastix provides an evaluation process with:

  • Temporary access token for ghcr.io/clastix
  • Technical support during evaluation period

Contact sales@clastix.io or learn more about our evaluation process.

Log in to the OCI registry

kMetal is delivered as an Operator that installs all the required dependencies, and managing the lifecycle of the platform. The Helm Chart is hosted in a private OCI registry, log in with your credentials before pulling:

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

Create the registry secrets

Two Secrets are needed, both in the namespace the operator runs in. The operator reads them from there and copies them into every namespace the platform installs into — a Secret is only usable from its own namespace, and the operator's is the one namespace guaranteed to hold them on a cluster installed from scratch.

kubectl create namespace kmetal-operator-system

# dockerconfigjson — kubelet pulling component images, and Flux fetching the
# private kMetal charts and artifacts.
kubectl create secret docker-registry clastix-ghcr \
  --docker-server=ghcr.io \
  --docker-username=<evaluation-username> \
  --docker-password=<evaluation-token> \
  --namespace=kmetal-operator-system

# Opaque — the Cluster API operator fetching the Kamaji control-plane provider
# from the private OCI registry. It reads these keys, not a docker config.
kubectl create secret generic clastix-ghcr-oci \
  --from-literal=OCI_USERNAME=<evaluation-username> \
  --from-literal=OCI_PASSWORD=<evaluation-token> \
  --namespace=kmetal-operator-system

The two are separate because the consumers want different shapes: kubelet and Flux want a kubernetes.io/dockerconfigjson, while the Cluster API operator reads OCI_USERNAME and OCI_PASSWORD (or OCI_ACCESS_TOKEN) as plain keys. Name them in the spec as registry.imagePullSecretName and registry.chartPullSecretName respectively — see the overlay below.

Credential Security

Store credentials securely. Never commit them to version control; use a secret manager or environment variables.

Prepare a values overlay

kMetal needs a small amount of per-deployment configuration. The chart carries the KMetal spec verbatim under kmetal.spec, so a values.yaml for your environment looks like this:

kmetal:
  spec:
    networking:
      kubeOVN:
        podCIDR: 10.16.0.0/16          # the ovn-default subnet, not the cluster pod network
        tunnelInterface: <primary-nic> # same interface as CONTROL_PLANE_INTERFACE; single node, no separate VLAN needed
        centralNodes:                  # this walkthrough's single node
          - kmetal
      serviceCIDR: 10.96.0.0/16        # must match --service-cluster-ip-range
      providerNetworks:
        - name: provider
          interface: <second-nic>      # taken wholesale into OVN's bridge — must be the second NIC, never the one carrying the node's IP
          subnets:
            - name: external
              cidrBlock: 198.51.100.0/27
              gateway: 198.51.100.1
              excludeIPs:
                - 198.51.100.1
      defaultProviderSubnet: external
      loadBalancer:
        tenantControlPlanes:
          addresses:
            - 192.0.2.10-192.0.2.50
    storage:
      underclusterClassName: platform-storage       # golden images + machine disks; must snapshot
      etcdClassName: local-path                     # optional; tenant control-plane etcd
      tenantClassName: tenant-storage-class         # handed to tenants
    clusterClass:
      values:
        dataVolume:
          # Same driver as underclusterClassName. No chart default: the
          # ClusterClass component will not render without it.
          volumeSnapshotClass: platform-storage-snapshot
    multiTenancy:
      # Who Capsule enforces tenancy for. Nothing is filled in for you.
      users:
        - kind: Group                  # the group covering every ServiceAccount
          name: system:serviceaccounts:kmetal-tenants   # in that namespace
    registry:
      imagePullSecretName: clastix-ghcr
      chartPullSecretName: clastix-ghcr-oci

Those are the fields with no sane default; everything else the release pins. storage.underclusterClassName must name a class whose driver can take snapshots — it holds the golden OS images and every tenant machine's root disk — while etcdClassName is where a node-local class still belongs, and is optional because it follows the class above when omitted. multiTenancy is the one block with no default at all: Capsule only enforces tenancy for subjects it has been told about, and kMetal names none on your behalf. The entry above is what makes the ServiceAccount-owned Tenant in Create First Tenant take effect — without it that Tenant is accepted and then ignored. The full spec (every field, its default, its constraints and how it fails) is the Platform Configuration Reference, and kubectl explain kmetal.spec --recursive is the same reference read off the cluster.

A missing registry Secret is not an error

Both are optional, and the operator logs a skip rather than failing the install — a cluster pulling only public charts and images needs neither. On a cluster pulling the private kMetal charts, an absent one surfaces later as a failed fetch or an ImagePullBackOff on the components that need it, rather than as a missing credential.

Install the chart

helm upgrade --install kmetal-operator oci://ghcr.io/clastix/charts/kmetal-operator \
  --version 1.0.0 \
  --namespace kmetal-operator-system \
  -f values.yaml --wait

Verify the release:

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

Monitor installation

The chart deploys multiple component pods across several namespaces. Watch them come up:

# Multi-Cluster management
kubectl get pods -n kmetal-capi-operator
kubectl get pods -n kmetal-capi-providers
kubectl get pods -n kmetal-kairos-capi
# Multi-Tenancy and Governance
kubectl get pods -n kmetal-capsule
# PKI
kubectl get pods -n kmetal-cert-manager
# UI, Conformance, Installer
kubectl get pods -n kmetal-console
kubectl get pods -n kmetal-operator-system
# Fleet Management and GitOps
kubectl get pods -n kmetal-flux
kubectl get pods -n kmetal-sveltos
# Immutable OS
kubectl get pods -n kmetal-image-builder
kubectl get pods -n kmetal-kairos-operator
# Hosted Control Planes
kubectl get pods -n kmetal-kamaji
# Networking
kubectl get pods -n kmetal-metallb
kubectl get pods -n kmetal-system

Next Steps

kMetal is now installed on your under cluster. Before a tenant cluster can exist it needs a Tenant that owns it and an Environment to live in — continue to Create First Tenant.