Skip to main content
Celum installs and operates storage per supervisor from a catalogue of backends, grouped into three families on the onboarding wizard’s Storage step. Each reports day-2 state through the platform’s component-status model, and each ends the same way: one or more StorageClasses that every downstream consumer — tenant clusters, VMs, the Image Library, monitoring — provisions against. Picking a family narrows the list; picking a backend renders that backend’s own parameters, including a disk picker where it consumes raw devices. Serving storage now, above the family tabs, lists what is already installed and the classes it provisions — the answer to “is there working storage here” without reading any panel below it. They are not exclusive. A supervisor commonly runs one software-defined backend as its default and adds NFS for bulk file storage.
Some catalogue rows are marked preview: their coordinates are verified — provisioner, chart, pinned version — but nothing has installed them through this platform yet, so the install refuses with that reason rather than pretending. Install one by hand once, confirm it, and the row stops being preview.

Choosing a backend

The families narrow it; the workload decides it. The figures behind these steps come from one benchmark recipe run in VMs and pods on two supervisors and on vSphere — see Storage performance for the tables and their caveats.
1

Local disks in the nodes — a software-defined backend

The default path. Replicated block storage with snapshots and fast CSI clones, no external dependency. This is what the Image Library’s ~seconds golden-image cloning and VM live migration are built on.LINSTOR and Rook-Ceph both do this, and Ceph offers self-healing, scrubbing and redundancy that does not depend on an array — a real trade, not a ranking.Replication needs enterprise NVMe with power-loss protection. A replicated write is acknowledged only once it is on stable storage on every copy. On enterprise drives that measured on par with a Fibre Channel array inside VMs; on consumer drives the same benchmark wrote at about 1/50 of that, with a 30 ms write p99.
2

An array behind the nodes — give it to a software-defined backend as a shared LUN

Rather than a volume-per-PVC vendor driver, the shipped pattern is one large LUN masked to every node, consumed by the software-defined backend. The array’s API stays out of the runtime path, so provisioning is a local operation rather than a REST call, and a path failure is absorbed by multipath.
3

Synchronous-commit workloads — enterprise drives or the array

This is the decision people get backwards. A consumer NVMe without power-loss protection must land every flushed write in flash before acknowledging it, so etcd, database commit logs and anything that fsyncs and waits must never sit on replicated consumer drives. On enterprise drives with power-loss protection, replicated local storage is a full alternative: inside a VM its write p99 measured lower than the array’s. In a pod, where the path is shorter, the array’s cache takes writes faster.
4

Read-heavy datasets — either class

Replicated local storage serves reads from the local copy, so reads do not pay for replication. Inside VMs the local class read somewhat faster than the array, in pods somewhat slower — close enough that capacity and placement, not read speed, should decide. Image stores, caches and read-mostly datasets can go on either.
5

Array-native data services required — a vendor driver

When a volume must be a first-class array object (one LDEV per PVC, array-side thin provisioning and snapshots), install the vendor’s driver from the Arrays family. Expect array-API latency in the provisioning path and, on Fibre Channel, a hard multipath prerequisite on the nodes.
6

Existing NAS, file semantics — NFS

Simplest to stand up: server + export path, one StorageClass, a built-in test-PVC smoke check. Filesystem-mode only — fine for shared data, the slow path for VM images.
Leave the default StorageClass unset unless you mean it. With this spread between classes, a claim that names no class is a placement decision nobody made — and the platform gates the choice to exactly one class per backend for the same reason.

