MiroirVolume
miroir.home-operations.com / v1alpha1
apiVersion: miroir.home-operations.com/v1alpha1
kind: MiroirVolume
metadata:
name: example
apiVersion
string
APIVersion defines the versioned schema of this representation of an object.
Servers should convert recognized schemas to the latest internal value, and
may reject unrecognized values.
More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources
kind
string
Kind is a string value representing the REST resource this object represents.
Servers may infer this from the endpoint the client submits requests to.
Cannot be updated.
In CamelCase.
More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds
metadata
object
spec object required
MiroirVolumeSpec is the desired state, written by the controller at
CreateVolume time and reconciled by node agents. Replicas may be edited
on a live replicated volume — add an entry (node + backend; the
membership reconciler completes it) or remove one — within the bounds
the validation rule pins: an unreplicated volume cannot grow a
replication layer in place (internal DRBD metadata cannot be added
under a live filesystem), and a replicated one keeps 2–3 replicas.
allowRemoteAccess
boolean
AllowRemoteAccess permits pods on nodes without a replica: the PV
carries no node affinity, and staging on a non-replica node attaches
an ephemeral diskless client leg (spec.clients). From the
StorageClass parameter; replicated volumes only.
clients []object
Clients are ephemeral diskless consumer legs, added at stage time on
non-replica nodes and removed at unstage. Bounded small: RWO means
one consumer, plus headroom for an attach/detach overlap during a
pod move.
maxItems:
2
addedAt
string
AddedAt is when the CSI node service attached this leg. The
auto-diskful reconciler keys its conversion threshold on it.
format:
date-time
address
string
Address is the replication endpoint, resolved like a replica's
(node-map override, else the Node's InternalIP).
node
string required
Node is the Kubernetes node name consuming the volume remotely.
nodeID
integer
NodeID is the DRBD node id, unique across replicas and clients,
assigned by the membership reconciler.
format:
int32drbd object
DRBD is set by the controller when len(Replicas) > 1.
bitmapGranularityBytes
integer
BitmapGranularityBytes is the DRBD bitmap block size handed to
create-md (--bitmap-block-size): each dirty bit tracks this many
bytes, so coarser bits cut bitmap RAM proportionally at the cost of
resyncing more per dirty bit. Applied only when a replica's metadata
is first created — replicas created earlier keep their granularity
(DRBD exchanges bitmaps across differing block sizes). 0 means the
DRBD default (4096). Needs kmod ≥ 9.3.0 (the agent's startup floor).
enum:
0, 4096, 8192, 16384, 32768, 65536, 131072, 262144, 524288, 1.048576e+06format:
int64
port
integer required
Port is the TCP port for this resource's replication links,
allocated cluster-wide by the controller at creation.
format:
int32minimum:
1024maximum:
65535
sharedSecret
string
SharedSecret authenticates peers (cram-hmac-alg challenge-response):
without it, anything that can reach the replication port can join the
resource. Generated by the controller at creation; both agents render
the same value. DRBD caps secrets at 64 characters.
maxLength:
64export object
Export, if set, serves the volume as a shared filesystem over NFS
(RWX). Set by the controller when the volume is created from a
MULTI_NODE access mode; immutable.
fsType
string required
FSType is the filesystem the gateway formats and mounts on the
device. Persisted here because mkfs happens in the gateway, which
never sees a CSI VolumeCapability; consumers only ever see NFS.
enum:
ext4, xfs
quorumPolicy
string
QuorumPolicy applies only when len(Replicas) > 1.
enum:
last-man-standing, freezereplicas []object required
Replicas lists the placement of the volume: one entry for local
volumes, two or more for DRBD-replicated ones. MaxItems matches the
CEL size rule and bounds the apiserver's CEL cost estimate — the
diskless transition rule is nested over this list and exceeds the
rule budget on an unbounded array.
minItems:
1maxItems:
3
address
string
Address is the replication endpoint (host IP), from the node map.
Only set on replicated volumes.
backend
string
Backend selects how the backing device is provisioned on this node.
Unused for diskless tie-breaker replicas (they have no backing device).
enum:
lvmthin, zfs, loopfile
diskless
boolean
Diskless makes this a quorum-only tie-breaker: DRBD joins for
voting but stores no data. No backend device, never a mount
target. The agent skips backend create/resize/delete and DRBD
create-md; the resource renders "disk none" for this peer.
fullSync
boolean
FullSync marks a replica added after volume creation: its agent
skips the day0 GI seed so DRBD full-syncs it from the existing
peers instead of treating it as a pristine twin. Set by the
membership reconciler when it completes the entry.
node
string required
Node is the Kubernetes node name hosting this replica.
nodeID
integer
NodeID is the DRBD node id, assigned by the controller at creation
and stable for the volume's lifetime. Only set on replicated volumes.
format:
int32
pool
string
Pool names the node-map storage pool holding this replica's backing
device. Persisted like Backend so the volume survives later topology
edits. Empty means the default pool (pre-multi-pool volumes are
adopted this way). Unused for diskless replicas.
sizeBytes
integer required
SizeBytes is the provisioned (virtual, thin) size of the volume.
The transition rule pins it monotonic: nothing downstream supports
shrinking — agents only grow the backing device and the filesystem,
and a shrunk spec would desync DRBD metadata from the device.
format:
int64minimum:
1source object
Source, if set, provisions content from a snapshot (CoW clone).
snapshotName
string required
SnapshotName references a MiroirSnapshot by name.
status object
MiroirVolumeStatus is the observed state aggregated from node agents.
activated
boolean
Activated is set the first time any node successfully stages the
volume for a consumer (filesystem or raw block). It latches "this
volume may hold data": split-brain auto-recovery, which discards one
leg's generation, runs only while this is false — on an activated
volume divergence is never auto-resolved. Broader than Formatted,
which a raw-block volume never sets.
conditions []object
Conditions follow the standard Kubernetes condition conventions.
lastTransitionTime
string required
lastTransitionTime is the last time the condition transitioned from one status to another.
This should be when the underlying condition changed. If that is not known, then using the time when the API field changed is acceptable.
format:
date-time
message
string required
message is a human readable message indicating details about the transition.
This may be an empty string.
maxLength:
32768
observedGeneration
integer
observedGeneration represents the .metadata.generation that the condition was set based upon.
For instance, if .metadata.generation is currently 12, but the .status.conditions[x].observedGeneration is 9, the condition is out of date
with respect to the current state of the instance.
format:
int64minimum:
0
reason
string required
reason contains a programmatic identifier indicating the reason for the condition's last transition.
Producers of specific condition types may define expected values and meanings for this field,
and whether the values are considered a guaranteed API.
The value should be a CamelCase string.
This field may not be empty.
pattern:
^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$minLength:
1maxLength:
1024
status
string required
status of the condition, one of True, False, Unknown.
enum:
True, False, Unknown
type
string required
type of condition in CamelCase or in foo.example.com/CamelCase.
pattern:
^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$maxLength:
316export object
Export is the observed state of the NFS gateway, set only on RWX
volumes (spec.export). Written by the export reconciler.
address
string
Address is the share Service's ClusterIP. Consumers mount
<address>:/<volume> over NFS. Empty until the reconciler has
created the Service and read back its allocated ClusterIP.
formatted
boolean
Formatted is set once the volume has ever carried a filesystem —
first mkfs at stage time, or inherited from the snapshot source on
restore. A blank device on a formatted volume is data loss: the
node refuses to mkfs again rather than silently wipe it.
perNode
object
PerNode maps node name to that agent's observed state.
phase
string
Phase summarizes the volume state for the controller and humans.
No matches. Try .spec.allowRemoteAccess for an exact path