The module lifecycle stageExperimental
The module has requirements for installation

The Deckhouse Kubernetes Platform installs CRDs but does not remove them when a module is disabled. If you no longer need the created CRDs, delete them.

Bucket

Short names: bkt

Scope: Cluster
Version: v1alpha1

Bucket declares a single S3 bucket in an ObjectStore. The controller creates the bucket in the backend. It is cluster-scoped: credentials are NOT issued here. Consuming namespaces request scoped access and receive a credentials Secret via namespaced BucketAccess resources, and cross-namespace access is gated by cluster-scoped BucketClaimPolicy resources (deny-by-default).
  • spec
    object
    Desired state of the bucket.
    • spec.accessPolicy
      string

      Bucket access policy.

      • Private (default) — accessible only with issued credentials.
      • PublicRead — objects are readable anonymously; writes still require credentials.

      Default: Private

      Allowed values: Private, PublicRead

    • spec.bucketName
      string
      Name of the bucket in S3. Defaults to metadata.name when omitted. Must follow S3 bucket naming rules. Immutable after creation.

      Length: 3..63

      Pattern: ^[a-z0-9][a-z0-9.-]{1,61}[a-z0-9]$

    • spec.claimRef
      object

      Identifies the BucketClaim that provisioned and owns this bucket (greenfield). Administrator-declared Shared buckets leave it empty.

      This is the authoritative owner record. Only the module’s own service account may set it (enforced by the admission webhook on create), and it is immutable afterwards, so a bucket cannot be re-pointed at another claim and no claim can take over a bucket that already belongs to a different one. The storage.deckhouse.io/owned-by-claim-* labels mirror it for label queries but are user-settable and are never used for authorization.

      It also scopes sharing: BucketClaimPolicy resources for this bucket are honored only in this namespace (or in the module namespace when the field is empty).

      • spec.claimRef.name
        string

        Required value

        Name of the owning BucketClaim.

        Length: 1..253

      • spec.claimRef.namespace
        string

        Required value

        Namespace of the owning BucketClaim.

        Length: 1..253

    • spec.objectStoreRef
      string

      Required value

      Name of the ObjectStore this bucket belongs to. The referenced ObjectStore must exist and be in Ready phase before the bucket is provisioned. Immutable after creation.

      Length: 1..30

      Pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$

    • spec.quota
      object
      Optional usage limits for the bucket. Enforcement depends on backend capabilities.
      • spec.quota.maxObjects
        integer
        Maximum number of objects. 0 (default) means no limit.

        Allowed values: 0 <= X

      • spec.quota.maxSize
        string
        Maximum total size of the bucket as a Kubernetes Quantity (BinarySI), e.g. 10Gi. Omit for no size limit.

        Pattern: ^[0-9]+(\.[0-9]+)?(Ki|Mi|Gi|Ti|Pi|Ei|k|M|G|T|P|E)?$

    • spec.reclaimPolicy
      string

      What happens to bucket data when the Bucket is deleted.

      • Retain (default) — the bucket and its objects are kept in the backend.
      • Delete — the bucket and all its objects are deleted.

      Default: Retain

      Allowed values: Retain, Delete

  • status
    object
    Observed state of the bucket.
    • status.bucketName
      string
      Effective bucket name created in the backend.
    • status.conditions
      array of objects
      Per-component conditions: BucketReady and the aggregate Ready.
      • status.conditions.lastTransitionTime
        string
        Timestamp of the last status transition for this condition.
      • status.conditions.message
        string
        Human-readable explanation of the current status.

        Maximum length: 32768

      • status.conditions.observedGeneration
        integer
        Value of metadata.generation the condition was last set against.

        Allowed values: 0 <= X

      • status.conditions.reason
        string
        Machine-readable reason for the current status, suitable for log filtering.

        Length: 1..1024

        Pattern: ^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$

      • status.conditions.status
        string
        Current status of the condition.

        Allowed values: True, False, Unknown

      • status.conditions.type
        string
        Condition type, for example Ready or BucketReady.

        Maximum length: 316

        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])$

    • status.endpoint
      string
      In-cluster S3 endpoint URL of the backing cluster.
    • status.observedGeneration
      integer
      Most recent metadata.generation reconciled by the controller.
    • status.phase
      string
      Coarse-grained summary derived from Conditions.

      Allowed values: Pending, InProgress, Ready, Error

BucketAccess

Short names: ba

Scope: Namespaced
Version: v1alpha1

BucketAccess requests scoped S3 access to a cluster-scoped Bucket from a consuming namespace. The controller mints a dedicated access key / secret key for this access, writes a Secret in the same namespace (see status.secretRef) with the standard S3 connection variables, and revokes the key when the access is deleted.

Whether the access is provisioned is governed by BucketClaimPolicy resources (deny-by-default): an access whose namespace matches no policy for the referenced bucket stays Pending.

Key rotation: set or change the annotation storage.deckhouse.io/rotate to trigger issuance of a fresh key pair (the Secret is updated and the previous key is revoked).

  • spec
    object
    Desired state of the access.
    • spec.bucketClaimName
      string

      Required value

      Name of the BucketClaim (in this access’s namespace) whose bound Bucket the credentials are scoped to. The claim must be Bound before credentials are issued. Immutable after creation.

      Length: 1..253

      Pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$

    • spec.credentialsSecretName
      string
      Overrides the name of the credentials Secret written in this access’s namespace. Defaults to <metadata.name>-s3-credentials.

      Length: 1..253

    • spec.permission
      string

      Access level granted to the issued credentials.

      • ReadWrite (default) — read and write objects.
      • ReadOnly — read objects only.

      Default: ReadWrite

      Allowed values: ReadWrite, ReadOnly

  • status
    object
    Observed state of the access.
    • status.accessKeyID
      string
      Public access key id issued for this access (the secret key is only written into the credentials Secret).
    • status.bucketName
      string
      Effective bucket name the access is scoped to.
    • status.conditions
      array of objects
      Per-component conditions: AccessGranted, CredentialsReady, and the aggregate Ready.
      • status.conditions.lastTransitionTime
        string
        Timestamp of the last status transition for this condition.
      • status.conditions.message
        string
        Human-readable explanation of the current status.

        Maximum length: 32768

      • status.conditions.observedGeneration
        integer
        Value of metadata.generation the condition was last set against.

        Allowed values: 0 <= X

      • status.conditions.reason
        string
        Machine-readable reason for the current status, suitable for log filtering.

        Length: 1..1024

        Pattern: ^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$

      • status.conditions.status
        string
        Current status of the condition.

        Allowed values: True, False, Unknown

      • status.conditions.type
        string
        Condition type, for example Ready, AccessGranted, or CredentialsReady.

        Maximum length: 316

        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])$

    • status.endpoint
      string
      In-cluster S3 endpoint URL of the backing cluster.
    • status.lastRotationTime
      string
      Timestamp of the most recent key issuance.
    • status.observedGeneration
      integer
      Most recent metadata.generation reconciled by the controller.
    • status.observedRotation
      string
      Last value of the storage.deckhouse.io/rotate annotation processed by the controller.
    • status.phase
      string
      Coarse-grained summary derived from Conditions.

      Allowed values: Pending, InProgress, Ready, Error

    • status.secretRef
      object
      Reference to the Secret (in this access’s namespace) holding the S3 connection variables and credentials: S3_ENDPOINT, S3_REGION, S3_BUCKET, AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY.
      • status.secretRef.name
        string

BucketClaim

Short names: bc

Scope: Namespaced
Version: v1alpha1

BucketClaim is the namespaced request for a bucket.

  • Greenfield (spec.existingBucketName empty): the controller provisions a new cluster-scoped Bucket owned by this claim and private to this namespace, in spec.objectStoreRef.
  • Brownfield (spec.existingBucketName set): the claim binds an existing Shared Bucket, allowed only when a BucketClaimPolicy grants this namespace (deny-by-default).

Credentials are requested separately with a BucketAccess that references this claim by name in the same namespace.

  • spec
    object
    Desired state of the claim.
    • spec.accessPolicy
      string

      Access policy for a greenfield bucket. Ignored for brownfield.

      • Private (default) — accessible only with issued credentials.
      • PublicRead — objects are readable anonymously; writes still require credentials.

      Default: Private

      Allowed values: Private, PublicRead

    • spec.existingBucketName
      string
      Name of an existing Shared (administrator-declared) Bucket to bind (brownfield). Allowed only when a BucketClaimPolicy grants this claim’s namespace. Immutable after creation.

      Length: 3..63

      Pattern: ^[a-z0-9][a-z0-9.-]{1,61}[a-z0-9]$

    • spec.objectStoreRef
      string
      Name of the ObjectStore in which a greenfield bucket is provisioned. Required for greenfield; ignored for brownfield. Immutable after creation.

      Length: 1..30

      Pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$

    • spec.quota
      object
      Optional usage limits for a greenfield bucket. Enforcement depends on backend capabilities.
      • spec.quota.maxObjects
        integer
        Maximum number of objects. 0 (default) means no limit.

        Allowed values: 0 <= X

      • spec.quota.maxSize
        string
        Maximum total size as a Kubernetes Quantity (BinarySI), e.g. 10Gi. Omit for no size limit.

        Pattern: ^[0-9]+(\.[0-9]+)?(Ki|Mi|Gi|Ti|Pi|Ei|k|M|G|T|P|E)?$

    • spec.reclaimPolicy
      string

      What happens to a greenfield bucket’s data when the claim (and its owned Bucket) is deleted. Ignored for brownfield.

      • Retain (default) — the bucket and its objects are kept.
      • Delete — the bucket and all its objects are deleted.

      Default: Retain

      Allowed values: Retain, Delete

  • status
    object
    Observed state of the claim.
    • status.boundBucketName
      string
      Name of the cluster-scoped Bucket this claim is bound to.
    • status.conditions
      array of objects
      Per-stage conditions: Bound, BucketReady, and the aggregate Ready.
      • status.conditions.lastTransitionTime
        string
        Timestamp of the last status transition for this condition.
      • status.conditions.message
        string
        Human-readable explanation of the current status.

        Maximum length: 32768

      • status.conditions.observedGeneration
        integer
        Value of metadata.generation the condition was last set against.

        Allowed values: 0 <= X

      • status.conditions.reason
        string
        Machine-readable reason for the current status, suitable for log filtering.

        Length: 1..1024

        Pattern: ^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$

      • status.conditions.status
        string
        Current status of the condition.

        Allowed values: True, False, Unknown

      • status.conditions.type
        string
        Condition type, for example Ready, Bound, or BucketReady.

        Maximum length: 316

        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])$

    • status.endpoint
      string
      In-cluster S3 endpoint URL of the backing ObjectStore.
    • status.observedGeneration
      integer
      Most recent metadata.generation reconciled by the controller.
    • status.phase
      string
      Coarse-grained summary derived from conditions.

      Allowed values: Pending, InProgress, Ready, Error

BucketClaimPolicy

Short names: bcp

Scope: Namespaced
Version: v1alpha1

BucketClaimPolicy declares which namespaces may bind a Shared cluster-scoped Bucket (via a brownfield BucketClaim) and, with it, obtain credentials via BucketAccess. Access is deny-by-default: it is only granted when at least one policy for the bucket matches the consuming namespace. Multiple policies for the same bucket are additive (their allowed sets are unioned).

The policy must live in the bucket’s OWNER namespace — the namespace of the BucketClaim that provisioned the bucket (Bucket.spec.claimRef.namespace), or the module namespace (d8-sds-object) for administrator-declared Shared buckets. Sharing is therefore granted by whoever owns the bucket. A policy created in any other namespace grants nothing: the controller reports it with phase Error and reason NotOwnerNamespace rather than applying it.

  • spec
    object
    Desired policy.
    • spec.allowedNamespaces
      object

      Required value

      Namespaces permitted to request access to the bucket. A namespace matches when it appears in names or fully matches any RE2 regular expression in patterns.
      • spec.allowedNamespaces.names
        array of strings
        Exact namespace names allowed.
        • spec.allowedNamespaces.names.Element of the array
          string

          Maximum length: 253

      • spec.allowedNamespaces.patterns
        array of strings
        RE2 regular expressions matched (anchored, full-string) against the namespace name, e.g. team-.*.
        • spec.allowedNamespaces.patterns.Element of the array
          string

          Maximum length: 253

    • spec.bucketRef
      string

      Required value

      Name of the cluster-scoped Bucket this policy governs. The policy is honored only when it lives in that bucket’s owner namespace. Immutable after creation.

      Length: 1..63

      Pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$

  • status
    object
    Observed state of the policy.
    • status.conditions
      array of objects
      Latest state. Known type: Ready.
      • status.conditions.lastTransitionTime
        string
        Timestamp of the last status transition for this condition.
      • status.conditions.message
        string
        Human-readable explanation of the current status.

        Maximum length: 32768

      • status.conditions.observedGeneration
        integer
        Value of metadata.generation the condition was last set against.

        Allowed values: 0 <= X

      • status.conditions.reason
        string
        Machine-readable reason for the current status, suitable for log filtering.

        Length: 1..1024

        Pattern: ^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$

      • status.conditions.status
        string
        Current status of the condition.

        Allowed values: True, False, Unknown

      • status.conditions.type
        string
        Condition type, for example Ready.

        Maximum length: 316

        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])$

    • status.observedGeneration
      integer
      Most recent metadata.generation reconciled by the controller.
    • status.phase
      string
      Coarse-grained summary. Ready when the policy is valid and its bucket exists; Error when a pattern fails to compile.

      Allowed values: Pending, Ready, Error

