Skip to content

API Reference

Packages

storage.simplyblock.io/v1alpha1

Package v1alpha1 contains API Schema definitions for the simplyblock v1alpha1 API group.

Resource Types

ActionStatus

Appears in: - StorageClusterStatus

Example:

action: string
nodeUUID: string
state: string
message: string
updatedAt: Time
observedGeneration: integer
triggered: boolean
subPhase: string
volumesMigrated: integer
volumesPending: integer
Field Description Default Validation
action string Action is the requested action name.
nodeUUID string NodeUUID is the target node UUID for the action.
state string
message string Message is a human-readable action result or error.
updatedAt Time ⧉ UpdatedAt is the timestamp of the last status transition.
observedGeneration integer ObservedGeneration is the resource generation observed by this status.
triggered boolean Triggered indicates whether the underlying backend action has been fired.
subPhase string SubPhase tracks the active drain step within the remove action. Enum: [Validating Suspending Migrating Verifying Removing]
Optional: {}
volumesMigrated integer VolumesMigrated is the count of volumes successfully migrated so far. Optional: {}
volumesPending integer VolumesPending is the count of volumes still awaiting migration. Optional: {}

AttachedLvol

AttachedLvol records a single PVC-to-lvol attachment managed by this policy.

Appears in: - BackupPolicyStatus

Example:

pvcName: string
pvcNamespace: string
lvolID: string
Field Description Default Validation
pvcName string PVCName is the name of the PVC.
pvcNamespace string PVCNamespace is the namespace of the PVC.
lvolID string LvolID is the Simplyblock logical volume UUID that this policy is attached to.

BackupCredentialsSecretRef

Appears in: - BackupSpec

Example:

name: string
Field Description Default Validation
name string Name is the name of the Secret in the same namespace as the cluster CR.

BackupImport

BackupImport imports a completed backup from a source cluster into a target cluster, creating a StorageBackup CR that can be referenced by a BackupRestore.

Example:

apiVersion: storage.simplyblock.io/v1alpha1
kind: BackupImport
metadata:
  name: string
spec:
  sourceClusterName: string
  sourceBackupID: '^[a-zA-Z0-9_-]{1,128}$'
  targetClusterName: string
status:
  phase: string
  message: string
  sourceClusterUUID: string
  targetClusterUUID: string
  importedBackupID: string
  storageBackupRef: string
  completedAt: Time
Field Description Default Validation
apiVersion string storage.simplyblock.io/v1alpha1
kind string BackupImport
metadata ObjectMeta ⧉ Refer to Kubernetes API documentation for fields of metadata. Optional: {}
spec BackupImportSpec spec defines the desired state of BackupImport Required: {}
status BackupImportStatus status defines the observed state of BackupImport Optional: {}

BackupImportSpec

BackupImportSpec defines the desired state of BackupImport.

Appears in: - BackupImport

Example:

sourceClusterName: string
sourceBackupID: '^[a-zA-Z0-9_-]{1,128}$'
targetClusterName: string
Field Description Default Validation
sourceClusterName string SourceClusterName is the StorageCluster CR name of the cluster that owns the backup.
sourceBackupID string SourceBackupID is the UUID of the backup on the source cluster to import. Pattern: ^[a-zA-Z0-9_-]\{1,128\}$
targetClusterName string TargetClusterName is the StorageCluster CR name of the cluster to import into.

BackupImportStatus

BackupImportStatus defines the observed state of BackupImport.

Appears in: - BackupImport

Example:

phase: string
message: string
sourceClusterUUID: string
targetClusterUUID: string
importedBackupID: string
storageBackupRef: string
completedAt: Time
Field Description Default Validation
phase string Phase is the high-level lifecycle shown in kubectl output.
message string Message contains the latest reconciliation detail or error.
sourceClusterUUID string SourceClusterUUID is the resolved UUID of the source cluster.
targetClusterUUID string TargetClusterUUID is the resolved UUID of the target cluster.
importedBackupID string ImportedBackupID is the backup UUID after successful import into the target cluster.
storageBackupRef string StorageBackupRef is the name of the StorageBackup CR created in the target namespace
after a successful import. This CR can be referenced directly in a BackupRestore.
completedAt Time ⧉ CompletedAt is when the import completed.

BackupPolicy

BackupPolicy is the Schema for the backuppolicies API.

A BackupPolicy defines retention and scheduling parameters for Simplyblock backups. To apply a policy to a PVC, annotate the PVC with:

simplyblock.io/backup-policy: <BackupPolicy-name>

The deprecated simplybk/backup-policy annotation is still honoured for backwards compatibility; when both are set, simplyblock.io/backup-policy takes precedence.

The BackupPolicy must be in the same namespace as the annotated PVC. The controller attaches and detaches the policy in the Simplyblock backend whenever the annotation is added or removed.

Example:

apiVersion: storage.simplyblock.io/v1alpha1
kind: BackupPolicy
metadata:
  name: string
spec:
  clusterName: string
  maxVersions: integer
  maxAge: '^[1-9]\d*[mhdw]$'
  schedule: '^(\d+[mhdw],\d+)( +\d+[mhdw],\d+)*$'
status:
  phase: string
  message: string
  clusterUUID: string
  policyID: string
  attachedLvols:
    - pvcName: string
      pvcNamespace: string
      lvolID: string
Field Description Default Validation
apiVersion string storage.simplyblock.io/v1alpha1
kind string BackupPolicy
metadata ObjectMeta ⧉ Refer to Kubernetes API documentation for fields of metadata. Optional: {}
spec BackupPolicySpec spec defines the desired state of BackupPolicy Required: {}
status BackupPolicyStatus status defines the observed state of BackupPolicy Optional: {}

BackupPolicySpec

BackupPolicySpec defines the desired state of BackupPolicy.

Appears in: - BackupPolicy

Example:

clusterName: string
maxVersions: integer
maxAge: '^[1-9]\d*[mhdw]$'
schedule: '^(\d+[mhdw],\d+)( +\d+[mhdw],\d+)*$'
Field Description Default Validation
clusterName string ClusterName is the target storage cluster name.
maxVersions integer MaxVersions is the maximum number of completed backup versions to retain.
When exceeded, the oldest backup is merged into the second-oldest.
Optional: {}
maxAge string MaxAge is the maximum age of backups to retain (e.g. "7d", "12h", "30m").
Backups older than this are merged. Accepts m, h, d, w suffixes.
Pattern: ^[1-9]\d*[mhdw]$
Optional: {}
schedule string Schedule defines the tiered backup schedule as a space-separated list of
interval,keep_count pairs (e.g. "15m,4 60m,11 24h,7").
Intervals must be strictly increasing. Supported units: m, h, d, w.
Pattern: ^(\d+[mhdw],\d+)( +\d+[mhdw],\d+)*$
Optional: {}

BackupPolicyStatus

BackupPolicyStatus defines the observed state of BackupPolicy.

Appears in: - BackupPolicy

Example:

phase: string
message: string
clusterUUID: string
policyID: string
attachedLvols:
  - pvcName: string
    pvcNamespace: string
    lvolID: string
Field Description Default Validation
phase string Phase is the high-level lifecycle state of the policy.
message string Message contains the latest reconciliation detail or error.
clusterUUID string ClusterUUID is the resolved backend cluster UUID.
policyID string PolicyID is the UUID assigned to this policy by the Simplyblock backend.
attachedLvols AttachedLvol array AttachedLvols lists the PVCs (and their lvol IDs) currently attached to
this policy in the Simplyblock backend. The controller uses this to detect
and reconcile annotation additions and removals.

BackupRef

BackupRef identifies the StorageBackup to restore from, scoped to the same namespace.

Appears in: - BackupRestoreSpec

Example:

name: string
Field Description Default Validation
name string Name is the StorageBackup resource name.

BackupRestore

BackupRestore is the Schema for the backuprestores API.

Example:

apiVersion: storage.simplyblock.io/v1alpha1
kind: BackupRestore
metadata:
  name: string
spec:
  clusterName: string
  backupRef:
    name: string
  targetPool: string
  targetNode: string
  pvcTemplate:
    metadata:
      name: string
    spec: PersistentVolumeClaimSpec
status:
  phase: string
  message: string
  clusterUUID: string
  backupID: string
  sourceLvolID: string
  fsType: string
  poolName: string
  poolUUID: string
  restoredLvolID: string
  pvName: string
  pvcName: string
  pvcNamespace: string
  sourceClusterUUID: string
  startedAt: Time
  completedAt: Time
Field Description Default Validation
apiVersion string storage.simplyblock.io/v1alpha1
kind string BackupRestore
metadata ObjectMeta ⧉ Refer to Kubernetes API documentation for fields of metadata. Optional: {}
spec BackupRestoreSpec spec defines the desired state of BackupRestore Required: {}
status BackupRestoreStatus status defines the observed state of BackupRestore Optional: {}

BackupRestoreSpec

BackupRestoreSpec defines the desired state of BackupRestore.

Appears in: - BackupRestore

Example:

clusterName: string
backupRef:
  name: string
targetPool: string
targetNode: string
pvcTemplate:
  metadata:
    name: string
  spec: PersistentVolumeClaimSpec
Field Description Default Validation
clusterName string ClusterName is the target storage cluster name.
backupRef BackupRef BackupRef references the StorageBackup resource to restore from.
targetPool string TargetPool overrides the pool to restore into.
Defaults to the source backup's pool.
Optional: {}
targetNode string TargetNode is the UUID of the storage node to restore onto.
Defaults to the node that originally held the backup.
Optional: {}
pvcTemplate PVCTemplate PVCTemplate describes the PVC to create once the restore completes.

BackupRestoreStatus

BackupRestoreStatus defines the observed state of BackupRestore.

Appears in: - BackupRestore

Example:

phase: string
message: string
clusterUUID: string
backupID: string
sourceLvolID: string
fsType: string
poolName: string
poolUUID: string
restoredLvolID: string
pvName: string
pvcName: string
pvcNamespace: string
sourceClusterUUID: string
startedAt: Time
completedAt: Time
Field Description Default Validation
phase string Phase is the high-level lifecycle shown in kubectl output.
message string Message contains the latest reconciliation detail or error.
clusterUUID string ClusterUUID is the backend cluster UUID.
backupID string BackupID is the backend backup UUID being restored.
sourceLvolID string SourceLvolID is the original logical volume UUID that was backed up.
fsType string FSType is the filesystem type of the original source volume, copied from
the referenced StorageBackup's status.fsType. Set on the restored
PersistentVolume so it mounts with the same filesystem it was backed up
with, instead of the CSI driver's default.
poolName string PoolName is the pool the restore was issued against.
poolUUID string PoolUUID is the backend pool UUID.
restoredLvolID string RestoredLvolID is the UUID of the newly-created logical volume.
pvName string PVName is the name of the PersistentVolume created by the controller.
pvcName string PVCName is the name of the PersistentVolumeClaim created from pvcTemplate.
pvcNamespace string PVCNamespace is the namespace of the created PVC.
sourceClusterUUID string SourceClusterUUID is the UUID of the cluster that originally created the backup.
Copied from the referenced StorageBackup's status.sourceClusterUUID. When non-empty
and different from ClusterUUID, the controller resolves that cluster's backup
credentials and sends them with the restore request, since the backup's bucket may
not be this cluster's own.
startedAt Time ⧉ StartedAt is when the backend restore task was accepted.
completedAt Time ⧉ CompletedAt is when the PVC became bound.

BackupSpec

Appears in: - StorageClusterSpec

Example:

localEndpoint: '^https?://[a-zA-Z0-9.-]+(:[0-9]{1,5})?(/.*)?$'
snapshotBackups: boolean
withCompression: boolean
secondaryTarget: integer
localTesting: boolean
credentialsSecretRef:
  name: string
Field Description Default Validation
localEndpoint string Pattern: ^https?://[a-zA-Z0-9.-]+(:[0-9]\{1,5\})?(/.*)?$
snapshotBackups boolean Optional: {}
withCompression boolean Optional: {}
secondaryTarget integer Optional: {}
localTesting boolean Optional: {}
credentialsSecretRef BackupCredentialsSecretRef CredentialsSecretRef points to the Secret holding access_key_id and secret_access_key.

CapacityThresholdSpec

Appears in: - StorageClusterSpec

Example:

capacity: integer
provisionedCapacity: integer
Field Description Default Validation
capacity integer Capacity defines the absolute capacity threshold value.
provisionedCapacity integer ProvisionedCapacity defines the provisioned-capacity threshold value.

ControlPlane

ControlPlane is a singleton resource (one per namespace, named "simplyblock") that reflects the readiness of the simplyblock control plane. It is created automatically by the Helm chart and should not be created or deleted manually.

Example:

apiVersion: storage.simplyblock.io/v1alpha1
kind: ControlPlane
metadata:
  name: string
spec:
  image: '^($|(quay\.io/simplyblock-io|docker\.io/simplyblock|public\.ecr\.aws/simply-block)/[a-z0-9][a-z0-9._-]*:[a-zA-Z0-9][a-zA-Z0-9._-]*(@sha256:[a-f0-9]{64})?)$'
status:
  phase: string
  message: string
  lastChecked: Time
