Blockstor is a Kubernetes control plane for LVM and ZFS storage with DRBD replication. It speaks a LINSTOR-compatible REST API, so the clients you already use — linstor-csi, piraeus-operator, ha-controller, golinstor, the linstor CLI — keep working unchanged.
The difference is what's underneath. Instead of a central controller with its own database and synchronous RPC to every node, blockstor is built the way Kubernetes operators are built: the desired state lives in CRDs, and a set of controller-runtime reconcilers drive the cluster toward it. There is no external database to back up, no in-memory state to lose on restart, and no controller→node polling to fall behind.
- Reconciliation control plane. State of truth lives in Kubernetes CRDs; controller and satellite are
controller-runtimemanagers with watch-based informers, declarative reconcile loops, and Status SSA. No synchronous fan-out RPC, no central in-memory state, no per-request controller→node polling. Desired/observed convergence is automatic. - First-class CRDs.
Resource,ResourceDefinition,ResourceGroup,StoragePool,Snapshot,Node,PhysicalDeviceare designed to be read and (where appropriate) written by other operators: cozystack tenant operators, GitOps tooling, custom monitoring/alerting, admission webhooks. Schemas carry kubebuilder enum/min/max validation; multi-writer Status uses Server-Side Apply field managers. - Per-node satellite as a controller. Each satellite is a controller-runtime manager that watches its own slice of CRDs (filtered by
Spec.NodeName) and writes observed state back via Status SSA directly. No gRPC dispatch from a central controller.
- Built in Go. Go is the lingua franca of the Kubernetes ecosystem — apiserver, kubelet, etcd, the bulk of CSI drivers, controller-runtime itself — so blockstor shares its tooling, libraries, and contributor base.
- Small footprint. The controller, apiserver, and satellite are statically-linked Go binaries — no JVM and no language runtime to ship — and DRBD is a Linux kernel module rather than a userspace daemon. The images are multi-arch (
linux/amd64,linux/arm64) and cross-compile cleanly, so blockstor fits on edge and small ARM nodes where a multi-hundred-megabyte Java runtime would not.
What works today:
- Replicated volumes over DRBD, on LVM, LVM-thin, ZFS, ZFS-thin, or file backends
- Running without DRBD — plain local storage (single-replica diskful or diskless)
- LUKS encryption — volume-level encryption at rest
- Autoplacement with constraints (zones, node properties, replicas-on-different)
- TieBreaker + quorum policies
- Snapshots — create, restore as a new resource, roll back, and clone
- Intra-cluster snapshot shipping (
zfs send/recv,thin-send-recv) for clone / add-replica - Online volume resize
- Device-pool creation from physical disks (
physical-storage create-device-pool) - LINSTOR-compatible REST API for the whole client ecosystem, served over mTLS
Not implemented — the API answers these with 501 Not Implemented:
- Cross-cluster snapshot shipping (disaster recovery)
- Backup create / restore / ship / abort, and the backup queue
- Schedules (cron-driven backups)
- Remote backends — S3, LINSTOR remotes
- Extra storage providers — SPDK, NVMe-oF, OpenFlex, Exos
On the roadmap:
- Bring-your-own-key encryption — operator-managed Secret references in the spec, instead of a controller-owned passphrase bag
- Migration tool from LINSTOR — adopt an existing LINSTOR cluster's resources into blockstor in place
- Shared-LUN provisioning — thick LVM plus thin qcow2-on-LVM, no filesystem layer
- VDUSE backend via
qemu-storage-daemon, for shared-SAN Kubernetes
Blockstor installs onto an existing cluster and is driven with the standard linstor client and piraeus linstor-csi. The full walkthrough — installing the control plane, registering nodes and pools, and wiring up CSI — lives in docs/usage.md.
The three images are published to GHCR on every release:
ghcr.io/cozystack/blockstor-controller— the reconcilersghcr.io/cozystack/blockstor-apiserver— the LINSTOR-compatible REST API (mTLS)ghcr.io/cozystack/blockstor-satellite— the per-node DRBD / storage agent
docs/usage.md— install and operate blockstor with thelinstorclient + piraeus/linstor-csi.docs/architecture.md— the load-bearing design decisions.docs/layer-stack.md— DRBD / LUKS / STORAGE compositions.AGENTS.md— repository layout and the local Talos+QEMU dev stand, for contributors.
Blockstor was inspired by LINBIT's LINSTOR, and it operates DRBD to provide block-level replication. It deliberately speaks LINSTOR's API so that the rich ecosystem the LINSTOR community has built keeps working unchanged. Heartfelt thanks to LINBIT and to the wider DRBD / LINSTOR / Piraeus community.
Blockstor is licensed under Apache 2.0. The code is provided as-is with no warranties.
Third-party Go modules and their licenses are catalogued in THIRD_PARTY_LICENSES.md; the runtime dependency graph is constrained to an Apache-2.0–compatible allowlist (Apache-2.0, BSD-2-Clause, BSD-3-Clause, MIT, MPL-2.0, ISC) by the license-scan CI gate in .github/workflows/license-check.yml. For interoperability with LINSTOR clients, type definitions are sourced from the Apache-2.0 golinstor library; blockstor does not copy or generate code from upstream LINSTOR (GPL) sources.
LINSTOR, LINBIT, and DRBD are trademarks or registered trademarks of LINBIT. Blockstor is an independent project and is not affiliated with, endorsed by, or sponsored by LINBIT.