What lives where

  • Install and reconfigure happen on the wizard’s Storage step — one panel over the whole catalogue, with a chart release panel and the selected backend’s own forms. Re-opening the step hydrates those forms from the live release on the supervisor, so a re-apply expresses deltas rather than re-entering a configuration the cluster already holds.
  • The snapshot controller arrives with the first backend, whichever it is, because every row in the catalogue declares snapshot support and a snapshot class written before its CRDs exist fails in a way that reads as a broken backend. See PVCs & snapshots.
  • Day-2 status is the same status model as every other component: exists / ready / revision / conditions with the chart controller’s reason and message. The supervisor’s Storage tab renders a panel per installed backend — LINSTOR’s network, replication and listeners, NFS’s route to the server, Ceph’s cluster health — plus a reachability check that sends real packets from the host and pod networks.
  • Disk inventory — every node’s block devices with model, size, transport (nvme / sata / fc / usb) and a lifecycle state — feeds the Rook disk picker and the Infrastructure page’s SAN LUN panel, where FC LUNs group by WWID with their multipath path counts.
The disk inventory comes from Omni, and its absence looks like an absence of disks. With Omni disabled or unreachable the endpoint answers 200 with an empty machine list and a source of omni-disabled or omni-error. On screen that is an empty disk table — indistinguishable from a supervisor whose nodes have nothing free — and Rook cannot be installed through the wizard at all. The source field is the only thing that separates the two, so read it before concluding there are no disks.
  • Classes & profiles list every StorageClass and its CDI StorageProfile — the clone strategy and access-mode/volume-mode combinations that decide VM cloning speed and live-migration eligibility.
  • PVCs & snapshots browse actual claims and volume snapshots per namespace.
The in-product assistant, Celum AI, answers storage questions from these same APIs — “which class should this VM use?” or “why is Ceph degraded?” reads the identical status, class, profile, disk, and PVC data the panels render.

PVC Pending — the triage order

A Pending claim is the universal storage symptom. Work top-down:
1

Read the claim's events

The test-PVC diagnostic provisions a throwaway claim against any class and returns the PVC events on failure — the provisioner’s own error, without kubectl.
2

Does the class exist, and is its provisioner running?

Check the backend’s status panel. A deleted NFS driver leaves orphan StorageClasses that look valid but can never bind; a Ceph cluster can be healthy while the CSI provisioner is absent.
3

Can the class satisfy what was requested?

ReadWriteMany on a class whose profile only claims ReadWriteOnce, or Block mode on file-backed storage, pends forever. The profiles table shows what each class actually supports.
4

Is the backend itself healthy?

Ceph health warnings (OSDs down, degraded PGs), an unreachable NFS server, or a misconfigured FC port list all surface in the respective status — see the per-backend pages for their failure signatures.
Result: either a bound claim, or one specific cause. The order matters because each step rules out a whole class: a claim that binds under the test PVC moves the question to the workload, and a class the profile cannot satisfy will never bind however healthy the backend is. The full checklist with per-cause signatures lives in PVCs & snapshots.

Permissions

All storage backend operations map to the storage action family, scoped to krn:celum:supervisor:<supervisor>:storage:*:
“Recover a stuck rollback” does not roll anything back. It detects a HelmRelease caught in a Flux rollback loop and forces it forward. It is idempotent and safe to press on a healthy cluster, where it reports matched: false and does nothing — but it will never take a backend back off. Removing a storage backend is a manual operation.
Ceph cluster health reads use ceph:GetStatus on krn:celum:supervisor:<supervisor>:ceph:*. The snapshot controller and the namespace-scoped PVC/snapshot listings have their own families — see the per-page tables.

The Storage pages

The Storage tab

What a supervisor’s storage is doing right now — per backend — and a check that sends packets to prove it.

LINSTOR

Replicated local disks and a shared array LUN from one backend — which class a workload wants, and why.

Storage performance

One benchmark across replicated NVMe, a Fibre Channel array and vSAN — in VMs and pods — and why consumer drives are excluded from replication.

Rook-Ceph

Local-disk and SAN-LUN installs, the disk picker and wipe flow, Ceph health, and rollback recovery.

NFS & Fibre Channel

The external backends — NFS driver and storage classes, and Fibre Channel array LUNs under LINSTOR or Ceph.

Classes & profiles

StorageClasses, CDI StorageProfiles, and which class to give VMs and golden images.

PVCs & snapshots

The per-namespace claim browser, volume snapshots, the snapshot controller, and the Pending checklist.