Show examples as

First cluster

This walkthrough creates a single-node kcore cluster: one machine running both the controller and the node agent, ready to schedule VMs. The entire process takes two commands from your operator workstation.

1. Create the cluster PKI

On your operator workstation (where kctl is installed), create the cluster trust material:

kctl create cluster \
  --controller 192.168.40.107:9090 \
  --context prod
# cluster.yaml
kind: Cluster
metadata:
  name: prod
spec:
  controller: 192.168.40.107:9090

Apply: kctl apply -f cluster.yaml

This generates the root CA, sub-CA, controller certificate, and kctl client certificate. All certificate data is embedded inline in ~/.kcore/config and the PEM files are saved to ~/.kcore/certs/.

This is a one-time operation per cluster. The context name (prod) is how kctl identifies this cluster in multi-cluster setups. If you omit --context, it defaults to default.

2. Boot the target machine

Write the kcore ISO to a USB drive and boot the server from it. The live environment starts a node-agent listening on :9091. You can optionally inspect the hardware first:

kctl --node 192.168.40.107:9091 -k node disks
kctl --node 192.168.40.107:9091 -k node nics

Identify the OS disk (e.g. /dev/sda) and any data disks.

3. Install to disk

Install kcore to disk with a controller on this node:

kctl node install \
  --node 192.168.40.107:9091 \
  --os-disk /dev/sda \
  --run-controller \
  --dc-id DC1 \
  -k
# node-controller.yaml
kind: NodeInstall
metadata:
  name: kvm-node-107
spec:
  node: 192.168.40.107:9091
  osDisk: /dev/sda
  runController: true
  dcId: DC1
  insecure: true

Apply: kctl apply -f node-controller.yaml

The installer wipes the disk, creates a LUKS-encrypted root partition (TPM2-sealed when available), deploys NixOS, provisions mTLS certificates, and reboots. After reboot:

The install takes 10–20 minutes depending on network speed (the installer downloads NixOS packages from the cache). The node reboots automatically when done.

4. Verify the cluster

After the node reboots, kctl connects over mTLS using the context created in step 1. No -s or -k flags needed:

kctl get nodes

Expected output:

ID                         ADDRESS              DC   STATUS  APPROVAL  CERT EXPIRY  LUKS
kvm-node-192-168-40-107    192.168.40.107:9091  DC1   ready   approved       364d    TPM2

The node shows status ready and approval approved. Your single-node cluster is operational.

5. Create your first VM

kctl create vm web-01 \
  --image https://cloud.debian.org/images/cloud/bookworm/latest/debian-12-genericcloud-amd64.qcow2 \
  --image-sha256 <sha256> \
  --network default \
  --storage-backend filesystem \
  --storage-size-bytes 42949672960 \
  --wait-for-ssh
kind: VM
metadata:
  name: web-01
spec:
  cpu: 2
  memoryBytes: "4G"
  storageBackend: filesystem
  storageSizeBytes: "40G"
  sshKeys:
    - my-key
  nics:
    - network: default
  disks:
    - image: https://cloud.debian.org/images/cloud/bookworm/latest/debian-12-genericcloud-amd64.qcow2
      sha256: "<sha256>"
      format: qcow2

Apply: kctl apply -f web-01.yaml

See VM creation for all options including YAML manifests, SSH keys, and cloud-init.

Next steps