Show examples as

Storage backends

kcore supports three VM data-plane storage backends: filesystem, LVM, and ZFS. The backend is chosen at node install time and determines where VM disks are stored.

Supported backends

BackendHow it works
Filesystem VM images and volumes are stored under /var/lib/kcore/. Single-disk nodes use the OS filesystem directly. Multi-disk nodes get dedicated ext4 mounts at /var/lib/kcore/volumes, /var/lib/kcore/volumes1, etc.
LVM Disko creates the PV and VG at install time. The node-agent creates and deletes LVs at runtime via lvcreate. The VG name is configurable (default vg_kcore).
ZFS Disko creates the pool at install time. The node-agent uses it for zvol and dataset operations. The pool name is configurable (default tank0).

Day-0 configuration (install time)

The kctl node install command accepts the following storage-related flags:

FlagDescription
--os-diskRequired. Device path for the OS disk (e.g. /dev/sda).
--data-diskRepeatable. Device path(s) for data disks.
--storage-backendOne of filesystem, lvm, or zfs.
--lvm-vg-nameLVM volume group name (default vg_kcore).
--lvm-lv-prefixPrefix for LVM logical volume names.
--zfs-pool-nameZFS pool name (default tank0).
--zfs-dataset-prefixPrefix for ZFS dataset names.

Filesystem example

kctl node install \
  --os-disk /dev/sda \
  --data-disk /dev/sdb \
  --storage-backend filesystem
resource "kcore_node" "files" {
  bootstrap       = true
  address         = "192.168.40.107:9091"
  os_disk         = "/dev/sda"
  data_disk       = ["/dev/sdb"]
  storage_backend = "filesystem"
  certs_dir       = "${path.module}/certs"
  run_controller  = true
}

LVM example

kctl node install \
  --os-disk /dev/sda \
  --data-disk /dev/sdb \
  --storage-backend lvm \
  --lvm-vg-name vg_kcore \
  --lvm-lv-prefix kcore-
resource "kcore_node" "lvm" {
  address         = "192.168.40.105:9091"
  os_disk         = "/dev/sda"
  data_disk       = ["/dev/sdb"]
  storage_backend = "lvm"
  certs_dir       = "${path.module}/certs"
  join_controller = "192.168.40.107:9090"
}

ZFS example

kctl node install \
  --os-disk /dev/sda \
  --data-disk /dev/sdb --data-disk /dev/sdc \
  --storage-backend zfs \
  --zfs-pool-name tank0 \
  --zfs-dataset-prefix kcore/
resource "kcore_node" "zfs" {
  address         = "192.168.40.103:9091"
  os_disk         = "/dev/sda"
  data_disk       = ["/dev/sdb", "/dev/sdc"]
  storage_backend = "zfs"
  certs_dir       = "${path.module}/certs"
  join_controller = "192.168.40.107:9090"
}

LUKS disk encryption

The OS disk is always encrypted with LUKS2. When /sys/class/tpm/tpm0 exists on the node, the key is TPM2-sealed for automatic unlock on boot. Otherwise a key-file is used.

The recovery key is written to /etc/kcore/recovery/luks-recovery-key.txt (root-only, mode 0400). Store this key securely — it is the only way to unlock the disk if the TPM is cleared or the key-file is lost.

Storage classes

Storage classes in kcore are derived from node registration — they are not a separate API object. Each node reports its configured backend, and the controller aggregates them.

$ kctl get storage-class
NAME          NODES
filesystem    3
lvm           2
zfs           1
unspecified   0

To see which nodes use a specific backend:

$ kctl describe storage-class lvm
Storage class: lvm
Nodes (2):
  - node-ab12cd34
  - node-ef56gh78

Node-agent configuration

The node-agent reads its storage settings from /etc/kcore/node-agent.yaml:

storage:
  backend: lvm                          # filesystem | lvm | zfs
  filesystemVolumeDir: /var/lib/kcore/volumes
  lvm:
    vgName: vg_kcore
    lvPrefix: kcore-
  zfs:
    poolName: tank0
    datasetPrefix: kcore/
  imageCacheDir: /var/lib/kcore/image-cache

VM storage flags

When creating a VM you can specify the storage backend and disk size:

kctl create vm \
  --storage-backend filesystem \
  --storage-size-bytes 42949672960
kind: VM
metadata:
  name: my-vm
spec:
  storageBackend: filesystem
  storageSizeBytes: "40G"
  # ... (other fields)

Apply: kctl apply -f vm.yaml

Showing Terraform examples. Provider source is kcorehypervisor/kcore, version 0.5.0.

image_url and image_path are mutually exclusive. URL mode needs image_sha256. cpu and memory_bytes are required.

resource "kcore_vm" "my_vm" {
  name               = "my-vm"
  cpu                = 2
  memory_bytes       = 4 * 1024 * 1024 * 1024
  storage_backend    = "filesystem"
  storage_size_bytes = 40 * 1024 * 1024 * 1024
  image_url          = "https://cloud.debian.org/images/cloud/bookworm/latest/debian-12-genericcloud-amd64.qcow2"
  image_sha256       = "<sha256>"

  nic {
    network = "default"
  }
}

resource "kcore_volume" "data" {
  name          = "my-vm-data"
  size_bytes    = 10737418240
  storage_class = "lvm"
  vm            = kcore_vm.my_vm.id
}

Shared storage (kcore SAN)

For Ceph RBD disks, cold drain, and live migration, see kcore SAN (Ceph) and VM migration.