bard-csi

module
v0.1.0-rc.4 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jul 21, 2026 License: Apache-2.0

README

bard-csi

A "jack of all trades" CSI driver for Kubernetes: one driver, many storage backends, and — unlike most existing CSIs — a single StorageClass that can provision across multiple backend instances / zones.

New here? docs/quickstart.md gets you from an empty kind cluster to a working PVC in about three minutes, with no external storage needed.

Every backend is an out-of-tree plugin. The flagship is the Ceph RBD backend — the most feature-rich (see Status) and where the deeper features are proven — but it is one backend among several: CephFS (a shared, ReadWriteMany filesystem), NFS, LVM (host-local block volumes), and iSCSI (network block that attaches via the control plane, with per-node LUN masking). Together they show the backend contract generalises across very different storage shapes (network block, distributed filesystem, network filesystem, host-local block, and control-plane attach).

The headline capability — one StorageClass provisioning across multiple backend instances/zones — is itself backend-agnostic: most CSI drivers bake a single backend target into the StorageClass, so a class can reach only one. Bard resolves the target per-volume from where the workload is scheduled instead.

Why this is different

A normal CSI bakes the target backend (e.g. a specific Ceph cluster's monitors) into the StorageClass, so a class can only ever reach one instance. bard-csi inverts that:

  • The StorageClass names only a backend type (e.g. backend: ceph-rbd) and a logical pool/location — not a specific instance.
  • With volumeBindingMode: WaitForFirstConsumer, provisioning is deferred until a pod is scheduled.
  • The node plugin reports its zone via NodeGetInfo; the external-provisioner (with Topology=true) feeds that zone into CreateVolume.
  • The dispatcher maps zone → a concrete backend instance.
  • Each backend plugin resolves its own per-instance credentials from a Secret it mounts, keyed by instance id (for the Ceph plugin, a cephx key) — not via StorageClass secret params (which have no node-zone token and so can't select a per-instance secret).

Net result: one StorageClass, N backend instances (e.g. N Ceph clusters), picked per-volume by where the workload landed.

Architecture

Bard core is backend-agnostic: it implements the CSI spec, resolves topology to a backend instance, and proxies every operation to an out-of-tree plugin over a unix socket. Storage backends — including the first-party Ceph RBD one — are plugins that bring their own tools; core ships none (its image is a ~22 MB static distroless binary). See docs/writing-a-plugin.md.

┌────────────────────────────────────────────────┐
│  Bard core  (distroless, backend-agnostic)     │
│   CSI gRPC (Identity/Controller/Node)          │  internal/driver
│   Dispatcher: zone → backend instance          │  internal/dispatch
│   Plugin proxy (backend registry)              │  internal/backend(/plugin)
└───────────────┬────────────────────────────────┘
                │  HTTP+JSON over a unix socket   (pkg/bardplugin)
        ┌───────┴────────┐
        ▼                ▼
   ceph-rbd plugin    nfs plugin          (sidecars; ship their own tools)
   cmd/bard-plugin-*  internal/cephplugin
Package Responsibility
pkg/bardplugin Public plugin SDK: the HTTP+JSON contract, the Backend interface, and Serve(). Plugins can be written in any language.
internal/backend Internal Backend interface + capability model + registry (what core programs against).
internal/backend/plugin Client: dials a plugin's socket and implements backend.Backend by proxying to it.
internal/cephplugin Ceph RBD plugin backend — depends only on pkg/bardplugin, exactly like a third-party plugin.
cmd/bard-plugin-ceph-rbd, cmd/bard-plugin-nfs The plugin binaries (own images, own tools).
internal/dispatch Resolves (StorageClass params, topology)(backend, instance, zone).
internal/driver The three CSI gRPC services + the unix-socket gRPC server.
internal/volumeid The self-describing CSI volume handle (swsk|1|ceph-rbd|east|pool|name).
internal/config Loads the backend/instance/zone config from BackendCluster CRs (listed from the API at startup) or a file.
cmd/bard-csi Core binary; runs as --controller or --node.

Adding a backend

Every backend — including the first-party Ceph RBD one — is an out-of-tree plugin, so you add one without forking Bard or rebuilding core:

  1. Implement the small HTTP+JSON contract (Go authors implement bardplugin.Backend and call Serve(); any language works).
  2. Ship it as a container; run it as a sidecar in Bard's controller + node pods, sharing the plugin socket dir.
  3. Add a plugin backend entry to Bard's config pointing at the socket.

See docs/writing-a-plugin.md. Worked examples: Ceph RBD (network block, RWO), CephFS (distributed filesystem, RWX), NFS (a network filesystem), LVM (host-local block, RWO), iSCSI (network block with control-plane attach — the reference ControllerPublish backend, masking a LUN to the node's initiator), and localpath — a directory bind-mount written in Python, stdlib only, the standing proof that "any language" is literal: not a line of Go, yet core dispatches to it identically. The division of labour: the plugin brings the tools; Bard core helps them talk to Kubernetes; the host provides kernel capabilities (rbd/nbd modules, /dev).

Build & test

make build     # -> bin/bard-csi
make test
make vet
make image VERSION=0.1.0

Deploy

Raw manifests:

# The CRD must exist before its CRs; apply it first, then the rest.
kubectl apply -f deploy/05-crd-backendcluster.yaml
# Edit deploy/20-config.yaml (BackendCluster clusters/zones) and the Secret keys.
kubectl apply -f deploy/

Or the Helm chart (charts/bard-csi), which assembles the driver runtime + the backend plugin sidecars you enable (backend connection config + credentials stay yours, referenced by name):

helm install bard-csi charts/bard-csi -n kube-system --set 'plugins.ceph-rbd.enabled=true'

Manifests: 00-csidriver, 05-crd-backendcluster (the BackendCluster CRD), 10-rbac, 20-config (BackendCluster CRs + the plugin's ConfigMap/Secret), 30-controller (Deployment + provisioner/snapshotter/resizer sidecars), 40-node (DaemonSet + node-driver-registrar), 50-storageclass (StorageClass + VolumeSnapshotClass + VolumeGroupSnapshotClass + VolumeAttributesClass). Core reads its backends from the BackendCluster CRs at startup (--config-source=crd); --config-source=file keeps the old ConfigMap path for out-of-cluster runs.

Day-2: the consistency scanner

Kubernetes only knows what its own objects claim. kubectl bard inspect joins that against backend truth — what actually exists on every configured backend, enumerated through the same plugin contract core provisions with — plus the driver's topology config, and reports the drift: PVs whose backing volume is gone, orphaned volumes eating pool space after a failed delete, stale attachments left by a dead node, zone labels that will crashloop the registrar. Read-only, every finding carries a remediation hint, exit codes made for cron. See docs/inspect.md.

go install github.com/kindacoolhamster/bard-csi/cmd/kubectl-bard@latest
kubectl bard inspect

Status

The implemented-feature inventory and the roadmap live in STATUS.md.

The six backends are not equally proven, and the feature list is the union across all of them. Ceph RBD and iSCSI are the two carrying real weight (Stable); CephFS is Beta; NFS and LVM are Experimental; localpath is a Python reference plugin, not for production. See Backend maturity for what each tier means and the per-backend caveats.

Contributing & license

Contributions welcome — see CONTRIBUTING.md; backend plugins in any language are the easiest entry point (docs/writing-a-plugin.md). Security reports: SECURITY.md. Licensed under Apache-2.0.

Directories

Path Synopsis
cmd
bard-csi command
Command bard-csi is the unified CSI driver binary.
Command bard-csi is the unified CSI driver binary.
bard-plugin-ceph-rbd command
Command bard-plugin-ceph-rbd is the Ceph RBD backend as an out-of-tree Bard plugin.
Command bard-plugin-ceph-rbd is the Ceph RBD backend as an out-of-tree Bard plugin.
bard-plugin-cephfs command
Command bard-plugin-cephfs is the CephFS backend as an out-of-tree Bard plugin.
Command bard-plugin-cephfs is the CephFS backend as an out-of-tree Bard plugin.
bard-plugin-conformance command
bard-plugin-conformance drives a Bard backend plugin over its unix socket the way Bard core would and verifies it honors the wire contract: required semantics (idempotent create/delete, error codes, identity rules, unknown- field tolerance) plus every optional capability the plugin declares.
bard-plugin-conformance drives a Bard backend plugin over its unix socket the way Bard core would and verifies it honors the wire contract: required semantics (idempotent create/delete, error codes, identity rules, unknown- field tolerance) plus every optional capability the plugin declares.
bard-plugin-iscsi command
Command bard-plugin-iscsi is the iSCSI backend as an out-of-tree Bard plugin -- the reference ATTACH-style backend (control-plane LUN masking via ControllerPublish).
Command bard-plugin-iscsi is the iSCSI backend as an out-of-tree Bard plugin -- the reference ATTACH-style backend (control-plane LUN masking via ControllerPublish).
bard-plugin-lvm command
Command bard-plugin-lvm is the LVM backend as an out-of-tree Bard plugin.
Command bard-plugin-lvm is the LVM backend as an out-of-tree Bard plugin.
bard-plugin-nfs command
Command bard-plugin-nfs is an out-of-tree Bard CSI backend for NFS, and a worked example of the bardplugin SDK.
Command bard-plugin-nfs is an out-of-tree Bard CSI backend for NFS, and a worked example of the bardplugin SDK.
kubectl-bard command
Command kubectl-bard is the kubectl plugin front-end for Bard's day-2 tooling: put it on PATH and `kubectl bard inspect` runs the consistency scanner inside the controller pod (the only place the backend plugin sockets are reachable) and streams the report back.
Command kubectl-bard is the kubectl plugin front-end for Bard's day-2 tooling: put it on PATH and `kubectl bard inspect` runs the consistency scanner inside the controller pod (the only place the backend plugin sockets are reachable) and streams the report back.
internal
backend
Package backend defines the abstraction every storage backend implements.
Package backend defines the abstraction every storage backend implements.
backend/plugin
Package plugin adapts an out-of-tree backend (a bardplugin HTTP+JSON server on a unix socket) to Bard's internal backend.Backend interface, so the rest of the driver treats a plugin exactly like a built-in backend.
Package plugin adapts an out-of-tree backend (a bardplugin HTTP+JSON server on a unix socket) to Bard's internal backend.Backend interface, so the rest of the driver treats a plugin exactly like a built-in backend.
cephenc
Package cephenc is the backend-agnostic encryption layer shared by Bard's Ceph plugins (ceph-rbd, cephfs): the pluggable KMS providers that resolve a per-volume passphrase, and the fscrypt key/policy helpers.
Package cephenc is the backend-agnostic encryption layer shared by Bard's Ceph plugins (ceph-rbd, cephfs): the pluggable KMS providers that resolve a per-volume passphrase, and the fscrypt key/policy helpers.
cephfsplugin
Package cephfsplugin is the CephFS backend as an out-of-tree Bard plugin.
Package cephfsplugin is the CephFS backend as an out-of-tree Bard plugin.
cephplugin
Package cephplugin is the Ceph RBD backend as an out-of-tree Bard plugin.
Package cephplugin is the Ceph RBD backend as an out-of-tree Bard plugin.
config
Package config loads the driver's backend configuration.
Package config loads the driver's backend configuration.
conformance
Package conformance drives a Bard backend plugin over its unix socket, the way Bard core would, and verifies it honors the wire contract (pkg/bardplugin): the required semantics every plugin must implement (idempotency, error codes, identity rules) plus every optional capability the plugin declares.
Package conformance drives a Bard backend plugin over its unix socket, the way Bard core would, and verifies it honors the wire contract (pkg/bardplugin): the required semantics every plugin must implement (idempotency, error codes, identity rules) plus every optional capability the plugin declares.
dispatch
Package dispatch resolves a provisioning request to a concrete backend instance using CSI topology.
Package dispatch resolves a provisioning request to a concrete backend instance using CSI topology.
driver
CSI-Addons is an out-of-CSI-spec extension API (github.com/csi-addons) served over its own gRPC endpoint and driven by the csi-addons sidecar + controller (e.g.
CSI-Addons is an out-of-CSI-spec extension API (github.com/csi-addons) served over its own gRPC endpoint and driven by the csi-addons sidecar + controller (e.g.
fakerun
Package fakerun is an in-memory simulation of the external commands the Ceph RBD backend shells out to (rbd, mount, blkid, findmnt, mkfs, ...).
Package fakerun is an in-memory simulation of the external commands the Ceph RBD backend shells out to (rbd, mount, blkid, findmnt, mkfs, ...).
incluster
Package incluster does minimal authenticated reads against the Kubernetes API from inside a pod, using the ServiceAccount token + the API server CA the kubelet projects into every container.
Package incluster does minimal authenticated reads against the Kubernetes API from inside a pod, using the ServiceAccount token + the API server CA the kubelet projects into every container.
inspect
Package inspect implements Bard's consistency scanner: it joins what Kubernetes believes (PVs, VolumeSnapshotContents, VolumeAttachments, node topology) against backend truth (what actually exists on each backend, via the plugins' ListVolumes/ListSnapshots) and the driver's own config, and reports the drift as findings — ghost PVs whose backing volume is gone, orphaned backend volumes no PV references, snapshot mismatches, and topology misconfiguration.
Package inspect implements Bard's consistency scanner: it joins what Kubernetes believes (PVs, VolumeSnapshotContents, VolumeAttachments, node topology) against backend truth (what actually exists on each backend, via the plugins' ListVolumes/ListSnapshots) and the driver's own config, and reports the drift as findings — ghost PVs whose backing volume is gone, orphaned backend volumes no PV references, snapshot mismatches, and topology misconfiguration.
iscsiplugin
Package iscsiplugin is an iSCSI backend as an out-of-tree Bard plugin, and the reference ATTACH-style backend: unlike Ceph RBD/LVM (which map on the node), making an iSCSI volume reachable is a control-plane operation.
Package iscsiplugin is an iSCSI backend as an out-of-tree Bard plugin, and the reference ATTACH-style backend: unlike Ceph RBD/LVM (which map on the node), making an iSCSI volume reachable is a control-plane operation.
lvmplugin
Package lvmplugin is an LVM backend as an out-of-tree Bard plugin.
Package lvmplugin is an LVM backend as an out-of-tree Bard plugin.
metrics
Package metrics exposes Prometheus-format gRPC operation metrics for the Bard CSI driver over a stdlib HTTP server -- deliberately NO prometheus/client_golang dependency, the same lean-image discipline as the rest of the driver (hand-rolled SigV4, KMIP as the only sanctioned dep).
Package metrics exposes Prometheus-format gRPC operation metrics for the Bard CSI driver over a stdlib HTTP server -- deliberately NO prometheus/client_golang dependency, the same lean-image discipline as the rest of the driver (hand-rolled SigV4, KMIP as the only sanctioned dep).
nfsplugin
Package nfsplugin is the NFS backend as an out-of-tree Bard plugin, and a worked example of the bardplugin SDK exercising a very different backend shape than Ceph RBD: each volume is a subdirectory of an export (created on the controller side, mounted on the node side) -- the nfs-subdir pattern.
Package nfsplugin is the NFS backend as an out-of-tree Bard plugin, and a worked example of the bardplugin SDK exercising a very different backend shape than Ceph RBD: each volume is a subdirectory of an export (created on the controller side, mounted on the node side) -- the nfs-subdir pattern.
volumeid
Package volumeid encodes and decodes CSI volume handles.
Package volumeid encodes and decodes CSI volume handles.
pkg
bardplugin
Package bardplugin is the public SDK for writing out-of-tree Bard CSI storage backends.
Package bardplugin is the public SDK for writing out-of-tree Bard CSI storage backends.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL