Blockstor: a LINSTOR-compatible storage system for Kubernetes, written from scratch in Go | Cozystack
Join the Community<br>Create docs issue<br>Create project issue
Article types<br>Announcement4<br>Case2<br>How-To8<br>News21<br>Release42<br>Tech-Article9
Topics<br>Backup1<br>Cilium3<br>Cncf1<br>Community9<br>Drbd2<br>Events8<br>Gpu2<br>Install1<br>Kubernetes18<br>Kubevirt10<br>Linstor2<br>Networking9<br>Observability1<br>Opensearch1<br>Platform61<br>Postgresql1<br>Security11<br>Storage10<br>Talos10<br>Virtualization2
The Cozystack team has open-sourced Blockstor, a control plane for block storage in Kubernetes: LVM and ZFS as backends, replication over DRBD, and a LINSTOR-compatible REST API. The project lives in the cozystack organization and is developed as part of Cozystack, a platform accepted into the CNCF Sandbox. The license is Apache 2.0.<br>The main thing that makes it worth a look: it is not a fork, and it is not a wrapper. Blockstor is written from scratch in Go, but it speaks the same REST API as LINSTOR — so all the client tooling you already run keeps working without a single change: the linstor CLI, linstor-csi, piraeus-operator, and the golinstor library.<br>Why Blockstor takes a different approach<br>LINSTOR is a mature system, and it ran in production in Cozystack for years. We did not hit a functionality ceiling — we hit the model.<br>The original controller is request-based: for most API calls it goes out to the nodes in real time and polls their state to assemble a response. That has two consequences. First, this design scales poorly. Second, with no reconciliation loop, automatic recovery from failures has to be bolted on from the outside.<br>Blockstor is built the way Kubernetes operators are normally built: the desired state lives in CRDs, and a set of reconcilers on controller-runtime drives the cluster toward it. Three practical consequences follow:<br>No external database to back up and worry about<br>No in-memory state to lose when the controller restarts<br>No controller-side polling of nodes that can fall behind reality<br>The satellites watch the API themselves and write the observed state back through Server-Side Apply, using separate field managers. Spec belongs to the controller, Status to the satellite, and that split is enforced strictly.<br>What it is made of<br>Three components, all of them ordinary Kubernetes workloads:<br>ComponentRoleblockstor-controllerA Deployment running the controller-runtime reconcilersblockstor-apiserverA stateless, LINSTOR-compatible REST front end, backed by CRDs. This is what linstor, CSI, and Piraeus talk toblockstor-satelliteA DaemonSet: it brings up the DRBD, LUKS, and STORAGE layers on the node and calls drbdadm, lvs, zfs, and cryptsetupThe objects live in the blockstor.cozystack.io/v1alpha1 group: Node, StoragePool, ResourceGroup, ResourceDefinition, Resource, Snapshot, PhysicalDevice, and ControllerConfig. The CRDs are designed as a public integration point, with schema-level validation and a safe multi-writer model for Status, so that GitOps tooling and monitoring can work with them directly.<br>What already works<br>Replicated DRBD volumes on top of LVM, LVM-thin, ZFS, ZFS-thin, and file backends<br>A DRBD-free mode — a single replica, diskful or diskless<br>LUKS encryption at the volume level; the layers stack as DRBD → LUKS → STORAGE<br>Auto-placement with constraints: zones, node properties, and replica spreading<br>TieBreaker and quorum policies — one of the most heavily tested parts of the system<br>Snapshots: create, roll back, clone, and restore into a new resource<br>Snapshot shipping within the cluster using zfs send/recv and thin-send-recv<br>Online volume resize. Shrinking is disabled by default and requires an explicit force=true — here we are deliberately stricter than the original<br>Creating pools from physical disks<br>Replica rebalancing and migration: automatic evacuation from a departing node, automatic promotion to diskful, and recovery after split-brain<br>Skipping the initial sync when a replica is added, by seeding the Generation Identifier. Adding a third replica to a multi-terabyte volume does not turn into a multi-hour resync<br>mTLS on the API with hot certificate reload, Prometheus metrics, and images for amd64 and arm64<br>RWX — verified by an end-to-end test through linstor-csi and NFS-Ganesha<br>What is not there yet<br>We would rather put this in the announcement than have you discover it on day three.<br>The following are not implemented, and they return an honest 501 Not Implemented rather than a silent 404: cross-cluster snapshot shipping, backups and the backup queue, schedules, remote backends such as S3, and the SPDK, NVMe-oF, OpenFlex, and Exos drivers. There is no Helm chart — installation goes through plain manifests. The version is still 0.x.<br>The list of CLI behaviour differences from the original is maintained in public, along with a register of known issues and a write-up of the csi-sanity tests that fail. Put plainly: the project itself publishes the list of its own gaps.<br>Why you can trust this<br>A storage control plane rewritten from scratch is a claim...