Field Description Default Validation
apiVersion string storage.simplyblock.io/v1alpha1
kind string ControlPlane
metadata ObjectMeta ⧉ Refer to Kubernetes API documentation for fields of metadata. Optional: {}
spec ControlPlaneSpec Optional: {}
status ControlPlaneStatus Optional: {}

ControlPlaneSpec

ControlPlaneSpec holds configuration for the singleton ControlPlane resource created by the Helm chart.

Appears in: - ControlPlane

Example:

image: '^($|(quay\.io/simplyblock-io|docker\.io/simplyblock|public\.ecr\.aws/simply-block)/[a-z0-9][a-z0-9._-]*:[a-zA-Z0-9][a-zA-Z0-9._-]*(@sha256:[a-f0-9]{64})?)$'
Field Description Default Validation
image string Image is the container image used for all simplyblock control-plane and
storage-node workloads (e.g. quay.io/simplyblock-io/simplyblock:26.2.2).
StorageNodeSet CRs that omit spec.clusterImage inherit this value.
Must reference one of the trusted registries (quay.io/simplyblock-io, docker.io/simplyblock, public.ecr.aws/simply-block); digest pinning (@sha256:...) is recommended.
Pattern: ^($\|(quay\.io/simplyblock-io\|docker\.io/simplyblock\|public\.ecr\.aws/simply-block)/[a-z0-9][a-z0-9._-]*:[a-zA-Z0-9][a-zA-Z0-9._-]*(@sha256:[a-f0-9]\{64\})?)$
Optional: {}

ControlPlaneStatus

ControlPlaneStatus reflects the observed readiness of the simplyblock control plane (FDB + management API).

Appears in: - ControlPlane

Example:

phase: string
message: string
lastChecked: Time
Field Description Default Validation
phase string Phase is Initializing while the control plane is not yet healthy,
and Ready once the FDB health check passes.
Enum: [Initializing Ready]
message string Message contains a human-readable explanation of the current phase,
for example the FDB error returned by the health endpoint.
lastChecked Time ⧉ LastChecked is the timestamp of the most recent FDB health probe.

DataRealignmentSettings

DataRealignmentSettings controls the periodic, post-migration control-plane data realignment. After one or more volumes have been moved the operator asks the control plane to re-align its internal data structures to the new placement, restoring fault-tolerance (FTT) and node-affinity guarantees.

Appears in: - VolumeMigrationSettings

Example:

enabled: boolean
interval: Duration
minMoves: integer
Field Description Default Validation
enabled boolean Enabled activates automatic post-migration data realignment for this cluster.
Defaults to true.
Optional: {}
interval Duration ⧉ Interval is how often the operator checks whether a realignment is pending
(i.e. at least one volume has moved since the last successful realignment) and,
if so, triggers it. Explicit triggers (see the
simplyblock.io/trigger-realignment annotation) bypass this spacing. Defaults to
10m.
Note that this is a floor on the spacing between realignment requests, not a
ceiling on how long one takes: a realignment blocks all volume migrations for as
long as the control plane needs, which on a busy cluster has been measured at
tens of minutes. An interval shorter than that means the next realignment is
requested as soon as the previous one finishes and any volume has moved, which is
what MinMoves exists to damp.
Optional: {}
minMoves integer MinMoves is how many volume moves must accumulate before a realignment is
triggered. Defaults to 1: every completed migration schedules a realignment.
Raise it to batch. Because the control plane refuses new migrations while a
realignment runs, a value of 1 makes the two alternate — one migration completes,
a realignment follows and blocks migrations until it is done. On a cluster where
realignment takes tens of minutes that is most of the available time, so a run
that migrates continuously spends the majority of it waiting. A higher value
trades realignment promptness (data structures stay unaligned for longer, so
fault-tolerance and node-affinity guarantees are restored later) for migration
throughput.
Explicit triggers (the simplyblock.io/trigger-realignment annotation) ignore this
threshold, so a drain or node removal still realigns immediately.
Minimum: 1
Optional: {}

DrainOpsSpec

DrainOpsSpec configures the drain workflow for action=remove.

Appears in: - StorageNodeOpsSpec

Example:

systemVolumeFilterRegex: string
Field Description Default Validation
systemVolumeFilterRegex string SystemVolumeFilterRegex is a Go regular expression matched against backend
volume names. Matching volumes are treated as system volumes: excluded from
drain migration and deleted inline during the Verifying phase.
Defaults to "^sb-fio-baseline-.*".
Optional: {}

HashicorpVaultSettings

HashicorpVaultSettings configures the HashiCorp Vault endpoint the cluster uses to store keys.

Appears in: - StorageClusterSpec

Example:

