Skip to content

API Reference

Custom Resource Definitions used by kMetal. Tenant clusters are provisioned through the upstream Cluster API topology (Cluster CR referencing a ClusterClass); kMetal-specific CRDs surface from there as the ClusterClass turns the topology into concrete control-plane and infrastructure resources.

Cluster API (Cluster + topology)

The user-facing CR. Users create a Cluster referencing kMetal's kubevirt-kubeadm ClusterClass. CAPI + CACPK + CAPK auto-create everything else.

apiVersion: cluster.x-k8s.io/v1beta2
kind: Cluster
metadata:
  name: my-cluster
  namespace: <tenant-namespace>
spec:
  clusterNetwork:
    pods:
      cidrBlocks:
        - 10.200.0.0/16
    services:
      cidrBlocks:
        - 10.201.0.0/16
  topology:
    classRef:
      name: kubevirt-kubeadm
      namespace: kmetal-capi-providers
    version: v1.34.1
    variables:
      - name: controlPlane
        value:
          dataStoreName: default
          network:
            certSANs:
              - <public-fqdn-or-ip>
            serviceAddress: <metallb-vip>
            serviceType: LoadBalancer
      - name: machineSize
        value: small
      - name: bootstrapConfig
        value:
          serverAddress: <bootstrap-server>
      - name: network
        value:
          subnet: <ovn-subnet-name>
    workers:
      machineDeployments:
        - class: default-worker
          name: md-0
          replicas: 2

KamajiControlPlane

Auto-created by CACPK (the Kamaji ControlPlane provider) from the Cluster.spec.topology variables. Driving the tenant control plane (Kamaji TenantControlPlane internally).

apiVersion: controlplane.cluster.x-k8s.io/v1alpha1
kind: KamajiControlPlane
metadata:
  name: my-cluster
  namespace: <tenant-namespace>
spec:
  replicas: 2
  version: v1.34.1
  dataStoreName: default
  registry: registry.k8s.io
  controlPlaneEndpoint:
    host: <metallb-vip>
    port: 6443
  network:
    advertiseAddress: <bootstrap-server>     # what workers connect to
    serviceAddress: <metallb-vip>
    serviceType: LoadBalancer
    serviceAnnotations:
      metallb.io/loadBalancerIPs: <metallb-vip>
    certSANs:
      - <public-fqdn-or-ip>
  addons:
    coreDNS: { imageTag: v1.13.1 }
    kubeProxy: { imageTag: v1.34.1 }
    konnectivity:
      server:
        port: 8132
        image: registry.k8s.io/kas-network-proxy/proxy-server
        version: v0.34.0
      agent:
        mode: DaemonSet
        image: registry.k8s.io/kas-network-proxy/proxy-agent
        version: v0.34.0

KubevirtCluster

Auto-created by CAPK from the topology. Infrastructure provider record; users rarely touch it directly.

apiVersion: infrastructure.cluster.x-k8s.io/v1alpha1
kind: KubevirtCluster
metadata:
  name: my-cluster-<hash>
  namespace: <tenant-namespace>
spec: {}            # populated by CAPK from ClusterClass + variables

DataStore

Kamaji DataStore CR. Each tenant control plane references one by name via the topology variable controlPlane.dataStoreName. By default the Kamaji chart deploys a 3-replica etcd statefulset in kmetal-kamaji and registers a cluster-scoped DataStore named default — every tenant control plane references default until you create a dedicated datastore for a specific tenant.

apiVersion: kamaji.clastix.io/v1alpha1
kind: DataStore
metadata:
  name: default
spec:
  driver: etcd                         # or "PostgreSQL" for CNPG
  endpoints:
    - "kamaji-etcd-0.kamaji-etcd.kmetal-kamaji.svc.cluster.local:2379"
    - "kamaji-etcd-1.kamaji-etcd.kmetal-kamaji.svc.cluster.local:2379"
    - "kamaji-etcd-2.kamaji-etcd.kmetal-kamaji.svc.cluster.local:2379"
  tlsConfig:
    certificateAuthority:
      certificate:
        secretRef:
          name: kamaji-etcd-ca
          namespace: kmetal-kamaji

MetalLB

IPAddressPool

apiVersion: metallb.io/v1beta1
kind: IPAddressPool
metadata:
  name: default-pool
  namespace: kmetal-metallb
spec:
  addresses:
    - 192.168.1.100-192.168.1.200
  autoAssign: true

L2Advertisement

apiVersion: metallb.io/v1beta1
kind: L2Advertisement
metadata:
  name: default-l2-adv
  namespace: kmetal-metallb
spec:
  ipAddressPools:
    - default-pool

Cert-Manager

Certificate

apiVersion: cert-manager.io/v1
kind: Certificate
metadata:
  name: console-tls
spec:
  secretName: console-tls
  issuerRef:
    name: letsencrypt-prod
    kind: ClusterIssuer
  dnsNames:
    - console.company.com

ClusterIssuer

apiVersion: cert-manager.io/v1
kind: ClusterIssuer
metadata:
  name: letsencrypt-prod
spec:
  acme:
    server: https://acme-v02.api.letsencrypt.org/directory
    email: admin@company.com
    privateKeySecretRef:
      name: letsencrypt-prod
    solvers:
      - http01:
          ingress:
            class: haproxy

Operations

# List resources
kubectl get cluster -A
kubectl get kamajicontrolplane -A
kubectl get tenantcontrolplane -A
kubectl get kubevirtcluster -A
kubectl get datastore
kubectl get certificates -A

# Status
helm status kmetal -n kmetal-flux
kubectl describe cluster <name> -n <tenant-namespace>
kubectl describe kamajicontrolplane <name> -n <tenant-namespace>