Skip to content

Creating Clusters

Create tenant Kubernetes clusters in kMetal. Each tenant cluster is a CAPI Cluster resource that references the platform-provided kubevirt-kubeadm ClusterClass — the ClusterClass drives the rest (hosted control plane, worker VMs, networking).

Prerequisites

Your platform admin has configured:

  • A tenant namespace where you can create Cluster resources.
  • A VPC + Subnet allocation reachable from the under cluster's provider network.
  • A control-plane VIP allocated from MetalLB.
  • A bootstrap-server endpoint your worker VMs can reach.

Create via YAML

# my-cluster.yaml
apiVersion: cluster.x-k8s.io/v1beta2
kind: Cluster
metadata:
  name: my-cluster
  namespace: <tenant-namespace>
spec:
  clusterNetwork:
    pods:
      cidrBlocks:
        - 10.200.0.0/16             # tenant cluster pod CIDR
    services:
      cidrBlocks:
        - 10.201.0.0/16             # tenant cluster service CIDR
  topology:
    classRef:
      name: kubevirt-kubeadm
      namespace: kmetal-capi-providers
    version: v1.34.1                 # tenant Kubernetes version
    variables:
      - name: controlPlane
        value:
          dataStoreName: default
          network:
            certSANs:
              - <public-fqdn-or-ip>
            serviceAddress: <metallb-vip>     # e.g. 172.21.204.201
            serviceType: LoadBalancer
      - name: machineSize
        value: small                  # small | medium | large (defined by ClusterClass)
      - name: bootstrapConfig
        value:
          serverAddress: <bootstrap-server>   # e.g. 10.100.0.254
      - name: network
        value:
          subnet: <ovn-subnet-name>           # tenant OVN Subnet
    workers:
      machineDeployments:
        - class: default-worker
          name: md-0
          replicas: 2

Apply it:

kubectl apply -f my-cluster.yaml

The ClusterClass topology drives the rest:

  • A KamajiControlPlane (the CAPI-managed Kamaji control plane) is auto-created.
  • A KubevirtCluster + KubevirtMachineTemplate are auto-created.
  • A MachineDeployment is auto-created for the workers.
  • Kamaji provisions the tenant control plane pods (api-server, controller-manager, scheduler, konnectivity-server).
  • CAPK provisions tenant worker VMs from the ClusterClass tier.

Provisioning typically takes a few minutes. Watch progress:

kubectl get cluster,kamajicontrolplane,machinedeployment,machine -n <tenant-namespace>

Access Cluster

Get Kubeconfig

# Kamaji creates the kubeconfig secret as <cluster-name>-admin-kubeconfig in the cluster's namespace
kubectl get secret my-cluster-admin-kubeconfig \
  -n <tenant-namespace> \
  -o jsonpath='{.data.admin\.conf}' | base64 -d > my-cluster.kubeconfig

export KUBECONFIG=my-cluster.kubeconfig
kubectl get nodes

Verify Cluster

# Under-cluster view
kubectl get cluster -n <tenant-namespace>                    # CAPI Cluster
kubectl get kamajicontrolplane -n <tenant-namespace>         # control plane status
kubectl get tenantcontrolplane -n <tenant-namespace>         # underlying Kamaji TCP
kubectl get machinedeployment,machines -n <tenant-namespace> # workers
kubectl get kubevirtcluster -n <tenant-namespace>            # CAPK infrastructure

# Tenant view (with kubeconfig)
kubectl get nodes
kubectl get pods -n kube-system
kubectl get storageclass

Troubleshooting

Cluster Not Ready

# Top-level Cluster status
kubectl describe cluster my-cluster -n <tenant-namespace>

# Kamaji control plane status
kubectl describe kamajicontrolplane my-cluster -n <tenant-namespace>
kubectl describe tenantcontrolplane my-cluster -n <tenant-namespace>

# Kamaji TCP pods
kubectl get pods -n <tenant-namespace> -l kamaji.clastix.io/name=my-cluster

# Events
kubectl get events -n <tenant-namespace> --sort-by='.lastTimestamp'

Workers Not Joining

# Worker provisioning state
kubectl get machinedeployment,machine -n <tenant-namespace>
kubectl describe machine <machine-name> -n <tenant-namespace>

# Worker VMs (KubeVirt)
kubectl get virtualmachine,virtualmachineinstance -n <tenant-namespace>

# Bootstrap (kubeadm)
kubectl get kubeadmconfig -n <tenant-namespace>

Contact your platform admin if workers stay stuck after a few minutes — common causes are subnet exhaustion, VIP unreachable from worker side, or bootstrap-server unreachable.