ObjectStore

Short names: ostore

Scope: Cluster
Version: v1alpha1

ObjectStore describes the desired state of an S3-compatible object storage cluster managed by the sds-object module. A single spec.type selects one of four turnkey profiles; the backend (Garage / SeaweedFS / Ceph RGW) and its low-level settings are hidden from the user (noops).

Buckets are declared separately in cluster-scoped Bucket resources that reference this cluster by name; per-namespace credentials are requested via BucketAccess.

  • spec
    object
    Desired state of the object storage cluster.
    • spec.elasticClusterRef
      string
      Name of the ElasticCluster (sds-elastic) the Ceph CephObjectStore is provisioned on. Required and only allowed when spec.type is Heavy. Immutable after creation.

      Maximum length: 30

      Pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$

    • spec.placement
      object
      Scheduling of the cluster data plane. For type: System placement is forced onto control-plane nodes and these fields are ignored.
      • spec.placement.nodeSelector
        object
        Node labels the data-plane Pods must match (same semantics as a Pod’s spec.nodeSelector).
      • spec.placement.tolerations
        array of objects
        Tolerations for the data-plane Pods (same shape as a Pod’s spec.tolerations).
        • spec.placement.tolerations.effect
          string

          Allowed values: ‘’, NoSchedule, PreferNoSchedule, NoExecute

        • spec.placement.tolerations.key
          string
        • spec.placement.tolerations.operator
          string

          Allowed values: Exists, Equal

        • spec.placement.tolerations.tolerationSeconds
          integer
        • spec.placement.tolerations.value
          string
    • spec.reclaimPolicy
      string

      What happens to the backend data plane and its persisted data when the ObjectStore is deleted.

      • Retain (default) — persisted data is preserved. For Heavy the Ceph RGW pools are kept (preservePoolsOnDelete: true), so no stored objects are lost; the CephObjectStore itself is still removed, because leaving it behind would keep the Ceph cluster in use and block the ElasticCluster from ever being deleted. For other profiles the PVCs/hostPath data are left in place.
      • Delete — the backend data (PVCs, hostPath data, or Ceph RGW pools) is destroyed.

      Immutable after creation.

      Default: Retain

      Allowed values: Retain, Delete

    • spec.redundancy
      string

      High-level fault-tolerance intent. The controller maps it to backend-specific settings (replication factor / erasure coding). When omitted, defaults to Standard.

      • None — no redundancy (single copy). Lowest overhead. Not accepted for Heavy: a Ceph RGW data pool below size 3 gives no usable redundancy.
      • Standard — replicated copies across nodes/zones (typical default).
      • High — maximum durability (extra replicas or erasure coding), requires more nodes.

      Immutable after creation: changing the replication factor on a live cluster is not supported.

      For System the only accepted value is None, which runs a single Garage replica (factor 1) instead of the default 3, and it is the one case where the field may be changed afterwards: the module sets it from sdsObject.systemBucket.singleReplica. Switching it RECREATES the system store — the data plane is torn down and rebuilt empty, so every stored object is lost (buckets are recreated and access keys re-issued automatically).

      Allowed values: None, Standard, High

    • spec.storage
      object
      Capacity and backing storage. Ignored for type: Heavy (capacity comes from the referenced Ceph cluster).
      • spec.storage.class
        string
        Name of the Kubernetes StorageClass used to provision PVCs. Required for Lightweight and Full; ignored for System (managed local StorageClass) and Heavy (Ceph).

        Length: 1..253

      • spec.storage.nodes
        integer
        Number of data-plane nodes (StatefulSet replicas for Lightweight, SeaweedFS volume servers for Full). When unset, the count is derived from redundancy. Ignored for System (a fixed 3-replica set) and Heavy (topology comes from the referenced Ceph cluster).

        Allowed values: 1 <= X

      • spec.storage.sizePerNode
        string
        Usable capacity provisioned per data-plane node as a Kubernetes Quantity (BinarySI), e.g. 50Gi or 2Ti. The cluster-wide capacity is roughly sizePerNode times the node count. Defaults to 10Gi when unset. Must not be set for System (local PVs on control-plane nodes).

        Pattern: ^[0-9]+(\.[0-9]+)?(Ki|Mi|Gi|Ti|Pi|Ei|k|M|G|T|P|E)?$

    • spec.type
      string

      Required value

      Cluster profile. Selects the backend and placement model:

      • System — Garage, deployed as a StatefulSet on control-plane nodes with node-sticky local PVs: 3 replicas by default, or a single one with redundancy: None. The count is independent of the master count. For platform/system needs (backups, registry, logs). storage.class is ignored.
      • Lightweight — Garage, deployed as a StatefulSet backed by PVCs on storage.class. For small application workloads.
      • Full — SeaweedFS (master/volume/filer + S3 gateway), backed by PVCs on storage.class. Scalable, full-featured.
      • Heavy — Ceph RADOS Gateway (CephObjectStore) on top of an existing sds-elastic cluster referenced by elasticClusterRef. Reuses Ceph capacity and HA.

      Immutable after creation.

      Allowed values: System, Lightweight, Full, Heavy

  • status
    object
    Observed state of the object storage cluster.
    • status.adminSecretRef
      object

      Reference to the Secret (in the module namespace) holding the backend admin credentials used by the controller to manage buckets and access keys.

      Not published for Heavy: its RGW credentials are owned by Rook and live in the sds-elastic namespace, not this module’s.

      • status.adminSecretRef.name
        string
    • status.backend
      object
      Resolved backend implementation behind spec.type.
      • status.backend.type
        string
        Backend implementing the selected profile.

        Allowed values: Garage, SeaweedFS, CephRGW

      • status.backend.version
        string
        Running backend version.
    • status.capacity
      object
      Cluster-wide storage usage reported by the backend.
      • status.capacity.available
        string
        Free capacity, Kubernetes Quantity (BinarySI).
      • status.capacity.lastUpdated
        string
        Timestamp of the latest capacity probe.
      • status.capacity.total
        string
        Total usable capacity, Kubernetes Quantity (BinarySI).
      • status.capacity.used
        string
        Consumed capacity, Kubernetes Quantity (BinarySI).
      • status.capacity.usedPercent
        string
        used / total * 100, formatted with two decimals.
    • status.conditions
      array of objects
      Per-component conditions: BackendReady, EndpointReady, and the aggregate Ready.
      • status.conditions.lastTransitionTime
        string
        Timestamp of the last status transition for this condition.
      • status.conditions.message
        string
        Human-readable explanation of the current status.

        Maximum length: 32768

      • status.conditions.observedGeneration
        integer
        Value of metadata.generation the condition was last set against.

        Allowed values: 0 <= X

      • status.conditions.reason
        string
        Machine-readable reason for the current status, suitable for log filtering.

        Length: 1..1024

        Pattern: ^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$

      • status.conditions.status
        string
        Current status of the condition.

        Allowed values: True, False, Unknown

      • status.conditions.type
        string
        Condition type, for example Ready, BackendReady, or EndpointReady.

        Maximum length: 316

        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])$

    • status.endpoint
      object
      S3 endpoint clients use to reach this cluster.
      • status.endpoint.internal
        string
        In-cluster S3 endpoint URL (Service DNS), e.g. http://system.d8-sds-object.svc.cluster.local.
      • status.endpoint.region
        string
        Default S3 region advertised by the endpoint.
    • status.observedGeneration
      integer
      Most recent metadata.generation reconciled by the controller.
    • status.phase
      string
      Coarse-grained summary derived from Conditions.

      Allowed values: Pending, InProgress, Ready, Error