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
| Backend | How 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:
| Flag | Description |
|---|---|
--os-disk | Required. Device path for the OS disk (e.g. /dev/sda). |
--data-disk | Repeatable. Device path(s) for data disks. |
--storage-backend | One of filesystem, lvm, or zfs. |
--lvm-vg-name | LVM volume group name (default vg_kcore). |
--lvm-lv-prefix | Prefix for LVM logical volume names. |
--zfs-pool-name | ZFS pool name (default tank0). |
--zfs-dataset-prefix | Prefix 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.