baseURL: '^https?://[a-zA-Z0-9.-]+(:[0-9]{1,5})?(/.*)?$'
Field Description Default Validation
baseURL string BaseURL is the HashiCorp Vault endpoint (e.g. https://vault.example.com:8200). Pattern: ^https?://[a-zA-Z0-9.-]+(:[0-9]\{1,5\})?(/.*)?$

JournalManagerSpec

JournalManagerSpec defines journal manager tuning parameters.

Appears in: - StorageNodeOverrides - StorageNodeSetSpec

Example:

count: integer
percentPerDevice: integer
Field Description Default Validation
count integer Count is the number of journal managers to configure.
percentPerDevice integer PercentPerDevice is the journal manager capacity percentage per device.

MetricsBackend

Underlying type: string

MetricsBackend selects the NodeMetricsProvider implementation.

Validation: - Enum: [controlplane prometheus uniform]

Appears in: - VolumeAutoPlacementSettings

Field Description
controlplane
prometheus
uniform MetricsBackendUniform returns IOPS=1 for every node, disabling
IOPS-based scoring while keeping capacity/volume-count balancing active.

MigrationConnection

MigrationConnection holds the NVMe-oF connection parameters for one path on the migration target node, as returned by the storage API's CreateMigration. All fields are passed verbatim to nvme connect in the validation Job.

Appears in: - VolumeMigrationStatus

Example:

nqn: string
ip: string
port: integer
transport: string
nrIoQueues: integer
reconnectDelay: integer
ctrlLossTmo: integer
fastIOFailTmo: integer
keepAliveTmo: integer
Field Description Default Validation
nqn string
ip string
port integer
transport string
nrIoQueues integer
reconnectDelay integer
ctrlLossTmo integer
fastIOFailTmo integer
keepAliveTmo integer

NodeDrainState

NodeDrainState tracks the upgrade-drain coordination state for a single worker node.

Appears in: - StorageNodeSetStatus

Example:

hostname: string
phase: string
startedAt: Time
message: string
activeNodeUUID: string
Field Description Default Validation
hostname string Hostname is the Kubernetes node name.
phase string Phase is the current drain coordination phase. Enum: [detected shutdown_called draining restart_called complete failed]
startedAt Time ⧉ StartedAt is when drain coordination began for this node.
message string Message provides additional status detail or error information.
activeNodeUUID string ActiveNodeUUID is the backend UUID of the storage node currently being shut
down or restarted. Used to sequence through multiple NUMA-socket nodes on
the same worker one at a time during drain coordination.

NodeLatencyMetrics

NodeLatencyMetrics holds fio-measured 4K NVMe-oF latency for a single backend storage node. The benchmark volume NQN and connection details are derived at runtime from the node UUID and the cluster NQN — they are not stored here.

Appears in: - StorageNodeSetStatus - StorageNodeStatus

Example:

nodeUUID: string
baselineP50NS: integer
baselineP99NS: integer
baselineMeasuredAt: Time
Field Description Default Validation
nodeUUID string NodeUUID is the backend storage node UUID.
baselineP50NS integer BaselineP50NS is the p50 write latency (nanoseconds) from the initial empty-cluster benchmark.
baselineP99NS integer BaselineP99NS is the p99 write latency (nanoseconds) from the initial empty-cluster benchmark.
baselineMeasuredAt Time ⧉ BaselineMeasuredAt is when the baseline was established.

NodeLoadMetrics

NodeLoadMetrics holds the latency deviation state for a single storage node.

Appears in: - RebalancingMetrics

Example:

nodeUUID: string
latencyDeviationPct: float
volumeCount: integer
lastUpdated: Time
Field Description Default Validation
nodeUUID string
latencyDeviationPct float
volumeCount integer
lastUpdated Time ⧉

NodeRecycleSpec

NodeRecycleSpec configures the node-recycle action behaviour.

Appears in: - StorageClusterSpec

Example:

refreshSNodeAPI: boolean
Field Description Default Validation
refreshSNodeAPI boolean RefreshSNodeAPI restarts the storage-node DaemonSet pod on each node
after the backend node is shut down and before it is restarted, ensuring
the latest image is running before the node comes back online.

NodeRecycleStatus

NodeRecycleStatus tracks in-progress state for the node-recycle action. All fields are persisted in CR status so the reconciler can resume after a requeue.

Appears in: - StorageClusterStatus

Example:

pendingNodes:
  - string
processedNodes:
  - string
nodePhase: string
phaseTriggered: boolean
Field Description Default Validation
pendingNodes string array PendingNodes is the ordered list of node UUIDs still to be recycled.
processedNodes string array ProcessedNodes is the list of node UUIDs already recycled.
nodePhase string NodePhase is the current step for the node being recycled:
"snode-refresh" | "snode-refresh-wait" | "shutting-down" | "restarting" | "rebalancing"
phaseTriggered boolean PhaseTriggered indicates the API call for the current NodePhase was already sent.

NodeStatus

Appears in: - StorageNodeSetStatus

Example:

uuid: string
health: boolean
status: string
cpu: integer
memory: string
volumes: integer
rpcPort: integer
lvolPort: integer
nvmfPort: integer
devices: string
uptime: string
hostname: string
mgmtIp: string
postedAt: Time
failureDomain: integer
Field Description Default Validation
uuid string UUID is the backend node UUID.
health boolean Health indicates whether health checks are currently passing.
status string Status is the backend lifecycle state for the node.
cpu integer CPU is the reported CPU allocation/count for the node.
memory string Memory is the reported memory value.
volumes integer Volumes is the current logical volume count.
rpcPort integer RpcPort is the node RPC service port.
lvolPort integer LvolPort is the logical-volume subsystem port.
nvmfPort integer NvmfPort is the NVMf service port.
devices string Devices is the backend summary of devices on this node.
uptime string Uptime is the reported node uptime value.
hostname string Hostname is the Kubernetes node hostname.
mgmtIp string MgmtIp is the management IP address for the node.
postedAt Time ⧉ PostedAt is when the storage-node add request was sent. Used to detect
timeout without blocking the reconcile goroutine.
failureDomain integer FailureDomain is the effective failure-domain group index for this node,
reflected from spec.nodeConfigs[hostname].failureDomain or spec.nodeFailureDomains[hostname].
Zero means unset.
Optional: {}

PVCTemplate

PVCTemplate describes the PVC the controller will create once the restore completes.

Appears in: - BackupRestoreSpec

Example:

metadata:
  name: string
spec: PersistentVolumeClaimSpec
Field Description Default Validation
metadata PVCTemplateMetadata Refer to Kubernetes API documentation for fields of metadata. Optional: {}
spec PersistentVolumeClaimSpec ⧉ Spec follows core PersistentVolumeClaimSpec.
spec.resources.requests.storage must be >= the backup size.

PVCTemplateMetadata

PVCTemplateMetadata describes the PVC metadata fields the controller honors.

Appears in: - PVCTemplate

Example:

name: string
labels:
  string: string
annotations:
  string: string
Field Description Default Validation
name string Optional: {}
labels object (keys:string, values:string) Optional: {}
annotations object (keys:string, values:string) Optional: {}

PersistentVolumeClaimRef

Appears in: - StorageBackupSpec

Example:

name: string
namespace: string
Field Description Default Validation
name string Name is the PVC name.
namespace string Namespace overrides the backup resource namespace for the PVC lookup.

RebalancingMetrics

RebalancingMetrics is written by the VolumeRebalancerReconciler each evaluation cycle.

Appears in: - StorageClusterStatus

Example:

avgDeviationPct: float
maxDeviationPct: float
hottestNodeUUID: string
coolestNodeUUID: string
imbalancePercent: float
lastEvaluatedAt: Time
lastMigrationAt: Time
nodeMetrics:
  - nodeUUID: string
    latencyDeviationPct: float
    volumeCount: integer
    lastUpdated: Time
Field Description Default Validation
avgDeviationPct float AvgDeviationPct is the mean latency deviation across all nodes.
maxDeviationPct float MaxDeviationPct is the highest per-node latency deviation (used as ImbalancePercent).
hottestNodeUUID string
coolestNodeUUID string
imbalancePercent float
lastEvaluatedAt Time ⧉
lastMigrationAt Time ⧉
nodeMetrics NodeLoadMetrics array

ReplicationOps

ReplicationOps is a one-shot user-driven CR for imperative replication operations: failover (planned or unplanned) and failback. The operator drives the backend calls to completion and records per-volume outcomes in status.results. Only one ReplicationOps may be active per ReplicationPolicy at a time, enforced via ReplicationPolicy.status.activeOpsRef.

Example:

apiVersion: storage.simplyblock.io/v1alpha1
kind: ReplicationOps
metadata:
  name: string
spec:
  action: string
  scope: string
  ref: string
  sourceClusterID: string
  deleteSource: boolean
status:
  phase: string
  subphase: string
  message: string
  startedAt: Time
  completedAt: Time
  results:
    - slotRef: string
      status: string
      detail: string
      targetLvolID: string
Field Description Default Validation
apiVersion string storage.simplyblock.io/v1alpha1
kind string ReplicationOps
metadata ObjectMeta ⧉ Refer to Kubernetes API documentation for fields of metadata.
spec ReplicationOpsSpec
status ReplicationOpsStatus

ReplicationOpsResult

ReplicationOpsResult holds the outcome for a single volume in a ReplicationOps.

Appears in: - ReplicationOpsStatus

Example:

slotRef: string
status: string
detail: string
targetLvolID: string
Field Description Default Validation
slotRef string SlotRef is the name of the ReplicationSlot CR.
status string Status is the outcome for this volume. Enum: [succeeded skipped failed]
detail string Detail is an optional human-readable note (error message or skip reason). Optional: {}
targetLvolID string TargetLvolID is the UUID of the volume on the target cluster (failover only). Optional: {}

ReplicationOpsSpec

ReplicationOpsSpec defines the desired state of a ReplicationOps.

Appears in: - ReplicationOps

Example:

action: string
scope: string
ref: string
sourceClusterID: string
deleteSource: boolean
Field Description Default Validation
action string Action is the operation to perform. Immutable.
failover: unplanned — promote target clone, source may be down.
failback: restore source as primary after a prior failover.
migration: planned cutover — calls replication_commit per volume; both clusters stay up.
State progression: replicating → cutover_pending → cutover_done.
Enum: [failover failback migration]
Required: {}
scope string Scope controls which volumes are affected. Immutable.
target: all volumes across every policy that uses the named ReplicationPair.
policy: all volumes managed by the named ReplicationPolicy CR.
volume: a single ReplicationSlot (planned or unplanned per-volume operation).
Enum: [target policy volume]
Required: {}
ref string Ref is the name of the resource identified by Scope:
a ReplicationPair name for scope=target,
a ReplicationPolicy name for scope=policy,
or a ReplicationSlot name for scope=volume. Immutable.
Required: {}
sourceClusterID string SourceClusterID is used for failback only. Omit to recover to the original source. Optional: {}
deleteSource boolean DeleteSource instructs the backend to delete the source volume after a
successful migration cutover. Only meaningful when action=migration.
Optional: {}

ReplicationOpsStatus

ReplicationOpsStatus holds the observed state of a ReplicationOps.

Appears in: - ReplicationOps

Example:

phase: string
subphase: string
message: string
startedAt: Time
completedAt: Time
results:
  - slotRef: string
    status: string
    detail: string
    targetLvolID: string
Field Description Default Validation
phase string Phase is the current lifecycle phase of this operation. Enum: [Pending Running Succeeded Failed]
Optional: {}
subphase string Subphase describes what the operation is currently doing within the phase
(e.g. "TriggeringFailover", "UpdatingSlotStatuses", "ReleasingLock").
Optional: {}
message string Message is a human-readable description of the current phase. Optional: {}
startedAt Time ⧉ StartedAt is when the operation began. Optional: {}
completedAt Time ⧉ CompletedAt is when the operation finished (successfully or not). Optional: {}
results ReplicationOpsResult array Results holds a per-volume summary of the operation outcome. Optional: {}

ReplicationPair

ReplicationPair defines the source and target clusters for a replication relationship. It is reusable configuration — multiple ReplicationPolicies may reference the same pair to replicate volumes between the same two clusters with different schedules or retention. The operator ensures the corresponding backend ReplicationTarget exists and stores its ID in status.backendTargetID for use by ReplicationPolicy resources.

Example:

apiVersion: storage.simplyblock.io/v1alpha1
kind: ReplicationPair
metadata:
  name: string
spec:
  sourceCluster: string
  targetCluster: string
status:
  ready: boolean
  backendTargetID: string
  message: string
  conditions:
    - Condition
  activeOpsRef: string
Field Description Default Validation
apiVersion string storage.simplyblock.io/v1alpha1
kind string ReplicationPair
metadata ObjectMeta ⧉ Refer to Kubernetes API documentation for fields of metadata.
spec ReplicationPairSpec
status ReplicationPairStatus

ReplicationPairSpec

ReplicationPairSpec defines the source and target clusters for a replication relationship.

Appears in: - ReplicationPair

Example:

sourceCluster: string
targetCluster: string
Field Description Default Validation
sourceCluster string SourceCluster is the name of the local StorageCluster (the replication source). Required: {}
targetCluster string TargetCluster is the name or UUID of the remote cluster (the replication target).
Immutable after creation.
Required: {}

ReplicationPairStatus

ReplicationPairStatus holds the observed state of a ReplicationPair.

Appears in: - ReplicationPair

Example:

ready: boolean
backendTargetID: string
message: string
conditions:
  - Condition
activeOpsRef: string
Field Description Default Validation
ready boolean Ready is true when the backend ReplicationTarget has been created and is available. Optional: {}
backendTargetID string BackendTargetID is the UUID of the backend ReplicationTarget resource. Optional: {}
message string Message provides a human-readable description of the current state. Optional: {}
conditions Condition ⧉ array Conditions holds standard Kubernetes condition types. Optional: {}
activeOpsRef string ActiveOpsRef is the name of the ReplicationOps currently holding the
target-scope lock on this pair. Only one scope=target ReplicationOps may
be active per pair at a time.
Optional: {}

ReplicationPolicy

ReplicationPolicy defines the replication schedule and retention for volumes replicated between the clusters defined by a ReplicationPair. A StorageClass or PVC references a policy via the storage.simplyblock.io/replication-policy annotation. The operator automatically creates one ReplicationSlot per bound PVC. Deletion is blocked while any ReplicationSlots reference this policy.

Example:

apiVersion: storage.simplyblock.io/v1alpha1
kind: ReplicationPolicy
metadata:
  name: string
spec:
  pairRef: string
  mode: string
  interval: string
  snapshotRetention: integer
status:
  ready: boolean
  backendPolicyID: string
  slotCount: integer
  activeOpsRef: string
  conditions:
    - Condition
Field Description Default Validation
apiVersion string storage.simplyblock.io/v1alpha1
kind string ReplicationPolicy
metadata ObjectMeta ⧉ Refer to Kubernetes API documentation for fields of metadata.
spec ReplicationPolicySpec
status ReplicationPolicyStatus

ReplicationPolicySpec

ReplicationPolicySpec defines the desired replication schedule and retention.

Appears in: - ReplicationPolicy

Example:

pairRef: string
mode: string
interval: string
snapshotRetention: integer
Field Description Default Validation
pairRef string PairRef is the name of the ReplicationPair that defines the source and target clusters.
Multiple ReplicationPolicies may reference the same pair with different schedules.
Required: {}
mode string Mode controls replication semantics.
failover: target is a DR standby; volumes are read-only on the target.
migration: planned online cutover to the target cluster.
failover Enum: [failover migration]
Optional: {}
interval string Interval is how often a replication snapshot is taken (e.g. "5m", "1h"). 5m Optional: {}
snapshotRetention integer SnapshotRetention is the minimum number of snapshots to retain on the target. 3 Minimum: 2
Optional: {}

ReplicationPolicyStatus

ReplicationPolicyStatus holds the observed state of a ReplicationPolicy.

Appears in: - ReplicationPolicy

Example:

ready: boolean
backendPolicyID: string
slotCount: integer
activeOpsRef: string
conditions:
  - Condition
Field Description Default Validation
ready boolean Ready is true when the backend ReplicationPolicy has been created. Optional: {}
backendPolicyID string BackendPolicyID is the UUID of the backend ReplicationPolicy resource. Optional: {}
slotCount integer SlotCount is the number of ReplicationSlot CRs currently managed by this policy. Optional: {}
activeOpsRef string ActiveOpsRef is the name of the currently running ReplicationOps CR.
Empty when no operation is in progress.
Optional: {}
conditions Condition ⧉ array Conditions holds standard Kubernetes condition types. Optional: {}

ReplicationSlot

ReplicationSlot tracks the live replication state for a single PVC. One ReplicationSlot is created per PVC by the PVCAnnotationWatcher controller when a PVC references a ReplicationPolicy via annotation. It is owned by its PVC, so deleting the PVC cascades deletion and triggers a backend detach via the slot finalizer. The ReplicationSlot reconciler drives all backend calls: attach, monitor, cutover, failover, and detach.

Example:

apiVersion: storage.simplyblock.io/v1alpha1
kind: ReplicationSlot
metadata:
  name: string
spec:
  policyRef: string
  pvcRef: string
  volumeID: string
status:
  state: string
  direction: string
  sourceLvolID: string
  targetLvolID: string
  targetNQN: string
  lastReplicatedAt: Time
  message: string
  conditions:
    - Condition
Field Description Default Validation
apiVersion string storage.simplyblock.io/v1alpha1
kind string ReplicationSlot
metadata ObjectMeta ⧉ Refer to Kubernetes API documentation for fields of metadata.
spec ReplicationSlotSpec
status ReplicationSlotStatus

ReplicationSlotSpec

ReplicationSlotSpec defines the identity of a per-volume replication slot.

Appears in: - ReplicationSlot

Example:

policyRef: string
pvcRef: string
volumeID: string
Field Description Default Validation
policyRef string PolicyRef is the name of the ReplicationPolicy governing this slot. Immutable. Required: {}
pvcRef string PVCRef is the name of the PVC being replicated. Immutable. Required: {}
volumeID string VolumeID is the backend lvol UUID of the source volume. Immutable.
Format: "::"
Required: {}

ReplicationSlotStatus

ReplicationSlotStatus holds the observed state of a ReplicationSlot.

Appears in: - ReplicationSlot

Example:

state: string
direction: string
sourceLvolID: string
targetLvolID: string
targetNQN: string
lastReplicatedAt: Time
message: string
conditions:
  - Condition
Field Description Default Validation
state string State is the current replication state for this slot. Enum: [attaching replicating cutover_pending cutover_done failed_over detaching error]
Optional: {}
direction string Direction is which side of the replication relationship this cluster holds. Enum: [source target]
Optional: {}
sourceLvolID string SourceLvolID is the UUID of the source volume on the source cluster. Optional: {}
targetLvolID string TargetLvolID is the UUID of the replicated volume on the target cluster. Optional: {}
targetNQN string TargetNQN is the NVMe NQN on the target cluster (populated after failover). Optional: {}
lastReplicatedAt Time ⧉ LastReplicatedAt is the timestamp of the last successful replication snapshot. Optional: {}
message string Message provides a human-readable description of the current state. Optional: {}
conditions Condition ⧉ array Conditions holds standard Kubernetes condition types. Optional: {}

StorageBackup

StorageBackup is the Schema for the storagebackups API.

Example:

apiVersion: storage.simplyblock.io/v1alpha1
kind: StorageBackup
metadata:
  name: string
spec:
  clusterName: string
  pvcRef:
    name: string
    namespace: string
  snapshotName: string
  sourceClusterUUID: string
status:
  phase: string
  apiStatus: string
  message: string
  clusterUUID: string
  pvcNamespace: string
  pvName: string
  poolName: string
  poolUUID: string
  lvolID: string
  lvolName: string
  fsType: string
  snapshotID: string
  snapshotName: string
  sourceClusterUUID: string
  backupID: string
  s3ID: integer
  nodeID: string
  prevBackupID: string
  size: integer
  allowedHosts:
    - 'map[string]string'
  createdAt: Time
  completedAt: Time
Field Description Default Validation
apiVersion string storage.simplyblock.io/v1alpha1
kind string StorageBackup
metadata ObjectMeta ⧉ Refer to Kubernetes API documentation for fields of metadata. Optional: {}
spec StorageBackupSpec spec defines the desired state of StorageBackup Required: {}
status StorageBackupStatus status defines the observed state of StorageBackup Optional: {}

StorageBackupSpec

StorageBackupSpec defines the desired state of StorageBackup.

Appears in: - StorageBackup

Example:

clusterName: string
pvcRef:
  name: string
  namespace: string
snapshotName: string
sourceClusterUUID: string
Field Description Default Validation
clusterName string ClusterName is the target storage cluster name.
pvcRef PersistentVolumeClaimRef PVCRef identifies the PVC whose backing Simplyblock volume should be snapshotted and backed up.
Not required when SourceClusterUUID is set (imported backup).
Optional: {}
snapshotName string SnapshotName optionally overrides the internally-created snapshot name. Optional: {}
sourceClusterUUID string SourceClusterUUID, when non-empty, marks this StorageBackup as imported from another cluster.
The StorageBackup controller will not create snapshots or backups for imported resources.
Set by the BackupImport controller; do not set manually.
Optional: {}

StorageBackupStatus

StorageBackupStatus defines the observed state of StorageBackup.

Appears in: - StorageBackup

Example:

phase: string
apiStatus: string
message: string
clusterUUID: string
pvcNamespace: string
pvName: string
poolName: string
poolUUID: string
lvolID: string
lvolName: string
fsType: string
snapshotID: string
snapshotName: string
sourceClusterUUID: string
backupID: string
s3ID: integer
nodeID: string
prevBackupID: string
size: integer
allowedHosts:
  - 'map[string]string'
createdAt: Time
completedAt: Time
Field Description Default Validation
phase string Phase is the high-level backup lifecycle shown in kubectl output.
apiStatus string APIStatus is the raw status returned by the backup API.
message string Message contains the latest reconciliation detail or error.
clusterUUID string ClusterUUID is the backend cluster UUID.
pvcNamespace string PVCNamespace is the resolved PVC namespace.
pvName string PVName is the bound PV name.
poolName string PoolName is the Simplyblock pool name derived from the CSI volume handle.
poolUUID string PoolUUID is the backend pool UUID.
lvolID string LvolID is the Simplyblock volume UUID.
lvolName string LvolName is the backend logical volume name.
fsType string FSType is the filesystem type of the source PersistentVolume (e.g. "ext4",
"xfs"), captured at backup time so a restore can preserve it regardless of
which StorageClass the restored PVC ends up using.
snapshotID string SnapshotID is the internally-created snapshot UUID used for the backup request.
snapshotName string SnapshotName is the snapshot name used for the backup request.
sourceClusterUUID string SourceClusterUUID is set for imported backups; identifies the cluster that originally
created the backup. When non-empty and different from the restore target cluster UUID,
BackupRestore will automatically perform source-switch operations around the restore.
backupID string BackupID is the backend backup UUID.
s3ID integer S3ID is the backend S3 object identifier.
nodeID string NodeID is the source storage node UUID.
prevBackupID string PrevBackupID links the previous backup in the chain.
size integer Size is the backup size in bytes.
allowedHosts object array AllowedHosts contains the allowed host metadata returned by the backup API.
createdAt Time ⧉ CreatedAt is when the backup was created.
completedAt Time ⧉ CompletedAt is when the backup completed.

StorageClassParameters

StorageClassParameters defines the default StorageClass parameter values for volumes in this pool. These are passed as-is to the CSI driver when the StorageClass is created. cluster_id and pool_name are always set automatically and cannot be overridden here.

IMPORTANT: StorageClass Parameters are immutable in the Kubernetes API, so this whole field is immutable once set (see StoragePoolSpec.StorageClassParameters) — there's no supported way to change a pool's StorageClass defaults after the pool is created. Create a new StoragePool instead.

Appears in: - StoragePoolSpec

Example:

qosRwIops: string
qosRwMbytes: string
qosRMbytes: string
qosWMbytes: string
encryption: boolean
fabric: string
maxNamespacePerSubsys: string
tune2fsReservedBlocks: string
filesystem: string
Field Description Default Validation
qosRwIops string QosRwIops sets the read/write IOPS limit (0 = unlimited). 0
qosRwMbytes string QosRwMbytes sets the read/write throughput limit in MB/s (0 = unlimited). 0
qosRMbytes string QosRMbytes sets the read throughput limit in MB/s (0 = unlimited). 0
qosWMbytes string QosWMbytes sets the write throughput limit in MB/s (0 = unlimited). 0
encryption boolean Encryption enables encryption for logical volumes. false
fabric string Fabric is the transport fabric (e.g. tcp). tcp
maxNamespacePerSubsys string MaxNamespacePerSubsys limits namespaces per NVMf subsystem. 1
tune2fsReservedBlocks string Tune2fsReservedBlocks sets the ext4 reserved-blocks percentage. Left unset, the node
plugin skips tune2fs entirely and mkfs.ext4's own default reserve applies, matching a
StorageClass that omits tune2fs_reserved_blocks. A default of "0" here would not be a
no-op: it actively runs tune2fs -m 0 on every volume, since the node plugin only skips
the call when the parameter is empty (see stageVolume in the CSI driver), not when it's
"0".
filesystem string Filesystem is the filesystem used to format logical volumes of this pool. xfs Enum: [ext4 xfs]

StorageCluster

StorageCluster is the Schema for the storageclusters API

Example:

apiVersion: storage.simplyblock.io/v1alpha1
kind: StorageCluster
metadata:
  name: string
spec:
  enableNodeAffinity: boolean
  stripe:
    dataChunks: integer
    parityChunks: integer
  action: string
  nodeRecycle:
    refreshSNodeAPI: boolean
  fabricType: string
  clientDataIfname: string
  nvmfBasePort: integer
  rpcBasePort: integer
  snodeApiPort: integer
  maxConcurrentWorkerRestarts: integer
  maxSubsystemCount: integer
  maxHugePagesSize: string
  vcpuCount: integer
  warningThreshold:
    capacity: integer
    provisionedCapacity: integer
  criticalThreshold:
    capacity: integer
    provisionedCapacity: integer
  backup:
    localEndpoint: '^https?://[a-zA-Z0-9.-]+(:[0-9]{1,5})?(/.*)?$'
    snapshotBackups: boolean
    withCompression: boolean
    secondaryTarget: integer
    localTesting: boolean
    credentialsSecretRef:
      name: string
  hashicorpVaultSettings:
    baseURL: '^https?://[a-zA-Z0-9.-]+(:[0-9]{1,5})?(/.*)?$'
  volumeMigrationSettings:
    enabled: boolean
    rebalancerImage: string
    dataRealignment:
      enabled: boolean
      interval: Duration
      minMoves: integer
  volumeAutoPlacement:
    enabled: boolean
    migrationEnabled: boolean
    evaluationInterval: Duration
    imbalanceThreshold: integer
    minHotColdDifferencePct: integer
    defaultCoolDownSeconds: integer
    maxVolumeMigrationsPerCycle: integer
    storageNodeCandidateCount: integer
    metricsBackend: MetricsBackend
    prometheusURL: string
    latencyBenchmarkEnabled: boolean
    latencyBenchmarkInterval: Duration
    iopsWeight: float
    throughputWeight: float
  enableFailureDomains: boolean
status:
  uuid: string
  phase: string
  subPhase: string
  clusterName: string
  mgmtNodes: integer
  storageNodes: integer
  nqn: string
  status: string
  rebalancing: boolean
  volumeMoveGeneration: integer
  realignedGeneration: integer
  lastDataRealignmentAt: Time
  erasureCodingScheme: string
  lastUpdated: Time
  created: Time
  configured: boolean
  maxFaultTolerance: integer
  maxConcurrentWorkerRestarts: integer
  actionStatus:
    action: string
    nodeUUID: string
    state: string
    message: string
    updatedAt: Time
    observedGeneration: integer
    triggered: boolean
    subPhase: string
    volumesMigrated: integer
    volumesPending: integer
  nodeRecycleStatus:
    pendingNodes:
      - string
    processedNodes:
      - string
    nodePhase: string
    phaseTriggered: boolean
  rebalancingMetrics:
    avgDeviationPct: float
    maxDeviationPct: float
    hottestNodeUUID: string
    coolestNodeUUID: string
    imbalancePercent: float
    lastEvaluatedAt: Time
    lastMigrationAt: Time
    nodeMetrics:
      - nodeUUID: string
        latencyDeviationPct: float
        volumeCount: integer
        lastUpdated: Time
Field Description Default Validation
apiVersion string storage.simplyblock.io/v1alpha1
kind string StorageCluster
metadata ObjectMeta ⧉ Refer to Kubernetes API documentation for fields of metadata. Optional: {}
spec StorageClusterSpec spec defines the desired state of StorageCluster Required: {}
status StorageClusterStatus status defines the observed state of StorageCluster Optional: {}

StorageClusterSpec

StorageClusterSpec defines the desired state of StorageCluster

Appears in: - StorageCluster

Example:

enableNodeAffinity: boolean
stripe:
  dataChunks: integer
  parityChunks: integer
action: string
nodeRecycle:
  refreshSNodeAPI: boolean
fabricType: string
clientDataIfname: string
nvmfBasePort: integer
rpcBasePort: integer
snodeApiPort: integer
maxConcurrentWorkerRestarts: integer
maxSubsystemCount: integer
maxHugePagesSize: string
vcpuCount: integer
warningThreshold:
  capacity: integer
  provisionedCapacity: integer
criticalThreshold:
  capacity: integer
  provisionedCapacity: integer
backup:
  localEndpoint: '^https?://[a-zA-Z0-9.-]+(:[0-9]{1,5})?(/.*)?$'
  snapshotBackups: boolean
  withCompression: boolean
  secondaryTarget: integer
  localTesting: boolean
  credentialsSecretRef:
    name: string
hashicorpVaultSettings:
  baseURL: '^https?://[a-zA-Z0-9.-]+(:[0-9]{1,5})?(/.*)?$'
volumeMigrationSettings:
  enabled: boolean
  rebalancerImage: string
  dataRealignment:
    enabled: boolean
    interval: Duration
    minMoves: integer
volumeAutoPlacement:
  enabled: boolean
  migrationEnabled: boolean
  evaluationInterval: Duration
  imbalanceThreshold: integer
  minHotColdDifferencePct: integer
  defaultCoolDownSeconds: integer
  maxVolumeMigrationsPerCycle: integer
  storageNodeCandidateCount: integer
  metricsBackend: MetricsBackend
  prometheusURL: string
  latencyBenchmarkEnabled: boolean
  latencyBenchmarkInterval: Duration
  iopsWeight: float
  throughputWeight: float
enableFailureDomains: boolean
Field Description Default Validation
enableNodeAffinity boolean EnableNodeAffinity enables node-affinity placement for storage components. Optional: {}
stripe StripeSpec StripeSpec configures erasure-coding data/parity chunk counts.
action string Action triggers a cluster-level action. Enum: [activate expand shutdown start restart node-recycle]
nodeRecycle NodeRecycleSpec NodeRecycle configures the node-recycle action.
fabricType string FabricType defines the storage fabric type.
clientDataIfname string ClientDataIfname defines the client data network interface.
nvmfBasePort integer NvmfBasePort defines the base NVMf service port.
rpcBasePort integer RpcBasePort defines the base RPC service port.
snodeApiPort integer SnodeApiPort defines the storage-node API port.
maxConcurrentWorkerRestarts integer MaxConcurrentWorkerRestarts is the maximum number of Kubernetes worker nodes the operator
may drain and restart simultaneously. The effective concurrency applied by the drain
coordinator is min(MaxConcurrentWorkerRestarts, MaxFaultTolerance).
Defaults to 1 when unset.
Minimum: 1
Optional: {}
maxSubsystemCount integer MaxSubsystemCount is the maximum number of NVMe-oF subsystems per storage
node. Applies to every storage node in the cluster. Required: it sizes huge
pages, and a node that receives no value fails config generation outright
rather than falling back to a default.
Maximum: 75
Minimum: 10
Required: {}
maxHugePagesSize string MaxHugePagesSize is the maximum allocatable size of huge pages on each
storage node (e.g. "100G", "1T"; a bare number is interpreted as GB). It is
a floor, not a cap: the effective huge-page allocation is the larger of this
value and the minimum the node's device and subsystem count requires. When
omitted the computed minimum is used.
Optional: {}
vcpuCount integer VCPUCount is the number of vCPUs allocated to SPDK on each storage node.
This is an explicit core count, not a percentage. Required: the core layout
it produces must match across the cluster, so it is stated rather than left
to a per-node heuristic.
Minimum: 6
Required: {}
warningThreshold CapacityThresholdSpec WarningThresholdSpec defines warning-level capacity thresholds.
criticalThreshold CapacityThresholdSpec CriticalThresholdSpec defines critical-level capacity thresholds.
backup BackupSpec Backup specifies the specification for backup to S3 configuration
hashicorpVaultSettings HashicorpVaultSettings HashicorpVaultSettings configures the Vault endpoint used by the cluster for key storage.
volumeMigrationSettings VolumeMigrationSettings VolumeMigrationSettings controls volume migration for this cluster. Optional: {}
volumeAutoPlacement VolumeAutoPlacementSettings VolumeAutoPlacement configures automatic, latency-driven volume rebalancing. When
nil/disabled the operator performs only manually-triggered VolumeMigrations.
Optional: {}
enableFailureDomains boolean EnableFailureDomains opts the cluster into failure-domain mode. When enabled, every
storage node must declare a failure-domain group so the control plane can spread
erasure-coding chunks across independent fault groups. Immutable once set — failure-
domain mode cannot be toggled on a live cluster.
Optional: {}

StorageClusterStatus

StorageClusterStatus defines the observed state of StorageCluster.

Appears in: - StorageCluster

Example:

uuid: string
phase: string
subPhase: string
clusterName: string
mgmtNodes: integer
storageNodes: integer
nqn: string
status: string
rebalancing: boolean
volumeMoveGeneration: integer
realignedGeneration: integer
lastDataRealignmentAt: Time
erasureCodingScheme: string
lastUpdated: Time
created: Time
configured: boolean
maxFaultTolerance: integer
maxConcurrentWorkerRestarts: integer
actionStatus:
  action: string
  nodeUUID: string
  state: string
  message: string
  updatedAt: Time
  observedGeneration: integer
  triggered: boolean
  subPhase: string
  volumesMigrated: integer
  volumesPending: integer
nodeRecycleStatus:
  pendingNodes:
    - string
  processedNodes:
    - string
  nodePhase: string
  phaseTriggered: boolean
rebalancingMetrics:
  avgDeviationPct: float
  maxDeviationPct: float
  hottestNodeUUID: string
  coolestNodeUUID: string
  imbalancePercent: float
  lastEvaluatedAt: Time
  lastMigrationAt: Time
  nodeMetrics:
    - nodeUUID: string
      latencyDeviationPct: float
      volumeCount: integer
      lastUpdated: Time
Field Description Default Validation
uuid string UUID is the backend cluster UUID.
phase string Phase tracks the cluster creation lifecycle to prevent concurrent reconcilers
from creating duplicate clusters. Set to "creation" while a creation is in
progress and cleared once the cluster UUID is persisted.
subPhase string SubPhase tracks the step within the current Phase. Reserved for future
sub-state machine expansion; currently only "creating" is used.
clusterName string ClusterName is the resolved backend cluster name.
mgmtNodes integer MgmtNodes is the number of management nodes.
FIXME: Unused for now (API update required?)
storageNodes integer StorageNodes is the number of storage nodes.
FIXME: Unused for now (API update required?)
nqn string NQN is the cluster NVM subsystem qualified name.
status string Status is the backend-reported lifecycle status.
rebalancing boolean Rebalancing indicates whether cluster rebalancing is currently active.
volumeMoveGeneration integer VolumeMoveGeneration counts completed volume moves. Every migration that reaches
Completed increments it, and nothing else writes it, so it only ever grows.
Optional: {}
realignedGeneration integer RealignedGeneration is the VolumeMoveGeneration that the last successfully
requested realignment covers. A realignment is outstanding while
VolumeMoveGeneration exceeds it.
This is recorded from the value read before the request is sent, because that
is what the realignment can actually account for: a migration completing while
the request is in flight raises VolumeMoveGeneration past it and so correctly
leaves another realignment outstanding, instead of being swallowed by the one
already running.
Optional: {}
lastDataRealignmentAt Time ⧉ LastDataRealignmentAt is the time of the last successful control-plane data
realignment. It is used to space realignments by DataRealignment.Interval and to
avoid re-running at the end of an interval when nothing is pending.
Optional: {}
erasureCodingScheme string ErasureCodingScheme is the active erasure-coding layout, for example "2x1".
lastUpdated Time ⧉ LastUpdated is the last backend update timestamp.
FIXME: Unused for now (API update required?)
created Time ⧉ Created is the backend creation timestamp.
FIXME: Unused for now (API update required?)
configured boolean Configured indicates whether initial cluster setup completed.
maxFaultTolerance integer MaxFaultTolerance is the backend-reported maximum number of nodes that can
be simultaneously offline (failed, drained, or restarted) without violating
the cluster's redundancy guarantees.
maxConcurrentWorkerRestarts integer MaxConcurrentWorkerRestarts is the effective concurrent-restart limit applied
by the drain coordinator: min(spec.MaxConcurrentWorkerRestarts, MaxFaultTolerance).
Defaults to 1. Exposed here so controllers and tooling can read a single
authoritative value without re-computing it.
Optional: {}
actionStatus ActionStatus ActionStatus tracks the most recent action execution state.
nodeRecycleStatus NodeRecycleStatus NodeRecycleStatus tracks in-progress state for the node-recycle action.
rebalancingMetrics RebalancingMetrics RebalancingMetrics is updated by the auto-rebalancer each evaluation cycle. Optional: {}

StorageNode

StorageNode is the Schema for a single backend storage node instance. One StorageNode CR exists per (workerNode, socketIndex) pair and is owned by the parent StorageNodeSet.

Example:

apiVersion: storage.simplyblock.io/v1alpha1
kind: StorageNode
metadata:
  name: string
spec:
  storageNodeSetRef: string
  workerNode: string
  socketId: string
  nodeIndex: integer
  socketIndex: integer
  overrides:
    spdkImage: string
    spdkProxyImage: string
    spdkSystemMemory: '^[0-9]+(G|GI|GB|GiB|M|MI|MB|MiB|g|gi|gb|gib|m|mi|mb|mib)?$'
    journalManager:
      count: integer
      percentPerDevice: integer
    pcieAllowList:
      - string
    pcieDenyList:
      - string
    pcieModel: string
    driveSizeRange: string
    deviceNames:
      - string
    enableCpuTopology: boolean
    reservedSystemCPU: string
    ubuntuHost: boolean
    skipKubeletConfiguration: boolean
    failureDomain: integer
    expand: boolean
status:
  uuid: string
  status: string
  health: boolean
  hostname: string
  uptime: string
  resources:
    cpu: integer
    memory: string
    volumes: integer
    devices: string
  ports:
    management: string
    nvmeof: integer
    lvol: integer
    rpc: integer
  postedAt: Time
  activeOpsRef: string
  latencyMetrics:
    nodeUUID: string
    baselineP50NS: integer
    baselineP99NS: integer
    baselineMeasuredAt: Time
  failureDomain: integer
Field Description Default Validation
apiVersion string storage.simplyblock.io/v1alpha1
kind string StorageNode
metadata ObjectMeta ⧉ Refer to Kubernetes API documentation for fields of metadata.
spec StorageNodeSpec
status StorageNodeStatus

StorageNodeOps

StorageNodeOps is a one-shot operational CR targeting a single StorageNode. Analogous to a Kubernetes Job — it drives an action (shutdown, restart, suspend, resume, remove/drain) to completion and records the result. Only one StorageNodeOps can be active per StorageNode at a time.

Example:

apiVersion: storage.simplyblock.io/v1alpha1
kind: StorageNodeOps
metadata:
  name: string
spec:
  storageNodeRef: string
  action: string
  targetWorkerNode: string
  force: boolean
  reattachVolume: boolean
  newSsdPcie:
    - string
  drain:
    systemVolumeFilterRegex: string
status:
  phase: StorageNodeOpsPhase
  subPhase: StorageNodeOpsSubPhase
  message: string
  volumesMigrated: integer
  volumesPending: integer
  triggered: boolean
  startedAt: Time
  completedAt: Time
Field Description Default Validation
apiVersion string storage.simplyblock.io/v1alpha1
kind string StorageNodeOps
metadata ObjectMeta ⧉ Refer to Kubernetes API documentation for fields of metadata.
spec StorageNodeOpsSpec
status StorageNodeOpsStatus

StorageNodeOpsPhase

Underlying type: string

StorageNodeOpsPhase is the lifecycle phase of a StorageNodeOps.

Validation: - Enum: [Pending Running Succeeded Failed]

Appears in: - StorageNodeOpsStatus

Field Description
Pending
Running
Succeeded
Failed

StorageNodeOpsSpec

StorageNodeOpsSpec defines the desired state of a StorageNodeOps.

Appears in: - StorageNodeOps

Example:

storageNodeRef: string
action: string
targetWorkerNode: string
force: boolean
reattachVolume: boolean
newSsdPcie:
  - string
drain:
  systemVolumeFilterRegex: string
Field Description Default Validation
storageNodeRef string StorageNodeRef is the name of the target StorageNode. Immutable. Required: {}
action string Action is the operation to perform. Immutable. Enum: [shutdown restart suspend resume remove migrate]
Required: {}
targetWorkerNode string TargetWorkerNode is the Kubernetes worker hostname the storage node is
relocated onto. Required (and only used) when action=migrate.
A migration is NOT a drain/remove: the storage node keeps its backend UUID
and its partition / logical-volume assignments follow it. The operator
issues a control-plane restart pointed at the target host's
storage-node-api (node_address), waits for the node to come back online
there, then /promotes it (starting a rebalance) and re-points the
StorageNode's spec.workerNode and the owning StorageNodeSet.workerNodes
from the source worker to this one. No fresh storage node is provisioned
and no VolumeMigration CRs are created. Immutable.
Optional: {}
force boolean Force enables forced execution where the backend supports it. Optional: {}
reattachVolume boolean ReattachVolume reattaches volumes during the node restart.
Applicable when action=restart or action=migrate.
Optional: {}
newSsdPcie string array NewSsdPcie lists additional NVMe PCIe addresses to bind on the target host
during a migration. Passed through to the control-plane restart as
new_ssd_pcie. Only applicable when action=migrate.
Optional: {}
drain DrainOpsSpec Drain configures the drain workflow. Only applicable when action=remove. Optional: {}

StorageNodeOpsStatus

StorageNodeOpsStatus holds the observed state of a StorageNodeOps.

Appears in: - StorageNodeOps

Example:

phase: StorageNodeOpsPhase
subPhase: StorageNodeOpsSubPhase
message: string
volumesMigrated: integer
volumesPending: integer
triggered: boolean
startedAt: Time
completedAt: Time
Field Description Default Validation
phase StorageNodeOpsPhase Phase is the high-level lifecycle phase. Enum: [Pending Running Succeeded Failed]
Optional: {}
subPhase StorageNodeOpsSubPhase SubPhase tracks the active drain step when action=remove and phase=Running. Enum: [Validating Suspending Migrating Verifying Removing Preparing Restarting Promoting]
Optional: {}
message string Message is a human-readable description of the current state or failure reason. Optional: {}
volumesMigrated integer VolumesMigrated is the count of volumes successfully migrated (drain only). Optional: {}
volumesPending integer VolumesPending is the count of volumes awaiting migration (drain only). Optional: {}
triggered boolean Triggered indicates the backend action POST has been sent (used during
Suspending to avoid duplicate POSTs across reconcile iterations).
Optional: {}
startedAt Time ⧉ StartedAt is when the operation began. Optional: {}
completedAt Time ⧉ CompletedAt is when the operation finished (successfully or not). Optional: {}

StorageNodeOpsSubPhase

Underlying type: string

StorageNodeOpsSubPhase is the active sub-phase during a running op: the drain steps when action=remove, and the Preparing → Migrating → Promoting steps when action=migrate.

Validation: - Enum: [Validating Suspending Migrating Verifying Removing Preparing Restarting Promoting]

Appears in: - StorageNodeOpsStatus

Field Description
Validating
Suspending
Migrating
Verifying
Removing
Preparing StorageNodeOpsSubPhasePreparing marks that a migrate op is preparing the
target worker: cloning per-node config, labeling it into the storage
plane, and waiting until its storage-node-api pod is Ready and its per-pod
DNS name is published in the EndpointSlice — the precondition for the
control-plane restart to resolve node_address.
Restarting StorageNodeOpsSubPhaseRestarting marks that a migrate op has issued the
control-plane restart and confirmed the node entered in_restart; it is
now waiting for the node to come back online on the target host. The
restart is asynchronous, so the op only advances to Promoting after the
node has left online (restart started) and returned to online (restart
finished) — issuing /promote earlier races the in-flight restart's node
writes and leaves the relocated devices stuck in "new".
Promoting StorageNodeOpsSubPhasePromoting marks that a migrate op has issued the
control-plane /promote for the relocated node (guards against re-promoting).

StorageNodeOverrides

StorageNodeOverrides holds per-node configuration that overrides the parent StorageNodeSet fleet defaults for a specific worker node. Populated by the StorageNodeSetReconciler from StorageNodeSet.spec.nodeConfigs[workerNode] on every reconcile. The StorageNodeSet is the single source of truth — users should not edit this struct directly on the StorageNode.

Fields here mirror the configurable (non-immutable, non-infrastructure) fields of StorageNodeSetSpec. When a field is set here it takes precedence over the fleet default; when omitted the fleet default applies.

Appears in: - StorageNodeSetSpec - StorageNodeSpec

Example:

spdkImage: string
spdkProxyImage: string
spdkSystemMemory: '^[0-9]+(G|GI|GB|GiB|M|MI|MB|MiB|g|gi|gb|gib|m|mi|mb|mib)?$'
journalManager:
  count: integer
  percentPerDevice: integer
pcieAllowList:
  - string
pcieDenyList:
  - string
pcieModel: string
driveSizeRange: string
deviceNames:
  - string
enableCpuTopology: boolean
reservedSystemCPU: string
ubuntuHost: boolean
skipKubeletConfiguration: boolean
failureDomain: integer
expand: boolean
Field Description Default Validation
spdkImage string SpdkImage overrides the SPDK image for this node (e.g. for phased rollouts). Optional: {}
spdkProxyImage string SpdkProxyImage overrides the SPDK proxy image for this node. Optional: {}
spdkSystemMemory string SpdkSystemMemory overrides the SPDK huge-page memory allocation for this node
(e.g. "4G", "512M").
Pattern: ^[0-9]+(G\|GI\|GB\|GiB\|M\|MI\|MB\|MiB\|g\|gi\|gb\|gib\|m\|mi\|mb\|mib)?$
Optional: {}
journalManager JournalManagerSpec JournalManagerSpec overrides journal manager tuning for this node. Optional: {}
pcieAllowList string array PcieAllowList overrides the list of PCI addresses allowed for use on this node. Optional: {}
pcieDenyList string array PcieDenyList overrides the list of PCI addresses excluded from use on this node. Optional: {}
pcieModel string PcieModel overrides the PCI model filter for this node. Optional: {}
driveSizeRange string DriveSizeRange overrides the drive size range filter for this node. Optional: {}
deviceNames string array DeviceNames explicitly defines the NVMe namespace names to use on this node
(e.g. ["nvme0n1","nvme1n1"]).
Optional: {}
enableCpuTopology boolean EnableCpuTopology overrides topology-aware CPU handling for this node. Optional: {}
reservedSystemCPU string ReservedSystemCPU overrides the CPUs reserved for system workloads on this node. Optional: {}
ubuntuHost boolean UbuntuHost overrides the Ubuntu host OS flag for this node. Optional: {}
skipKubeletConfiguration boolean SkipKubeletConfiguration overrides whether kubelet configuration changes are
skipped for this node.
Optional: {}
failureDomain integer FailureDomain is the failure-domain group index (≥ 0) for this node.
Required when the parent StorageCluster has enableFailureDomains=true.
Overrides StorageNodeSet.spec.nodeFailureDomains[workerNode] when both are set.
Minimum: 0
Optional: {}
expand boolean Expand marks this node as a cluster-expansion add. When true the backend
node-add endpoint receives expand=true, triggering rebalancing behaviour
appropriate for in-place cluster growth. Overrides StorageNodeSet.spec.expand.
Optional: {}

StorageNodePorts

StorageNodePorts groups the network port and address fields reported by the backend.

Appears in: - StorageNodeStatus

Example:

management: string
nvmeof: integer
lvol: integer
rpc: integer
Field Description Default Validation
management string Management is the management IP address of the node. Optional: {}
nvmeof integer NvmeOf is the NVMe-oF fabric port. Optional: {}
lvol integer Lvol is the logical-volume subsystem port. Optional: {}
rpc integer Rpc is the RPC/management API port. Optional: {}

StorageNodeResources

StorageNodeResources groups compute and storage resource fields reported by the backend.

Appears in: - StorageNodeStatus

Example:

cpu: integer
memory: string
volumes: integer
devices: string
Field Description Default Validation
cpu integer CPU is the number of SPDK CPU cores allocated to this node. Optional: {}
memory string Memory is the SPDK memory allocation reported by the backend. Optional: {}
volumes integer Volumes is the current number of logical volumes on this node. Optional: {}
devices string Devices is the device summary (online/total) reported by the backend. Optional: {}

StorageNodeSet

StorageNodeSet is the Schema for the storagenodesets API

Example:

apiVersion: storage.simplyblock.io/v1alpha1
kind: StorageNodeSet
metadata:
  name: string
spec:
  clusterName: string
  clusterImage: '^($|(quay\.io/simplyblock-io|docker\.io/simplyblock|public\.ecr\.aws/simply-block)/[a-z0-9][a-z0-9._-]*:[a-zA-Z0-9][a-zA-Z0-9._-]*(@sha256:[a-f0-9]{64})?)$'
  spdkImage: '^($|(quay\.io/simplyblock-io|docker\.io/simplyblock|public\.ecr\.aws/simply-block)/[a-z0-9][a-z0-9._-]*:[a-zA-Z0-9][a-zA-Z0-9._-]*(@sha256:[a-f0-9]{64})?)$'
  spdkProxyImage: '^($|(quay\.io/simplyblock-io|docker\.io/simplyblock|public\.ecr\.aws/simply-block)/[a-z0-9][a-z0-9._-]*:[a-zA-Z0-9][a-zA-Z0-9._-]*(@sha256:[a-f0-9]{64})?)$'
  mgmtIfname: string
  enableJournalDevice: boolean
  journalManager:
    count: integer
    percentPerDevice: integer
  pcieAllowList:
    - string
  pcieDenyList:
    - string
  pcieModel: string
  driveSizeRange: string
  socketsToUse:
    - string
  nodesPerSocket: integer
  dataIfname:
    - string
  workerNodes:
    - string
  openShiftCluster: boolean
  openShiftMachineConfigPool: string
  deviceNames:
    - string
  ubuntuHost: boolean
  skipKubeletConfiguration: boolean
  forceFormat4K: boolean
  enableCpuTopology: boolean
  reservedSystemCPU: string
  spdkSystemMemory: '^[0-9]+(G|GI|GB|GiB|M|MI|MB|MiB|g|gi|gb|gib|m|mi|mb|mib)?$'
  tolerations:
    - Toleration
  maxParallelNodeAdds: integer
  containerResources: ResourceRequirements
  initContainerResources: ResourceRequirements
  imagePullPolicy: PullPolicy
  nodeFailureDomains:
    string: integer
  expand: boolean
  nodeConfigs:
    string:
      spdkImage: string
      spdkProxyImage: string
      spdkSystemMemory: '^[0-9]+(G|GI|GB|GiB|M|MI|MB|MiB|g|gi|gb|gib|m|mi|mb|mib)?$'
      journalManager:
        count: integer
        percentPerDevice: integer
      pcieAllowList:
        - string
      pcieDenyList:
        - string
      pcieModel: string
      driveSizeRange: string
      deviceNames:
        - string
      enableCpuTopology: boolean
      reservedSystemCPU: string
      ubuntuHost: boolean
      skipKubeletConfiguration: boolean
      failureDomain: integer
      expand: boolean
status:
  totalNodes: integer
  onlineNodes: integer
  offlineNodes: integer
  suspendedNodes: integer
  creatingNodes: integer
  removedNodes: integer
  nodes:
    - uuid: string
      health: boolean
      status: string
      cpu: integer
      memory: string
      volumes: integer
      rpcPort: integer
      lvolPort: integer
      nvmfPort: integer
      devices: string
      uptime: string
      hostname: string
      mgmtIp: string
      postedAt: Time
      failureDomain: integer
  drainCoordination:
    - hostname: string
      phase: string
      startedAt: Time
      message: string
      activeNodeUUID: string
  pendingNodeAdds:
    string: Time
  schedulingFailedWorkers:
    string: boolean
  latencyMetrics:
    - nodeUUID: string
      baselineP50NS: integer
      baselineP99NS: integer
      baselineMeasuredAt: Time
Field Description Default Validation
apiVersion string storage.simplyblock.io/v1alpha1
kind string StorageNodeSet
metadata ObjectMeta ⧉ Refer to Kubernetes API documentation for fields of metadata. Optional: {}
spec StorageNodeSetSpec spec defines the desired state of StorageNodeSet Required: {}
status StorageNodeSetStatus status defines the observed state of StorageNodeSet Optional: {}

StorageNodeSetSpec

StorageNodeSetSpec defines the desired state of StorageNodeSet

Appears in: - StorageNodeSet

Example:

clusterName: string
clusterImage: '^($|(quay\.io/simplyblock-io|docker\.io/simplyblock|public\.ecr\.aws/simply-block)/[a-z0-9][a-z0-9._-]*:[a-zA-Z0-9][a-zA-Z0-9._-]*(@sha256:[a-f0-9]{64})?)$'
spdkImage: '^($|(quay\.io/simplyblock-io|docker\.io/simplyblock|public\.ecr\.aws/simply-block)/[a-z0-9][a-z0-9._-]*:[a-zA-Z0-9][a-zA-Z0-9._-]*(@sha256:[a-f0-9]{64})?)$'
spdkProxyImage: '^($|(quay\.io/simplyblock-io|docker\.io/simplyblock|public\.ecr\.aws/simply-block)/[a-z0-9][a-z0-9._-]*:[a-zA-Z0-9][a-zA-Z0-9._-]*(@sha256:[a-f0-9]{64})?)$'
mgmtIfname: string
enableJournalDevice: boolean
journalManager:
  count: integer
  percentPerDevice: integer
pcieAllowList:
  - string
pcieDenyList:
  - string
pcieModel: string
driveSizeRange: string
socketsToUse:
  - string
nodesPerSocket: integer
dataIfname:
  - string
workerNodes:
  - string
openShiftCluster: boolean
openShiftMachineConfigPool: string
deviceNames:
  - string
ubuntuHost: boolean
skipKubeletConfiguration: boolean
forceFormat4K: boolean
enableCpuTopology: boolean
reservedSystemCPU: string
spdkSystemMemory: '^[0-9]+(G|GI|GB|GiB|M|MI|MB|MiB|g|gi|gb|gib|m|mi|mb|mib)?$'
tolerations:
  - Toleration
maxParallelNodeAdds: integer
containerResources: ResourceRequirements
initContainerResources: ResourceRequirements
imagePullPolicy: PullPolicy
nodeFailureDomains:
  string: integer
expand: boolean
nodeConfigs:
  string:
    spdkImage: string
    spdkProxyImage: string
    spdkSystemMemory: '^[0-9]+(G|GI|GB|GiB|M|MI|MB|MiB|g|gi|gb|gib|m|mi|mb|mib)?$'
    journalManager:
      count: integer
      percentPerDevice: integer
    pcieAllowList:
      - string
    pcieDenyList:
      - string
    pcieModel: string
    driveSizeRange: string
    deviceNames:
      - string
    enableCpuTopology: boolean
    reservedSystemCPU: string
    ubuntuHost: boolean
    skipKubeletConfiguration: boolean
    failureDomain: integer
    expand: boolean
Field Description Default Validation
clusterName string ClusterName is the target storage cluster name.
clusterImage string ClusterImage is the container image used for storage-node workloads.
Must reference one of the trusted registries (quay.io/simplyblock-io, docker.io/simplyblock, public.ecr.aws/simply-block); digest pinning (@sha256:...) is recommended.
Pattern: ^($\|(quay\.io/simplyblock-io\|docker\.io/simplyblock\|public\.ecr\.aws/simply-block)/[a-z0-9][a-z0-9._-]*:[a-zA-Z0-9][a-zA-Z0-9._-]*(@sha256:[a-f0-9]\{64\})?)$
spdkImage string SpdkImage is the SPDK image reference used by node services.
Must reference one of the trusted registries (quay.io/simplyblock-io, docker.io/simplyblock, public.ecr.aws/simply-block); digest pinning (@sha256:...) is recommended.
Pattern: ^($\|(quay\.io/simplyblock-io\|docker\.io/simplyblock\|public\.ecr\.aws/simply-block)/[a-z0-9][a-z0-9._-]*:[a-zA-Z0-9][a-zA-Z0-9._-]*(@sha256:[a-f0-9]\{64\})?)$
spdkProxyImage string SpdkProxyImage is the SPDK proxy image reference used by node services.
Must reference one of the trusted registries (quay.io/simplyblock-io, docker.io/simplyblock, public.ecr.aws/simply-block); digest pinning (@sha256:...) is recommended.
Pattern: ^($\|(quay\.io/simplyblock-io\|docker\.io/simplyblock\|public\.ecr\.aws/simply-block)/[a-z0-9][a-z0-9._-]*:[a-zA-Z0-9][a-zA-Z0-9._-]*(@sha256:[a-f0-9]\{64\})?)$
mgmtIfname string MgmtIfname is the management interface name used by storage nodes.
enableJournalDevice boolean EnableJournalDevice dedicates a whole NVMe device to the journal manager
instead of carving a journal partition out of every storage device. When
true the smallest device on the node becomes the journal device, and the
remaining devices are used whole; when false (the default) each device is
GPT-partitioned into a journal slice plus a storage slice.
journalManager JournalManagerSpec JournalManagerSpec configures journal manager behavior.
pcieAllowList string array PcieAllowList is the list of PCI addresses allowed for use.
pcieDenyList string array PcieDenyList is the list of PCI addresses excluded from use.
pcieModel string PcieModel filters devices by PCI model.
driveSizeRange string DriveSizeRange filters devices by size range.
socketsToUse string array SocketsToUse restricts deployment to selected NUMA sockets.
nodesPerSocket integer NodesPerSocket defines how many storage nodes are created per NUMA socket.
dataIfname string array DataIfname lists data-plane network interfaces.
workerNodes string array WorkerNodes is the set of Kubernetes worker nodes to manage. MaxItems: 200
openShiftCluster boolean OpenShiftCluster indicates OpenShift-specific behavior should be enabled.
openShiftMachineConfigPool string OpenShiftMachineConfigPool is the name of the MachineConfigPool that storage nodes belong to.
Generated MachineConfig resources will carry the machineconfiguration.openshift.io/role label
set to this value. Defaults to "worker" when unset.
deviceNames string array DeviceNames explicitly defines a comma separated list of nvme namespace names like nvme0n1,nvme1n1...
ubuntuHost boolean UbuntuHost indicates the node host OS is Ubuntu.
skipKubeletConfiguration boolean SkipKubeletConfiguration skips kubelet configuration changes.
forceFormat4K boolean ForceFormat4K forces 4K blocksize formatting of the NVMe device where supported.
enableCpuTopology boolean EnableCpuTopology enables topology-aware CPU handling.
reservedSystemCPU string ReservedSystemCPU defines CPUs reserved for system workloads.
spdkSystemMemory string SpdkSystemMemory is the amount of memory reserved for SPDK system use (e.g. "4G", "512M").
When omitted the backend default is used.
Pattern: ^[0-9]+(G\|GI\|GB\|GiB\|M\|MI\|MB\|MiB\|g\|gi\|gb\|gib\|m\|mi\|mb\|mib)?$
tolerations Toleration ⧉ array Tolerations configures pod tolerations for storage-node pods.
maxParallelNodeAdds integer MaxParallelNodeAdds limits how many non-FDB worker nodes can be in the
add process simultaneously. Defaults to 1 (fully sequential).
FDB workers are always sequential regardless of this setting.
1 Minimum: 1
containerResources ResourceRequirements ⧉ ContainerResources sets CPU and memory requests/limits for the main storage-node container.
When omitted no limits are enforced, which preserves the previous behaviour.
initContainerResources ResourceRequirements ⧉ InitContainerResources sets CPU and memory requests/limits for the init container.
When omitted no limits are enforced.
imagePullPolicy PullPolicy ⧉ ImagePullPolicy controls when the container image is pulled. Defaults to IfNotPresent. Enum: [Always Never IfNotPresent]
nodeFailureDomains object (keys:string, values:integer) NodeFailureDomains assigns each worker node to a failure-domain group (integer ≥ 0).
Required when the referenced StorageCluster has enableFailureDomains=true.
Keys are Kubernetes worker node names; values are the failure-domain group index.
Each node in the same physical failure domain (rack, AZ, power unit) should share
the same group index so the control plane can spread erasure-coding chunks across
independent fault groups.
Optional: {}
expand boolean Expand indicates that storage nodes added from this StorageNodeSet are being
added to expand an already-active cluster. When true the backend node-add
endpoint receives expand=true, which triggers the appropriate rebalancing
behaviour for in-place cluster growth.
Optional: {}
nodeConfigs object (keys:string, values:StorageNodeOverrides) NodeConfigs allows per-worker-node configuration overrides keyed by the
Kubernetes worker node name. Entries are propagated to the corresponding
StorageNode.spec.overrides by the StorageNodeReconciler on every reconcile.
The StorageNodeSet is the single source of truth for all per-node config,
including failure domain assignment via nodeConfigs[worker].failureDomain.
MaxProperties: 200
Optional: {}

StorageNodeSetStatus

StorageNodeSetStatus defines the observed state of StorageNodeSet.

Appears in: - StorageNodeSet

Example:

totalNodes: integer
onlineNodes: integer
offlineNodes: integer
suspendedNodes: integer
creatingNodes: integer
removedNodes: integer
nodes:
  - uuid: string
    health: boolean
    status: string
    cpu: integer
    memory: string
    volumes: integer
    rpcPort: integer
    lvolPort: integer
    nvmfPort: integer
    devices: string
    uptime: string
    hostname: string
    mgmtIp: string
    postedAt: Time
    failureDomain: integer
drainCoordination:
  - hostname: string
    phase: string
    startedAt: Time
    message: string
    activeNodeUUID: string
pendingNodeAdds:
  string: Time
schedulingFailedWorkers:
  string: boolean
latencyMetrics:
  - nodeUUID: string
    baselineP50NS: integer
    baselineP99NS: integer
    baselineMeasuredAt: Time
Field Description Default Validation
totalNodes integer TotalNodes is the total number of owned StorageNode CRs. Optional: {}
onlineNodes integer OnlineNodes is the count of StorageNode CRs with status "online". Optional: {}
offlineNodes integer OfflineNodes is the count of StorageNode CRs with status "offline". Optional: {}
suspendedNodes integer SuspendedNodes is the count of StorageNode CRs with status "suspended". Optional: {}
creatingNodes integer CreatingNodes is the count of StorageNode CRs with status "in_creation". Optional: {}
removedNodes integer RemovedNodes is the count of StorageNode CRs with status "removed". Optional: {}
nodes NodeStatus array Nodes is the observed state of each managed storage node.
drainCoordination NodeDrainState array DrainCoordination tracks the upgrade-drain state per worker node.
pendingNodeAdds object (keys:string, values:Time ⧉) PendingNodeAdds records the timestamp when a node-add POST was sent for
each worker hostname. Entries are removed only when all socket nodes for
that worker come online. This is the authoritative guard against duplicate
POSTs — it is a separate map field so patches to Status.Nodes never
inadvertently delete it.
schedulingFailedWorkers object (keys:string, values:boolean) SchedulingFailedWorkers tracks worker hostnames whose SPDK pod experienced
a FailedScheduling event during node add. Used to emit a recovery event
when the node subsequently comes online.
latencyMetrics NodeLatencyMetrics array LatencyMetrics holds per-backend-node fio-measured latency data for rebalancing decisions.

StorageNodeSpec

StorageNodeSpec defines the desired state of a StorageNode.

Appears in: - StorageNode

Example:

storageNodeSetRef: string
workerNode: string
socketId: string
nodeIndex: integer
socketIndex: integer
overrides:
  spdkImage: string
  spdkProxyImage: string
  spdkSystemMemory: '^[0-9]+(G|GI|GB|GiB|M|MI|MB|MiB|g|gi|gb|gib|m|mi|mb|mib)?$'
  journalManager:
    count: integer
    percentPerDevice: integer
  pcieAllowList:
    - string
  pcieDenyList:
    - string
  pcieModel: string
  driveSizeRange: string
  deviceNames:
    - string
  enableCpuTopology: boolean
  reservedSystemCPU: string
  ubuntuHost: boolean
  skipKubeletConfiguration: boolean
  failureDomain: integer
  expand: boolean
Field Description Default Validation
storageNodeSetRef string StorageNodeSetRef is the name of the owning StorageNodeSet. Immutable. Required: {}
workerNode string WorkerNode is the Kubernetes node hostname this StorageNode runs on.
Users may not change it directly — it is re-pointed only by the operator
during a node migration (StorageNodeOps action=migrate). The
StorageNode validating webhook rejects user-driven changes to this field.
Required: {}
socketId string SocketID is the NUMA socket identifier from spec.socketsToUse (e.g. "0", "1"). Immutable. Optional: {}
nodeIndex integer NodeIndex is the per-socket node index (0..nodesPerSocket-1). Immutable. Optional: {}
socketIndex integer SocketIndex is the global ordinal (socketPosition × nodesPerSocket + nodeIndex).
Used internally by the operator to select the correct backend node from the
RPC-port-sorted list in pollUUIDFromBackend. Immutable.
Optional: {}
overrides StorageNodeOverrides Overrides holds per-node configuration propagated from
StorageNodeSet.spec.nodeConfigs[workerNode] on every reconcile.
Optional: {}

StorageNodeStatus

StorageNodeStatus holds the observed state of a StorageNode.

Appears in: - StorageNode

Example:

uuid: string
status: string
health: boolean
hostname: string
uptime: string
resources:
  cpu: integer
  memory: string
  volumes: integer
  devices: string
ports:
  management: string
  nvmeof: integer
  lvol: integer
  rpc: integer
postedAt: Time
activeOpsRef: string
latencyMetrics:
  nodeUUID: string
  baselineP50NS: integer
  baselineP99NS: integer
  baselineMeasuredAt: Time
failureDomain: integer
Field Description Default Validation
uuid string UUID is the backend storage node UUID. Set once after node-add completes. Optional: {}
status string Status is the backend-reported node status (e.g. online, suspended, offline). Optional: {}
health boolean Health is the backend-reported node health flag. Optional: {}
hostname string Hostname is the node hostname as reported by the backend. Optional: {}
uptime string Uptime is the node uptime as reported by the backend. Optional: {}
resources StorageNodeResources Resources groups compute and storage resource metrics. Optional: {}
ports StorageNodePorts Ports groups network connectivity fields (addresses and ports). Optional: {}
postedAt Time ⧉ PostedAt is the timestamp when the node-add POST was sent.
Used as a provisioning guard against duplicate POSTs.
Optional: {}
activeOpsRef string ActiveOpsRef is the name of the currently active StorageNodeOps CR targeting
this node. Empty when no operation is in progress. Used for mutual exclusion.
Optional: {}
latencyMetrics NodeLatencyMetrics LatencyMetrics holds the fio-measured baseline NVMe-oF latency for this node,
used by the volume rebalancer to make data-placement decisions.
Optional: {}
failureDomain integer FailureDomain is the effective failure-domain group index for this node
as reported by the backend (≥ 0). Nil when the backend has not assigned one.
Optional: {}

StoragePool

StoragePool is the Schema for the storagepools API

Example:

apiVersion: storage.simplyblock.io/v1alpha1
kind: StoragePool
metadata:
  name: string
spec:
  clusterName: string
  status: string
  capacityLimit: string
  logicalVolumeMaxSize: string
  dhchap: boolean
  allowedNodes:
    - string
  qos:
    iops: integer
    throughput:
      read: integer
      readWrite: integer
      write: integer
  action: string
  storageClassParameters:
    qosRwIops: string
    qosRwMbytes: string
    qosRMbytes: string
    qosWMbytes: string
    encryption: boolean
    fabric: string
    maxNamespacePerSubsys: string
    tune2fsReservedBlocks: string
    filesystem: string
status:
  uuid: string
  status: string
  qos:
    host: string
    iops: integer
    throughput:
      read: integer
      readWrite: integer
      write: integer
  allowedNodes:
    - string
Field Description Default Validation
apiVersion string storage.simplyblock.io/v1alpha1
kind string StoragePool
metadata ObjectMeta ⧉ Refer to Kubernetes API documentation for fields of metadata. Optional: {}
spec StoragePoolSpec spec defines the desired state of StoragePool Required: {}
status StoragePoolStatus status defines the observed state of StoragePool Optional: {}

StoragePoolQoSSpec

StoragePoolQoSSpec defines pool QosSpec limits.

Appears in: - StoragePoolSpec

Example:

iops: integer
throughput:
  read: integer
  readWrite: integer
  write: integer
Field Description Default Validation
iops integer IOPS is the IOPS limit for the pool.
throughput StoragePoolQoSThroughputSpec Throughput contains throughput limits for the pool.

StoragePoolQoSStatus

StoragePoolQoSStatus defines observed pool QosSpec values.

Appears in: - StoragePoolStatus

Example:

host: string
iops: integer
throughput:
  read: integer
  readWrite: integer
  write: integer
Field Description Default Validation
host string Host is the backend host handling pool QosSpec enforcement.
iops integer IOPS is the observed/configured IOPS value.
throughput StoragePoolQoSThroughputStatus Throughput contains observed/configured throughput values.

StoragePoolQoSThroughputSpec

StoragePoolQoSThroughputSpec defines throughput QosSpec limits in MiB/s.

Appears in: - StoragePoolQoSSpec

Example:

read: integer
readWrite: integer
write: integer
Field Description Default Validation
read integer Read is the read throughput limit for the pool.
readWrite integer ReadWrite is the combined read/write throughput limit for the pool.
write integer Write is the write throughput limit for the pool.

StoragePoolQoSThroughputStatus

StoragePoolQoSThroughputStatus defines observed throughput QosSpec values in MiB/s.

Appears in: - StoragePoolQoSStatus

Example:

read: integer
readWrite: integer
write: integer
Field Description Default Validation
read integer Read is the observed/configured read throughput value.
readWrite integer ReadWrite is the observed/configured combined read/write throughput value.
write integer Write is the observed/configured write throughput value.

StoragePoolSpec

StoragePoolSpec defines the desired state of StoragePool

Appears in: - StoragePool

Example:

clusterName: string
status: string
capacityLimit: string
logicalVolumeMaxSize: string
dhchap: boolean
allowedNodes:
  - string
qos:
  iops: integer
  throughput:
    read: integer
    readWrite: integer
    write: integer
action: string
storageClassParameters:
  qosRwIops: string
  qosRwMbytes: string
  qosRMbytes: string
  qosWMbytes: string
  encryption: boolean
  fabric: string
  maxNamespacePerSubsys: string
  tune2fsReservedBlocks: string
  filesystem: string
Field Description Default Validation
clusterName string ClusterName is the target storage cluster name.
status string Status is an optional desired-status hint for backend workflows.
FIXME: Unused for now
capacityLimit string CapacityLimit is the maximum aggregate capacity that can be allocated from this pool.
This maps to sbctl pool add --pool-max. Use sizes like 20M, 20G, or 0 for unlimited.
logicalVolumeMaxSize string LogicalVolumeMaxSize is the maximum size allowed for any single logical volume
created in this pool. This maps to sbctl pool add --lvol-max. Use sizes like
20M, 20G, or 0 for unlimited.
dhchap boolean DHCHAP enables DH-HMAC-CHAP key generation for the pool. Authentication is only
enforced when allowedNodes is non-empty. Also controls whether the StoragePool's StorageClass
gets an allowedTopologies restriction, which — like StorageClass Parameters — is
immutable in the Kubernetes API, hence this field is immutable too.
false
allowedNodes string array AllowedNodes is the list of Kubernetes worker node names allowed to access volumes
in this pool. The operator resolves each node name to a deterministic NQN derived
from the node's UID: nqn.2014-08.io.simplyblock:uuid:.
The CSI node uses the same formula so no manual NQN management is required.
qos StoragePoolQoSSpec QosSpec defines QosSpec limits for the pool.
action string Action triggers an imperative pool operation.
FIXME: Unused for now
storageClassParameters StorageClassParameters StorageClassParameters sets default StorageClass parameter values for volumes in this pool.
Immutable: the underlying StorageClass's Parameters/AllowedTopologies cannot be patched in
the Kubernetes API once created, so there is no supported way to change these after the
fact. Create a new StoragePool to provision volumes with different settings.
{ }

StoragePoolStatus

StoragePoolStatus defines the observed state of StoragePool.

Appears in: - StoragePool

Example:

uuid: string
status: string
qos:
  host: string
  iops: integer
  throughput:
    read: integer
    readWrite: integer
    write: integer
allowedNodes:
  - string
Field Description Default Validation
uuid string UUID is the backend pool UUID.
status string Status is the backend lifecycle status.
qos StoragePoolQoSStatus QoS contains observed/configured QoS values.
allowedNodes string array AllowedNodes lists the Kubernetes node names currently registered on the backend.

StripeSpec

Appears in: - StorageClusterSpec

Example:

dataChunks: integer
parityChunks: integer
Field Description Default Validation
dataChunks integer DataChunks defines the number of data chunks in the erasure-coding layout.
parityChunks integer ParityChunks defines the number of parity chunks in the erasure-coding layout.

Task

Task is the Schema for the tasks API

Example:

apiVersion: storage.simplyblock.io/v1alpha1
kind: Task
metadata:
  name: string
spec:
  clusterName: string
  taskID: string
  subtasks: boolean
status:
  tasks:
    - uuid: string
      taskType: string
      taskStatus: string
      taskResult: string
      canceled: boolean
      parentTask: string
      startedAt: Time
      retried: integer
Field Description Default Validation
apiVersion string storage.simplyblock.io/v1alpha1
kind string Task
metadata ObjectMeta ⧉ Refer to Kubernetes API documentation for fields of metadata. Optional: {}
spec TaskSpec spec defines the desired state of Task Required: {}
status TaskStatus status defines the observed state of Task Optional: {}

TaskEntry

Appears in: - TaskStatus

Example:

uuid: string
taskType: string
taskStatus: string
taskResult: string
canceled: boolean
parentTask: string
startedAt: Time
retried: integer
Field Description Default Validation
uuid string UUID is the backend task UUID.
taskType string TaskType is the backend task function/type name.
taskStatus string TaskStatus is the backend lifecycle status for the task.
taskResult string TaskResult is the backend result payload/message.
canceled boolean Canceled indicates whether the task was canceled.
parentTask string ParentTask is the parent task UUID when this task is a subtask.
FIXME: Unused for now
startedAt Time ⧉ StartedAt is the backend-reported task start timestamp.
FIXME: Unused for now
retried integer Retried is the number of retry attempts made for the task.

TaskSpec

TaskSpec defines the desired state of Task

Appears in: - Task

Example:

clusterName: string
taskID: string
subtasks: boolean
Field Description Default Validation
clusterName string ClusterName is the target storage cluster name.
taskID string TaskID filters results to a specific backend task when set.
subtasks boolean Subtasks includes related child subtasks when supported by the backend.
FIXME: Unused for now

TaskStatus

TaskStatus defines the observed state of Task.

Appears in: - Task

Example:

tasks:
  - uuid: string
    taskType: string
    taskStatus: string
    taskResult: string
    canceled: boolean
    parentTask: string
    startedAt: Time
    retried: integer
Field Description Default Validation
tasks TaskEntry array Tasks is the currently reported task list for the query scope.

ValidationJob

ValidationJob is one NVMe path-validation Job and the worker node it runs on. The node is a consumer of some volume in the migrated subsystem — the volume named in the spec, or one of its siblings sharing the same NVMe subsystem.

Appears in: - VolumeMigrationStatus

Example:

node: string
jobName: string
succeeded: boolean
Field Description Default Validation
node string Node is the Kubernetes node name the Job is pinned to.
jobName string JobName is the name of the Job object in the VolumeMigration's namespace.
succeeded boolean Succeeded records that this node's validation passed. It is kept because the
Job's own existence is not a reliable record: Jobs are reaped, and re-reading a
reaped Job would otherwise look like "never validated" and start it again.
Optional: {}

VolumeAutoPlacementSettings

VolumeAutoPlacementSettings controls the automatic, latency-driven volume rebalancing behaviour. It is configured under StorageClusterSpec.VolumeAutoPlacement.

Appears in: - StorageClusterSpec

Example:

enabled: boolean
migrationEnabled: boolean
evaluationInterval: Duration
imbalanceThreshold: integer
minHotColdDifferencePct: integer
defaultCoolDownSeconds: integer
maxVolumeMigrationsPerCycle: integer
storageNodeCandidateCount: integer
metricsBackend: MetricsBackend
prometheusURL: string
latencyBenchmarkEnabled: boolean
latencyBenchmarkInterval: Duration
iopsWeight: float
throughputWeight: float
Field Description Default Validation
enabled boolean Enabled activates automatic rebalancing for this cluster. Defaults to false. Optional: {}
migrationEnabled boolean MigrationEnabled controls whether the rebalancer actually creates VolumeMigration
CRs. When false the rebalancer still runs every cycle — evaluating load, computing
deviations, selecting candidates and emitting metrics — but discards the migrations
instead of creating them (dry-run). Defaults to true.
Optional: {}
evaluationInterval Duration ⧉ EvaluationInterval is how often the rebalancer evaluates load. Defaults to 60s. Optional: {}
imbalanceThreshold integer ImbalanceThreshold is the minimum latency deviation from baseline (in percent)
that a node must exhibit before it is considered a rebalancing source. Defaults to 80.
Optional: {}
minHotColdDifferencePct integer MinHotColdDifferencePct is the minimum latency-deviation gap (in percentage points)
that a candidate target node must be below the hot source node before a migration is
performed. Prevents migrating between near-equally-loaded nodes. Defaults to 20.
Optional: {}
defaultCoolDownSeconds integer DefaultCoolDownSeconds is the cool-down period (seconds) applied to a volume after
it has been migrated. Defaults to 600.
Optional: {}
maxVolumeMigrationsPerCycle integer MaxVolumeMigrationsPerCycle is the maximum number of volumes moved per cycle. Defaults to 10. Optional: {}
storageNodeCandidateCount integer StorageNodeCandidateCount is the number of top-loaded nodes evaluated each cycle to
find the best migration source. Defaults to 3.
Optional: {}
metricsBackend MetricsBackend MetricsBackend selects the data source for I/O metrics. Defaults to "prometheus". Enum: [controlplane prometheus uniform]
Optional: {}
prometheusURL string PrometheusURL is required when MetricsBackend is "prometheus". Optional: {}
latencyBenchmarkEnabled boolean LatencyBenchmarkEnabled enables fio-based NVMe-oF latency measurement via Kubernetes Jobs.
Defaults to false; set to true once a RebalancerImage is configured.
Optional: {}
latencyBenchmarkInterval Duration ⧉ LatencyBenchmarkInterval is how often fio benchmark Jobs run against each storage node.
Defaults to 5m.
Optional: {}
iopsWeight float IOPSWeight is the weight applied to per-volume IOPS in the volume IO score. Defaults to 1.0. Optional: {}
throughputWeight float ThroughputWeight is the weight applied to per-volume throughput (MB/s) in the volume
IO score. Defaults to 0.1.
Optional: {}

VolumeMigration

VolumeMigration triggers a storage-node migration for a single PersistentVolume. Create a VolumeMigration to move a volume's backing logical volume to a different storage node. The controller resolves the PV to a logical volume UUID, submits the migration via the storage API, and tracks progress until completion or failure. Set spec.abort=true to cancel an in-progress migration.

Example:

apiVersion: storage.simplyblock.io/v1alpha1
kind: VolumeMigration
metadata:
  name: string
spec:
  pvName: string
  targetNodeUUID: string
  abort: boolean
status:
  phase: VolumeMigrationPhase
  migrationUUID: string
  clusterUUID: string
  volumeUUID: string
  poolUUID: string
  subsystemNQN: string
  sourceNodeUUID: string
  memberCount: integer
  errorMessage: string
  connections:
    - nqn: string
      ip: string
      port: integer
      transport: string
      nrIoQueues: integer
      reconnectDelay: integer
      ctrlLossTmo: integer
      fastIOFailTmo: integer
      keepAliveTmo: integer
  validationJobs:
    - node: string
      jobName: string
      succeeded: boolean
  deferredSince: Time
  startedAt: Time
  completedAt: Time
Field Description Default Validation
apiVersion string storage.simplyblock.io/v1alpha1
kind string VolumeMigration
metadata ObjectMeta ⧉ Refer to Kubernetes API documentation for fields of metadata.
spec VolumeMigrationSpec
status VolumeMigrationStatus

VolumeMigrationPhase

Underlying type: string

VolumeMigrationPhase describes the lifecycle state of a VolumeMigration.

Appears in: - VolumeMigrationStatus

Field Description
Pending VolumeMigrationPhasePending means the migration has been accepted but not
yet submitted to the storage API.
Validating VolumeMigrationPhaseValidating means CreateMigration has been called and
the operator is validating the new NVMe-oF connection paths on the target
node before calling ContinueMigration.
Running VolumeMigrationPhaseRunning means ContinueMigration has been called and
the data migration is in progress.
Completed VolumeMigrationPhaseCompleted means the migration finished successfully.
Failed VolumeMigrationPhaseFailed means the migration finished with an error.
Aborted VolumeMigrationPhaseAborted means the migration was cancelled via spec.abort.

VolumeMigrationSettings

VolumeMigrationSettings carries cluster-level settings for volume migration. Automatic load-based rebalancing is configured separately via StorageClusterSpec.VolumeAutoPlacement, keeping the manual-migration controls separate from the rebalancing policy.

Appears in: - StorageClusterSpec

Example:

enabled: boolean
rebalancerImage: string
dataRealignment:
  enabled: boolean
  interval: Duration
  minMoves: integer
Field Description Default Validation
enabled boolean Enabled turns on volume migration for this cluster. When false, the operator
will not act on VolumeMigration resources for this cluster. Defaults to true.
Optional: {}
rebalancerImage string RebalancerImage is the container image used for the volume-migration path
validation Job and the rebalancer latency/baseline Jobs. The image must include
nvme-cli (and, for rebalancing, fio + jq).
Optional: {}
dataRealignment DataRealignmentSettings DataRealignment configures the periodic control-plane data realignment that
runs after volumes have been moved. Realignment re-aligns the cluster's internal
data structures to the current volume placement so fault-tolerance (FTT) and
node-affinity guarantees are preserved. It applies to all volume moves —
auto-rebalancing, manual VolumeMigrations, and drain/removal-triggered moves —
so it lives here rather than under AutoRebalancing. Enabled by default.
Optional: {}

VolumeMigrationSpec

VolumeMigrationSpec defines the desired state of a VolumeMigration.

Appears in: - VolumeMigration

Example:

pvName: string
targetNodeUUID: string
abort: boolean
Field Description Default Validation
pvName string PVName is the name of the PersistentVolume whose backing logical volume
should be migrated. The PV must be provisioned by the simplyblock CSI driver.
MinLength: 1
targetNodeUUID string TargetNodeUUID is the UUID of the storage node that should host the
volume after migration.
MinLength: 1
abort boolean Abort requests cancellation of an in-progress migration. Set to true to
cancel; the phase will transition to Aborted once the backend confirms.
Optional: {}

VolumeMigrationStatus

VolumeMigrationStatus defines the observed state of a VolumeMigration.

Appears in: - VolumeMigration

Example:

phase: VolumeMigrationPhase
migrationUUID: string
clusterUUID: string
volumeUUID: string
poolUUID: string
subsystemNQN: string
sourceNodeUUID: string
memberCount: integer
errorMessage: string
connections:
  - nqn: string
    ip: string
    port: integer
    transport: string
    nrIoQueues: integer
    reconnectDelay: integer
    ctrlLossTmo: integer
    fastIOFailTmo: integer
    keepAliveTmo: integer
validationJobs:
  - node: string
    jobName: string
    succeeded: boolean
deferredSince: Time
startedAt: Time
completedAt: Time
Field Description Default Validation
phase VolumeMigrationPhase Phase is the current lifecycle phase of the migration. Enum: [Pending Validating Running Completed Failed Aborted]
migrationUUID string MigrationUUID is the identifier returned by the storage API when the
migration was submitted. Used for polling and cancellation.
clusterUUID string ClusterUUID is the storage cluster UUID resolved from the PV.
volumeUUID string VolumeUUID is the logical volume UUID resolved from the PV's CSI volume handle.
poolUUID string PoolUUID is the storage pool UUID that contains the volume.
subsystemNQN string SubsystemNQN is the NQN of the volume's NVMe subsystem, resolved from the
storage API when the migration is submitted. The migration is addressed by
it, and every volume sharing the subsystem moves with it.
sourceNodeUUID string SourceNodeUUID is the storage node UUID where the volume resided before
migration, as reported by the storage API.
memberCount integer MemberCount is the number of volumes (namespaces) in the migrated
subsystem, as reported by the storage API. More than one means the
migration moves sibling volumes along with this one.
errorMessage string ErrorMessage holds the failure reason when Phase is Failed.
connections MigrationConnection array Connections holds the NVMe-oF connection parameters for the new target-side
paths returned by CreateMigration. Used during the Validating phase to
establish and verify the paths before calling ContinueMigration, and again to
release them if the migration never cuts over.
These are the parameters the paths are actually connected with, not verbatim
what CreateMigration answered: ctrlLossTmo is replaced with the value every
path in this system uses, because a target path becomes the volume's data path
at cutover. The rest is passed through.
validationJobs ValidationJob array ValidationJobs are the Jobs that run nvme connect for each connection path
and validate ANA state before ContinueMigration is called — one per worker
node that consumes a volume of the migrated subsystem. A subsystem migrates
as a unit, so every consuming node must have the new paths before cutover;
all of these Jobs must succeed. Set during the Validating phase; cleared when
the phase advances to Running.
deferredSince Time ⧉ DeferredSince is when the storage API first refused to accept this migration
because the cluster was busy with work that ends on its own (a data realignment
or another node migration). While set, the migration is being retried and has
not started. It bounds the retrying: past a fixed window the migration fails
rather than waiting forever. Cleared once the migration is submitted.
startedAt Time ⧉ StartedAt is the time the migration was submitted to the storage API.
completedAt Time ⧉ CompletedAt is the time the migration finished (successfully or not).