The number of RDB Pods. Decide this before creating your RegattaCluster resource
spec.rdb.devices
1; minimum 1
Yes
The number of raw block devices given to every RDB Pod
spec.rdb.service.type
ClusterIP
No
How the aggregate RDB Kubernetes Service (the Service that selects every RDB Pod together) is exposed. ClusterIP keeps it reachable only from inside your Kubernetes cluster. LoadBalancer additionally requests an externally reachable address; this is optional, and the resulting address is shared/load-balanced across every RDB Pod, not reserved for one client - see Networking
spec.rdb.service.port
spec.rdb.port
No
The port RegattaDB clients connect to on the aggregate RDB Kubernetes Service, for database queries. It defaults to spec.rdb.port, but unlike spec.rdb.port (immutable), you can change it later: it only changes the Service’s exposed port, not the port RDB listens on inside the container
spec.rdb.service.loadBalancerSourceRanges
Optional
No
CIDR blocks allowed to reach the aggregate RDB Service when spec.rdb.service.type is LoadBalancer; ignored for ClusterIP. Enforcement depends on your cluster’s LoadBalancer integration - GKE enforces it as a firewall rule, but behavior varies by cloud provider and on-prem controller, so verify it actually restricts traffic on your platform before relying on it
spec.rdb.blockStorage.size
Required
Cannot change
Capacity of each raw block device; must resolve to more than 0 bytes
spec.rdb.blockStorage.storageClassName
Optional
Cannot change
StorageClass that provisions the raw block devices dynamically. If omitted, Kubernetes uses your cluster’s default StorageClass, if one is set; otherwise the PVCs stay Pending
spec.rdb.blockStorage.accessModes
[ReadWriteOnce]
Cannot change
Access modes requested for each raw block device. ReadWriteOncePod must be used alone
spec.rdb.blockStorage.provisioning
Dynamic
Cannot change
Dynamic provisions devices from the named StorageClass. Static binds to PersistentVolumes you pre-create; see Choosing dynamic or static RDB storage below
spec.rdb.blockStorage.selector
Required for Static; rejected for Dynamic
Cannot change
Selector (matchLabels/matchExpressions) matching the PersistentVolumes to bind, when using Static provisioning
Every setting under spec.rdb.blockStorage is fixed once your RegattaCluster resource is created, because Kubernetes does not allow changing a StatefulSet’s storage templates. Choose these values carefully up front.
accessModes is a list mainly so you can request ReadWriteOncePod instead of the default ReadWriteOnce. ReadWriteOncePod restricts the volume to exactly one Pod cluster-wide, stricter than ReadWriteOnce (which technically still permits multiple Pods on the same Kubernetes node); some customers prefer it for raw block storage. ReadOnlyMany and ReadWriteMany are part of the underlying Kubernetes API but are not meaningful choices here - RDB’s raw block storage is always single-writer, one device per Pod.
Every RDB Pod can be given more than one raw block device: set spec.rdb.devices to the total device count per Pod. All devices on an RDB Pod share the same spec.rdb.blockStorage settings; there is no per-device size or StorageClass. Device indexes start at 0: the first device is /dev/rdb0, the second is /dev/rdb1, and so on. A RegattaCluster with spec.rdb.replicas: 3 and spec.rdb.devices: 2 creates 6 raw block PVCs in total (2 per RDB Pod):
In short: use Dynamic if your cluster has a StorageClass that provisions raw block volumes on demand, and use Static if your raw block storage is provisioned outside Kubernetes (for example pre-attached local disks) or your environment does not support dynamic block provisioning.spec.rdb.blockStorage.provisioning selects how Kubernetes obtains the raw block PersistentVolumes for RDB:
Dynamic (the default): a StorageClass, named in spec.rdb.blockStorage.storageClassName, provisions a new PersistentVolume for every raw block PVC on demand. Use this when your Kubernetes cluster has a StorageClass that supports volumeMode: Block. Do not set spec.rdb.blockStorage.selector with Dynamic provisioning: Kubernetes never dynamically provisions a PersistentVolumeClaim that has a selector, so the PVC would stay Pending indefinitely; the operator rejects this combination up front instead.
Static: you pre-create the PersistentVolumes yourself, and spec.rdb.blockStorage.selector (matchLabels or matchExpressions) tells the operator which ones to bind. Use this when your raw block storage is provisioned outside Kubernetes, for example pre-attached local disks, or your environment does not allow dynamic provisioning for raw block storage.
With Static provisioning, you need at least spec.rdb.replicas * spec.rdb.devicesPersistentVolumes that match the selector, StorageClass, requested access modes, volumeMode: Block, and requested capacity, and that are available or already bound to your claims.The cluster-scoped read-only permission you installed in Installation lets the operator check these conditions before applying resources, so problems surface early. If that permission is ever missing or denied, the operator skips this check and relies on normal PVC binding as the readiness signal instead.See Example: Two Local NVMe Devices, One RDB Replica for a full walkthrough of static provisioning.
spec.repoStorage and spec.logs are Pod-level settings, applying equally to the SM Pod and every RDB Pod. spec.repoStorage backs RegattaDB’s mutable runtime repository paths. spec.logs backs RegattaDB’s own log output at /var/log/regatta. See Prepare For Deployment for the underlying storage-sizing guidance this maps to. Neither field has a default size - you must size both for your workload; storageClassName falls back to your cluster’s default StorageClass if omitted.
Field
Required/default
Immutable
Description
spec.repoStorage.size
Required
Cannot change
Filesystem capacity for RegattaDB’s mutable repository paths, on every Pod; must resolve to more than 0 bytes
spec.repoStorage.storageClassName
Optional
Cannot change
StorageClass for repository storage. If omitted, Kubernetes uses your cluster’s default StorageClass, if one is set; otherwise the PVCs stay Pending
spec.repoStorage.accessModes
[ReadWriteOnce]
Cannot change
Access modes requested for the repository storage. ReadWriteOncePod must be used alone
spec.logs.size
Required
Cannot change
Filesystem capacity for /var/log/regatta, on every Pod; must resolve to more than 0 bytes
spec.logs.storageClassName
Optional
Cannot change
StorageClass for log storage. If omitted, Kubernetes uses your cluster’s default StorageClass, if one is set; otherwise the PVCs stay Pending
spec.logs.accessModes
[ReadWriteOnce]
Cannot change
Access modes requested for the log storage.
Storage size, StorageClass, and access modes for spec.repoStorage and spec.logs cannot change once your RegattaCluster resource is created, for the same reason as spec.rdb.blockStorage. Choose these values carefully up front.
Every raw block device on an RDB Pod is backed by its own PersistentVolumeClaim, generated from the claim-template name, the RDB StatefulSet name, and the Pod ordinal. For a RegattaCluster named my-regattadb, device 0 of RDB Pod 0 produces the PVC rdb-block-0-my-regattadb-rdb-0; device 1 of the same Pod produces rdb-block-1-my-regattadb-rdb-0, and so on.Storage readiness requires every one of these PVCs, for every RDB Pod, to be bound before RegattaDB is configured. An RDB Pod with spec.rdb.devices: 2 stays pending until both of its raw block PVCs are bound, not just one.
RDB Pods run as the non-root user and group configured in spec.security (UID 1000/GID 1001 by default) and additionally receive Linux supplemental group 6, the conventional disk group on most Linux distributions, so that user can open the raw block devices without running as root. The SM Pod does not receive this supplemental group, because it has no raw block devices.Whether group 6 actually grants access depends on which Linux group your storage and container runtime assign to the device node inside the Pod. For deterministic, non-root device ownership, configure your container runtime to derive device ownership from the Pod’s security context: set device_ownership_from_security_context = true under containerd, or the equivalent option under [crio.runtime] for CRI-O. Validate this on one RDB Pod, for example by checking device ownership inside the Pod, before relying on it for production.
Was this page helpful?
{"docsConfig":{"theme":"mint","$schema":"https://mintlify.com/docs.json","name":"Regatta","colors":{"primary":"#ff6600","light":"#FF6600","dark":"#ff6600"},"logo":{"light":"https://mintcdn.com/regatta/HR4-Kyi3p6WFSWx7/logo/Regatta_Logo_Colors_Black_RGB_1.svg?fit=max\u0026auto=format\u0026n=HR4-Kyi3p6WFSWx7\u0026q=85\u0026s=80ecf4af831aaabfecd51ca1c1dab7a7","dark":"https://mintcdn.com/regatta/HR4-Kyi3p6WFSWx7/logo/Regatta_Logo_Colors_White_RGB_1.svg?fit=max\u0026auto=format\u0026n=HR4-Kyi3p6WFSWx7\u0026q=85\u0026s=1be4bc683939b389d14aa1eeda3216d9"},"favicon":"https://mintcdn.com/regatta/xrn8wIqTNfsgHe4O/images/favicon.svg?fit=max\u0026auto=format\u0026n=xrn8wIqTNfsgHe4O\u0026q=85\u0026s=c025dcbef503c87e965049f809c4a3c4","background":{"color":{"light":"#f7f8fa","dark":"#041225"}},"navbar":{"links":[{"href":"https://rdbproject.atlassian.net/servicedesk/customer/portals","label":"Support"}],"primary":{"type":"button","label":"Start Coding","href":"https://regatta.dev/"}},"footer":{"socials":{"x":"https://twitter.com/regatta_data","linkedin":"https://www.linkedin.com/company/regatta-data"}},"fonts":{"family":"Inter"},"styling":{"latex":false},"navigation":{"pages":[]}},"deployment":{"deploymentMetadataValue":{"subdomain":"regatta","hasAudioNarration":false,"actualSubdomain":"regatta","customDomains":["docs.regatta.dev"],"gitSource":{"type":"github","owner":"regattadata","repo":"docs","deployBranch":"main","contentDirectory":"","isPrivate":true,"mountPath":"","label":""},"feedback":{"thumbs":true},"entitlements":{"AI_CHAT":{"status":"ENABLED"},"REMOVE_BRANDING":{"status":"ENABLED"},"CONTEXTUAL_FEEDBACK":{"status":"ENABLED"},"CODE_SNIPPET_FEEDBACK":{"status":"ENABLED"},"WEB_MCP":{"status":"ENABLED"},"NARRATION":{"status":"ENABLED"}},"buildId":"6af1eeb6572291321c9713bb","clientVersion":"0.0.4117","searchFilterCounts":[{"language":"default","tag":"SQL","count":84},{"language":"default","tag":"Self-Hosted Deployment","count":38},{"language":"default","tag":"Tuning Performance","count":20},{"language":"default","tag":"Regatta Deployment Tool","count":19},{"language":"default","tag":"Quickstart","count":18},{"language":"default","tag":"System Monitoring","count":18},{"language":"default","tag":"Drivers \u0026 Clients","count":16},{"language":"default","tag":"SQL Functions and Operators","count":15},{"language":"default","tag":"Kubernetes Deployment","count":13},{"language":"default","tag":"Hints","count":12}]},"assistantConfig":{},"basePath":"","hasChatPermissions":true,"hasWebMcpPermissions":true,"toggles":[{"name":"kill-isr","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"custom-rbac-roles","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"agent-mintlify-slack","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"agent-integrations-settings","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"rbac-expansion","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"automations-pr-grouping","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"custom-prefix","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"analytics-v7","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"user-flows-analytics","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"no-publish-flow","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"workos-onboarding","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"llms-txt-v2","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"snapshot-serving-live","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"stripTemperatureMiddleware","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"support-platform-pylon-zendesk","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"snapshot-serving","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"instant-rollback","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"granular-notifications-server","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"granular-notifications","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"automations-fable","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"fixed-ai-action-pricing","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"automation-resolve-merge-conflict","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"scoped-publishing","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"mintql","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"page-level-analytics","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"editor-version-history-v2","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"billing-page-v2","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"full-page-search","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"workspace-projects","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"assistant-v5","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"fork-pr-previews","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"revalidation-jwt","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"workos-sso-scim","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"hobby-abuse-scan","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"dashboard-inbox","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"workos-signup","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"turbopuffer-dual-write","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"workos-enabled","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"approve-review-flow","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"editor-metadata","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"sso-setup-deadline-banner","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"turbopuffer-serve","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"live-agents","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false}],"googleFontsInlined":false},"customCss":[{"filePath":"style.css","content":"body::-webkit-scrollbar{width:5px}body::-webkit-scrollbar-thumb{background-color:#888;border-radius:10px}body::-webkit-scrollbar-track{background-color:#f1f1f1}#sidebar-content::-webkit-scrollbar{display:none}table td:first-child,table th:first-child{max-width:16rem}table code{white-space:normal;overflow-wrap:break-word;word-break:break-word}"}],"page":{"pagePath":"self-hosted-deployment/kubernetes/configuration/storage","slug":"/self-hosted-deployment/kubernetes/configuration/storage","pageMetadata":{"title":"Storage","description":"Configure RDB block storage, repo and log storage, and raw block device access.","href":"/self-hosted-deployment/kubernetes/configuration/storage"},"description":{"compiledSource":"\"use strict\";\nconst {jsx: _jsx} = arguments[0];\nconst {useMDXComponents: _provideComponents} = arguments[0];\nfunction _createMdxContent(props) {\n const _components = {\n p: \"p\",\n ..._provideComponents(),\n ...props.components\n };\n return _jsx(_components.p, {\n children: \"Configure RDB block storage, repo and log storage, and raw block device access.\"\n });\n}\nfunction MDXContent(props = {}) {\n const {wrapper: MDXLayout} = {\n ..._provideComponents(),\n ...props.components\n };\n return MDXLayout ? _jsx(MDXLayout, {\n ...props,\n children: _jsx(_createMdxContent, {\n ...props\n })\n }) : _createMdxContent(props);\n}\nreturn {\n default: MDXContent\n};\n","frontmatter":{},"scope":{}},"pageType":"default","mdx":{"mdxSource":{"compiledSource":"\"use strict\";const{Fragment:_Fragment,jsx:_jsx,jsxs:_jsxs}=arguments[0];const{useMDXComponents:_provideComponents}=arguments[0];function _createMdxContent(props){const _components={a:`a`,code:`code`,li:`li`,p:`p`,pre:`pre`,span:`span`,tbody:`tbody`,td:`td`,th:`th`,thead:`thead`,tr:`tr`,ul:`ul`,..._provideComponents(),...props.components},{CodeBlock,Heading,Table,Warning}=_components;if(!CodeBlock)_missingMdxReference(`CodeBlock`,true);if(!Heading)_missingMdxReference(`Heading`,true);if(!Table)_missingMdxReference(`Table`,true);if(!Warning)_missingMdxReference(`Warning`,true);return _jsxs(_Fragment,{children:[_jsx(Heading,{level:`2`,id:`configure-rdb-replicas-and-storage`,children:`Configure RDB replicas and storage`}),`\n`,_jsxs(Table,{children:[_jsx(_components.thead,{children:_jsxs(_components.tr,{children:[_jsx(_components.th,{children:`Field`}),_jsx(_components.th,{children:`Required/default`}),_jsx(_components.th,{children:`Immutable`}),_jsx(_components.th,{children:`Description`})]})}),_jsxs(_components.tbody,{children:[_jsxs(_components.tr,{children:[_jsx(_components.td,{children:_jsx(_components.code,{children:`spec.rdb.replicas`})}),_jsxs(_components.td,{children:[`Required; minimum `,_jsx(_components.code,{children:`1`})]}),_jsx(_components.td,{children:`Yes`}),_jsxs(_components.td,{children:[`The number of RDB Pods. Decide this before creating your `,_jsx(_components.code,{children:`RegattaCluster`}),` resource`]})]}),_jsxs(_components.tr,{children:[_jsx(_components.td,{children:_jsx(_components.code,{children:`spec.rdb.devices`})}),_jsxs(_components.td,{children:[_jsx(_components.code,{children:`1`}),`; minimum `,_jsx(_components.code,{children:`1`})]}),_jsx(_components.td,{children:`Yes`}),_jsx(_components.td,{children:`The number of raw block devices given to every RDB Pod`})]}),_jsxs(_components.tr,{children:[_jsx(_components.td,{children:_jsx(_components.code,{children:`spec.rdb.service.type`})}),_jsx(_components.td,{children:_jsx(_components.code,{children:`ClusterIP`})}),_jsx(_components.td,{children:`No`}),_jsxs(_components.td,{children:[`How the aggregate RDB Kubernetes Service (the Service that selects every RDB Pod together) is exposed. `,_jsx(_components.code,{children:`ClusterIP`}),` keeps it reachable only from inside your Kubernetes cluster. `,_jsx(_components.code,{children:`LoadBalancer`}),` additionally requests an externally reachable address; this is optional, and the resulting address is shared/load-balanced across every RDB Pod, not reserved for one client - see `,_jsx(_components.a,{href:`/self-hosted-deployment/kubernetes/configuration/networking`,children:`Networking`})]})]}),_jsxs(_components.tr,{children:[_jsx(_components.td,{children:_jsx(_components.code,{children:`spec.rdb.service.port`})}),_jsx(_components.td,{children:_jsx(_components.code,{children:`spec.rdb.port`})}),_jsx(_components.td,{children:`No`}),_jsxs(_components.td,{children:[`The port RegattaDB clients connect to on the aggregate RDB Kubernetes Service, for database queries. It defaults to `,_jsx(_components.code,{children:`spec.rdb.port`}),`, but unlike `,_jsx(_components.code,{children:`spec.rdb.port`}),` (immutable), you can change it later: it only changes the Service’s exposed port, not the port RDB listens on inside the container`]})]}),_jsxs(_components.tr,{children:[_jsx(_components.td,{children:_jsx(_components.code,{children:`spec.rdb.service.loadBalancerSourceRanges`})}),_jsx(_components.td,{children:`Optional`}),_jsx(_components.td,{children:`No`}),_jsxs(_components.td,{children:[`CIDR blocks allowed to reach the aggregate RDB Service when `,_jsx(_components.code,{children:`spec.rdb.service.type`}),` is `,_jsx(_components.code,{children:`LoadBalancer`}),`; ignored for `,_jsx(_components.code,{children:`ClusterIP`}),`. Enforcement depends on your cluster’s LoadBalancer integration - GKE enforces it as a firewall rule, but behavior varies by cloud provider and on-prem controller, so verify it actually restricts traffic on your platform before relying on it`]})]}),_jsxs(_components.tr,{children:[_jsx(_components.td,{children:_jsx(_components.code,{children:`spec.rdb.blockStorage.size`})}),_jsx(_components.td,{children:`Required`}),_jsx(_components.td,{children:`Cannot change`}),_jsx(_components.td,{children:`Capacity of each raw block device; must resolve to more than 0 bytes`})]}),_jsxs(_components.tr,{children:[_jsx(_components.td,{children:_jsx(_components.code,{children:`spec.rdb.blockStorage.storageClassName`})}),_jsx(_components.td,{children:`Optional`}),_jsx(_components.td,{children:`Cannot change`}),_jsxs(_components.td,{children:[_jsx(_components.code,{children:`StorageClass`}),` that provisions the raw block devices dynamically. If omitted, Kubernetes uses your cluster’s default `,_jsx(_components.code,{children:`StorageClass`}),`, if one is set; otherwise the PVCs stay `,_jsx(_components.code,{children:`Pending`})]})]}),_jsxs(_components.tr,{children:[_jsx(_components.td,{children:_jsx(_components.code,{children:`spec.rdb.blockStorage.accessModes`})}),_jsx(_components.td,{children:_jsx(_components.code,{children:`[ReadWriteOnce]`})}),_jsx(_components.td,{children:`Cannot change`}),_jsxs(_components.td,{children:[`Access modes requested for each raw block device. `,_jsx(_components.code,{children:`ReadWriteOncePod`}),` must be used alone`]})]}),_jsxs(_components.tr,{children:[_jsx(_components.td,{children:_jsx(_components.code,{children:`spec.rdb.blockStorage.provisioning`})}),_jsx(_components.td,{children:_jsx(_components.code,{children:`Dynamic`})}),_jsx(_components.td,{children:`Cannot change`}),_jsxs(_components.td,{children:[_jsx(_components.code,{children:`Dynamic`}),` provisions devices from the named `,_jsx(_components.code,{children:`StorageClass`}),`. `,_jsx(_components.code,{children:`Static`}),` binds to `,_jsx(_components.code,{children:`PersistentVolumes`}),` you pre-create; see `,_jsx(_components.a,{href:`#choosing-dynamic-or-static-rdb-storage`,children:`Choosing dynamic or static RDB storage`}),` below`]})]}),_jsxs(_components.tr,{children:[_jsx(_components.td,{children:_jsx(_components.code,{children:`spec.rdb.blockStorage.selector`})}),_jsxs(_components.td,{children:[`Required for `,_jsx(_components.code,{children:`Static`}),`; rejected for `,_jsx(_components.code,{children:`Dynamic`})]}),_jsx(_components.td,{children:`Cannot change`}),_jsxs(_components.td,{children:[`Selector (`,_jsx(_components.code,{children:`matchLabels`}),`/`,_jsx(_components.code,{children:`matchExpressions`}),`) matching the `,_jsx(_components.code,{children:`PersistentVolumes`}),` to bind, when using `,_jsx(_components.code,{children:`Static`}),` provisioning`]})]})]})]}),`\n`,_jsx(Warning,{children:_jsxs(_components.p,{children:[`Every setting under `,_jsx(_components.code,{children:`spec.rdb.blockStorage`}),` is fixed once your `,_jsx(_components.code,{children:`RegattaCluster`}),` resource is created, because Kubernetes does not allow changing a StatefulSet’s storage templates. Choose these values carefully up front.`]})}),`\n`,_jsxs(_components.ul,{children:[`\n`,_jsxs(_components.li,{children:[_jsx(_components.code,{children:`accessModes`}),` is a list mainly so you can request `,_jsx(_components.code,{children:`ReadWriteOncePod`}),` instead of the default `,_jsx(_components.code,{children:`ReadWriteOnce`}),`. `,_jsx(_components.code,{children:`ReadWriteOncePod`}),` restricts the volume to exactly one Pod cluster-wide, stricter than `,_jsx(_components.code,{children:`ReadWriteOnce`}),` (which technically still permits multiple Pods on the same Kubernetes node); some customers prefer it for raw block storage. `,_jsx(_components.code,{children:`ReadOnlyMany`}),` and `,_jsx(_components.code,{children:`ReadWriteMany`}),` are part of the underlying Kubernetes API but are not meaningful choices here - RDB’s raw block storage is always single-writer, one device per Pod.`]}),`\n`,_jsxs(_components.li,{children:[`Every RDB Pod can be given more than one raw block device: set `,_jsx(_components.code,{children:`spec.rdb.devices`}),` to the total device count per Pod. All devices on an RDB Pod share the same `,_jsx(_components.code,{children:`spec.rdb.blockStorage`}),` settings; there is no per-device size or `,_jsx(_components.code,{children:`StorageClass`}),`. Device indexes start at `,_jsx(_components.code,{children:`0`}),`: the first device is `,_jsx(_components.code,{children:`/dev/rdb0`}),`, the second is `,_jsx(_components.code,{children:`/dev/rdb1`}),`, and so on. A `,_jsx(_components.code,{children:`RegattaCluster`}),` with `,_jsx(_components.code,{children:`spec.rdb.replicas: 3`}),` and `,_jsx(_components.code,{children:`spec.rdb.devices: 2`}),` creates 6 raw block PVCs in total (2 per RDB Pod):`]}),`\n`]}),`\n`,_jsx(CodeBlock,{filename:``,numberOfLines:`6`,language:`yaml`,children:_jsx(_components.pre,{className:`shiki shiki-themes github-light-default dark-plus`,style:{backgroundColor:`#ffffff`,\"--shiki-dark-bg\":`#0B0C0E`,color:`#1f2328`,\"--shiki-dark\":`#D4D4D4`},language:`yaml`,children:_jsxs(_components.code,{language:`yaml`,numberOfLines:`6`,children:[_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#116329`,\"--shiki-dark\":`#569CD6`},children:`rdb`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`:`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#116329`,\"--shiki-dark\":`#569CD6`},children:` replicas`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`: `}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#B5CEA8`},children:`3`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#116329`,\"--shiki-dark\":`#569CD6`},children:` devices`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`: `}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#B5CEA8`},children:`2`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#116329`,\"--shiki-dark\":`#569CD6`},children:` blockStorage`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`:`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#116329`,\"--shiki-dark\":`#569CD6`},children:` size`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`: `}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:`500Gi`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#116329`,\"--shiki-dark\":`#569CD6`},children:` storageClassName`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`: `}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:`\u003cstorage-class>`})]}),`\n`]})})}),`\n`,_jsx(Heading,{level:`3`,id:`choosing-dynamic-or-static-rdb-storage`,children:`Choosing dynamic or static RDB storage`}),`\n`,_jsxs(_components.p,{children:[`In short: use `,_jsx(_components.code,{children:`Dynamic`}),` if your cluster has a `,_jsx(_components.code,{children:`StorageClass`}),` that provisions raw block volumes on demand, and use `,_jsx(_components.code,{children:`Static`}),` if your raw block storage is provisioned outside Kubernetes (for example pre-attached local disks) or your environment does not support dynamic block provisioning.`]}),`\n`,_jsxs(_components.p,{children:[_jsx(_components.code,{children:`spec.rdb.blockStorage.provisioning`}),` selects how Kubernetes obtains the raw block `,_jsx(_components.code,{children:`PersistentVolumes`}),` for RDB:`]}),`\n`,_jsxs(_components.ul,{children:[`\n`,_jsxs(_components.li,{children:[_jsx(_components.code,{children:`Dynamic`}),` (the default): a `,_jsx(_components.code,{children:`StorageClass`}),`, named in `,_jsx(_components.code,{children:`spec.rdb.blockStorage.storageClassName`}),`, provisions a new `,_jsx(_components.code,{children:`PersistentVolume`}),` for every raw block PVC on demand. Use this when your Kubernetes cluster has a `,_jsx(_components.code,{children:`StorageClass`}),` that supports `,_jsx(_components.code,{children:`volumeMode: Block`}),`. Do not set `,_jsx(_components.code,{children:`spec.rdb.blockStorage.selector`}),` with `,_jsx(_components.code,{children:`Dynamic`}),` provisioning: Kubernetes never dynamically provisions a `,_jsx(_components.code,{children:`PersistentVolumeClaim`}),` that has a selector, so the PVC would stay `,_jsx(_components.code,{children:`Pending`}),` indefinitely; the operator rejects this combination up front instead.`]}),`\n`,_jsxs(_components.li,{children:[_jsx(_components.code,{children:`Static`}),`: you pre-create the `,_jsx(_components.code,{children:`PersistentVolumes`}),` yourself, and `,_jsx(_components.code,{children:`spec.rdb.blockStorage.selector`}),` (`,_jsx(_components.code,{children:`matchLabels`}),` or `,_jsx(_components.code,{children:`matchExpressions`}),`) tells the operator which ones to bind. Use this when your raw block storage is provisioned outside Kubernetes, for example pre-attached local disks, or your environment does not allow dynamic provisioning for raw block storage.`]}),`\n`]}),`\n`,_jsxs(_components.p,{children:[`With `,_jsx(_components.code,{children:`Static`}),` provisioning, you need at least `,_jsx(_components.code,{children:`spec.rdb.replicas * spec.rdb.devices`}),` `,_jsx(_components.code,{children:`PersistentVolumes`}),` that match the selector, `,_jsx(_components.code,{children:`StorageClass`}),`, requested access modes, `,_jsx(_components.code,{children:`volumeMode: Block`}),`, and requested capacity, and that are available or already bound to your claims.`]}),`\n`,_jsxs(_components.p,{children:[`The cluster-scoped read-only permission you installed in `,_jsx(_components.a,{href:`/self-hosted-deployment/kubernetes/installation`,children:`Installation`}),` lets the operator check these conditions before applying resources, so problems surface early. If that permission is ever missing or denied, the operator skips this check and relies on normal PVC binding as the readiness signal instead.`]}),`\n`,_jsxs(_components.p,{children:[`See `,_jsx(_components.a,{href:`/self-hosted-deployment/kubernetes/examples/static-storage-local-nvme`,children:`Example: Two Local NVMe Devices, One RDB Replica`}),` for a full walkthrough of static provisioning.`]}),`\n`,_jsx(Heading,{level:`2`,id:`configure-repo-and-log-storage`,children:`Configure repo and log storage`}),`\n`,_jsxs(_components.p,{children:[_jsx(_components.code,{children:`spec.repoStorage`}),` and `,_jsx(_components.code,{children:`spec.logs`}),` are Pod-level settings, applying equally to the SM Pod and every RDB Pod. `,_jsx(_components.code,{children:`spec.repoStorage`}),` backs RegattaDB’s mutable runtime repository paths. `,_jsx(_components.code,{children:`spec.logs`}),` backs RegattaDB’s own log output at `,_jsx(_components.code,{children:`/var/log/regatta`}),`. See `,_jsx(_components.a,{href:`https://docs.regatta.dev/self-hosted-deployment/manual-deployment/prepare-for-deployment`,children:`Prepare For Deployment`}),` for the underlying storage-sizing guidance this maps to. Neither field has a default size - you must size both for your workload; `,_jsx(_components.code,{children:`storageClassName`}),` falls back to your cluster’s default `,_jsx(_components.code,{children:`StorageClass`}),` if omitted.`]}),`\n`,_jsxs(Table,{children:[_jsx(_components.thead,{children:_jsxs(_components.tr,{children:[_jsx(_components.th,{children:`Field`}),_jsx(_components.th,{children:`Required/default`}),_jsx(_components.th,{children:`Immutable`}),_jsx(_components.th,{children:`Description`})]})}),_jsxs(_components.tbody,{children:[_jsxs(_components.tr,{children:[_jsx(_components.td,{children:_jsx(_components.code,{children:`spec.repoStorage.size`})}),_jsx(_components.td,{children:`Required`}),_jsx(_components.td,{children:`Cannot change`}),_jsx(_components.td,{children:`Filesystem capacity for RegattaDB’s mutable repository paths, on every Pod; must resolve to more than 0 bytes`})]}),_jsxs(_components.tr,{children:[_jsx(_components.td,{children:_jsx(_components.code,{children:`spec.repoStorage.storageClassName`})}),_jsx(_components.td,{children:`Optional`}),_jsx(_components.td,{children:`Cannot change`}),_jsxs(_components.td,{children:[_jsx(_components.code,{children:`StorageClass`}),` for repository storage. If omitted, Kubernetes uses your cluster’s default `,_jsx(_components.code,{children:`StorageClass`}),`, if one is set; otherwise the PVCs stay `,_jsx(_components.code,{children:`Pending`})]})]}),_jsxs(_components.tr,{children:[_jsx(_components.td,{children:_jsx(_components.code,{children:`spec.repoStorage.accessModes`})}),_jsx(_components.td,{children:_jsx(_components.code,{children:`[ReadWriteOnce]`})}),_jsx(_components.td,{children:`Cannot change`}),_jsxs(_components.td,{children:[`Access modes requested for the repository storage. `,_jsx(_components.code,{children:`ReadWriteOncePod`}),` must be used alone`]})]}),_jsxs(_components.tr,{children:[_jsx(_components.td,{children:_jsx(_components.code,{children:`spec.logs.size`})}),_jsx(_components.td,{children:`Required`}),_jsx(_components.td,{children:`Cannot change`}),_jsxs(_components.td,{children:[`Filesystem capacity for `,_jsx(_components.code,{children:`/var/log/regatta`}),`, on every Pod; must resolve to more than 0 bytes`]})]}),_jsxs(_components.tr,{children:[_jsx(_components.td,{children:_jsx(_components.code,{children:`spec.logs.storageClassName`})}),_jsx(_components.td,{children:`Optional`}),_jsx(_components.td,{children:`Cannot change`}),_jsxs(_components.td,{children:[_jsx(_components.code,{children:`StorageClass`}),` for log storage. If omitted, Kubernetes uses your cluster’s default `,_jsx(_components.code,{children:`StorageClass`}),`, if one is set; otherwise the PVCs stay `,_jsx(_components.code,{children:`Pending`})]})]}),_jsxs(_components.tr,{children:[_jsx(_components.td,{children:_jsx(_components.code,{children:`spec.logs.accessModes`})}),_jsx(_components.td,{children:_jsx(_components.code,{children:`[ReadWriteOnce]`})}),_jsx(_components.td,{children:`Cannot change`}),_jsx(_components.td,{children:`Access modes requested for the log storage.`})]})]})]}),`\n`,_jsx(Warning,{children:_jsxs(_components.p,{children:[`Storage size, `,_jsx(_components.code,{children:`StorageClass`}),`, and access modes for `,_jsx(_components.code,{children:`spec.repoStorage`}),` and `,_jsx(_components.code,{children:`spec.logs`}),` cannot change once your `,_jsx(_components.code,{children:`RegattaCluster`}),` resource is created, for the same reason as `,_jsx(_components.code,{children:`spec.rdb.blockStorage`}),`. Choose these values carefully up front.`]})}),`\n`,_jsx(Heading,{level:`2`,id:`multiple-rdb-devices-naming-and-readiness`,children:`Multiple RDB devices: naming and readiness`}),`\n`,_jsxs(_components.p,{children:[`Every raw block device on an RDB Pod is backed by its own `,_jsx(_components.code,{children:`PersistentVolumeClaim`}),`, generated from the claim-template name, the RDB StatefulSet name, and the Pod ordinal. For a `,_jsx(_components.code,{children:`RegattaCluster`}),` named `,_jsx(_components.code,{children:`my-regattadb`}),`, device `,_jsx(_components.code,{children:`0`}),` of RDB Pod `,_jsx(_components.code,{children:`0`}),` produces the PVC `,_jsx(_components.code,{children:`rdb-block-0-my-regattadb-rdb-0`}),`; device `,_jsx(_components.code,{children:`1`}),` of the same Pod produces `,_jsx(_components.code,{children:`rdb-block-1-my-regattadb-rdb-0`}),`, and so on.`]}),`\n`,_jsxs(_components.p,{children:[`Storage readiness requires every one of these PVCs, for every RDB Pod, to be bound before RegattaDB is configured. An RDB Pod with `,_jsx(_components.code,{children:`spec.rdb.devices: 2`}),` stays pending until both of its raw block PVCs are bound, not just one.`]}),`\n`,_jsx(Heading,{level:`2`,id:`non-root-access-to-raw-block-devices`,children:`Non-root access to raw block devices`}),`\n`,_jsxs(_components.p,{children:[`RDB Pods run as the non-root user and group configured in `,_jsx(_components.a,{href:`/self-hosted-deployment/kubernetes/configuration/security-and-lifecycle`,children:_jsx(_components.code,{children:`spec.security`})}),` (UID `,_jsx(_components.code,{children:`1000`}),`/GID `,_jsx(_components.code,{children:`1001`}),` by default) and additionally receive Linux supplemental group `,_jsx(_components.code,{children:`6`}),`, the conventional `,_jsx(_components.code,{children:`disk`}),` group on most Linux distributions, so that user can open the raw block devices without running as root. The SM Pod does not receive this supplemental group, because it has no raw block devices.`]}),`\n`,_jsxs(_components.p,{children:[`Whether group `,_jsx(_components.code,{children:`6`}),` actually grants access depends on which Linux group your storage and container runtime assign to the device node inside the Pod. For deterministic, non-root device ownership, configure your container runtime to derive device ownership from the Pod’s security context: set `,_jsx(_components.code,{children:`device_ownership_from_security_context = true`}),` under containerd, or the equivalent option under `,_jsx(_components.code,{children:`[crio.runtime]`}),` for CRI-O. Validate this on one RDB Pod, for example by checking device ownership inside the Pod, before relying on it for production.`]})]})}function MDXContent(props={}){const{wrapper:MDXLayout}={..._provideComponents(),...props.components};return MDXLayout?_jsx(MDXLayout,{...props,children:_jsx(_createMdxContent,{...props})}):_createMdxContent(props)}return{default:MDXContent};function _missingMdxReference(id,component){throw new Error(`Expected `+(component?`component`:`object`)+\" `\"+id+\"` to be defined: you likely forgot to import, pass, or provide it.\")}","frontmatter":{},"scope":{"config":{},"pageMetadata":{"title":"Storage","description":"Configure RDB block storage, repo and log storage, and raw block device access.","href":"/self-hosted-deployment/kubernetes/configuration/storage"}}},"mdxSourceWithNoJs":null},"mdxExtracts":{"tableOfContents":[{"title":"Configure RDB replicas and storage","slug":"configure-rdb-replicas-and-storage","depth":2,"children":[{"title":"Choosing dynamic or static RDB storage","slug":"choosing-dynamic-or-static-rdb-storage","depth":3,"children":[]}]},{"title":"Configure repo and log storage","slug":"configure-repo-and-log-storage","depth":2,"children":[]},{"title":"Multiple RDB devices: naming and readiness","slug":"multiple-rdb-devices-naming-and-readiness","depth":2,"children":[]},{"title":"Non-root access to raw block devices","slug":"non-root-access-to-raw-block-devices","depth":2,"children":[]}],"codeExamples":{}},"jsLinks":[],"subdomain":"regatta","siteName":"Regatta","title":"Storage - Regatta","navMaps":{"firstHrefInVersion":{},"firstHrefInLanguage":{}},"lastModified":"2026-09-28T14:37:08.888Z","originalFileLocation":"self-hosted-deployment/kubernetes/configuration/storage.mdx"},"headHtml":"\u003cscript data-mint-head>(function(){var d=document.documentElement,p=null;if(!p){try{p=localStorage.getItem(\"isDarkMode\")}catch(e){}if(p==='true')p='dark';else if(p==='false')p='light';if(p!=='light'\u0026\u0026p!=='dark'\u0026\u0026p!=='system')p=\"system\"}var r=p==='system'?(matchMedia(\"(prefers-color-scheme: dark)\").matches?'dark':'light'):p;d.classList.remove(r==='dark'?'light':'dark');d.classList.add(r);d.setAttribute(\"data-theme-preference\",p)})();\u003c/script>\u003cmeta data-mint-head name=\"description\" content=\"Configure RDB block storage, repo and log storage, and raw block device access.\">\u003cmeta data-mint-head name=\"application-name\" content=\"Regatta\">\u003cmeta data-mint-head name=\"generator\" content=\"Mintlify\">\u003clink data-mint-head rel=\"icon\" type=\"image/png\" sizes=\"192x192\" href=\"/mintlify-assets/_mintlify/favicons/regatta/gm5LFpBlkeZD76CN/_generated/favicon/android-chrome-192x192.png\" media=\"(prefers-color-scheme: light)\">\u003clink data-mint-head rel=\"apple-touch-icon\" type=\"image/png\" sizes=\"180x180\" href=\"/mintlify-assets/_mintlify/favicons/regatta/gm5LFpBlkeZD76CN/_generated/favicon/apple-touch-icon.png\">\u003clink data-mint-head rel=\"icon\" type=\"image/png\" sizes=\"16x16\" href=\"/mintlify-assets/_mintlify/favicons/regatta/gm5LFpBlkeZD76CN/_generated/favicon/favicon-16x16.png\" media=\"(prefers-color-scheme: light)\">\u003clink data-mint-head rel=\"icon\" type=\"image/png\" sizes=\"32x32\" href=\"/mintlify-assets/_mintlify/favicons/regatta/gm5LFpBlkeZD76CN/_generated/favicon/favicon-32x32.png\" media=\"(prefers-color-scheme: light)\">\u003clink data-mint-head rel=\"shortcut icon\" type=\"image/x-icon\" href=\"/mintlify-assets/_mintlify/favicons/regatta/gm5LFpBlkeZD76CN/_generated/favicon/favicon.ico\" media=\"(prefers-color-scheme: light)\">\u003clink data-mint-head rel=\"icon\" type=\"image/png\" sizes=\"192x192\" href=\"/mintlify-assets/_mintlify/favicons/regatta/gm5LFpBlkeZD76CN/_generated/favicon-dark/android-chrome-192x192.png\" media=\"(prefers-color-scheme: dark)\">\u003clink data-mint-head rel=\"icon\" type=\"image/png\" sizes=\"16x16\" href=\"/mintlify-assets/_mintlify/favicons/regatta/gm5LFpBlkeZD76CN/_generated/favicon-dark/favicon-16x16.png\" media=\"(prefers-color-scheme: dark)\">\u003clink data-mint-head rel=\"icon\" type=\"image/png\" sizes=\"32x32\" href=\"/mintlify-assets/_mintlify/favicons/regatta/gm5LFpBlkeZD76CN/_generated/favicon-dark/favicon-32x32.png\" media=\"(prefers-color-scheme: dark)\">\u003clink data-mint-head rel=\"shortcut icon\" type=\"image/x-icon\" href=\"/mintlify-assets/_mintlify/favicons/regatta/gm5LFpBlkeZD76CN/_generated/favicon-dark/favicon.ico\" media=\"(prefers-color-scheme: dark)\">\u003cmeta data-mint-head property=\"og:title\" content=\"Storage - Regatta\">\u003cmeta data-mint-head property=\"og:description\" content=\"Configure RDB block storage, repo and log storage, and raw block device access.\">\u003cmeta data-mint-head property=\"og:site_name\" content=\"Regatta\">\u003cmeta data-mint-head property=\"og:url\" content=\"https://docs.regatta.dev/self-hosted-deployment/kubernetes/configuration/storage\">\u003cmeta data-mint-head property=\"og:type\" content=\"website\">\u003cmeta data-mint-head property=\"og:image\" content=\"https://regatta.mintlify.site/_mintlify/api/og/v2?division=Configuration\u0026amp;title=Storage\u0026amp;description=Configure+RDB+block+storage%2C+repo+and+log+storage%2C+and+raw+block+device+access.\u0026amp;theme=acca279d31253fc5f4f921a2\u0026amp;signature=2908319e6df551b32a4f36c00c74428a624a22236f50aef7fa8d940a808d91d6\">\u003cmeta data-mint-head property=\"og:image:width\" content=\"1200\">\u003cmeta data-mint-head property=\"og:image:height\" content=\"630\">\u003cmeta data-mint-head name=\"twitter:card\" content=\"summary_large_image\">\u003cmeta data-mint-head name=\"twitter:title\" content=\"Storage - Regatta\">\u003cmeta data-mint-head name=\"twitter:description\" content=\"Configure RDB block storage, repo and log storage, and raw block device access.\">\u003cmeta data-mint-head name=\"twitter:image\" content=\"https://regatta.mintlify.site/_mintlify/api/og/v2?division=Configuration\u0026amp;title=Storage\u0026amp;description=Configure+RDB+block+storage%2C+repo+and+log+storage%2C+and+raw+block+device+access.\u0026amp;theme=acca279d31253fc5f4f921a2\u0026amp;signature=2908319e6df551b32a4f36c00c74428a624a22236f50aef7fa8d940a808d91d6\">\u003cmeta data-mint-head name=\"twitter:image:width\" content=\"1200\">\u003cmeta data-mint-head name=\"twitter:image:height\" content=\"630\">\u003cmeta data-mint-head name=\"msapplication-config\" content=\"/mintlify-assets/_mintlify/favicons/regatta/gm5LFpBlkeZD76CN/_generated/favicon/browserconfig.xml\">\u003cmeta data-mint-head name=\"apple-mobile-web-app-title\" content=\"Regatta\">\u003cmeta data-mint-head name=\"msapplication-TileColor\" content=\"#ff6600\">\u003clink data-mint-head rel=\"canonical\" href=\"https://docs.regatta.dev/self-hosted-deployment/kubernetes/configuration/storage\">\u003clink data-mint-head rel=\"alternate\" type=\"application/xml\" href=\"/sitemap.xml\">\u003clink data-mint-head rel=\"alternate\" type=\"text/markdown\" href=\"/self-hosted-deployment/kubernetes/configuration/storage.md\">\u003cscript data-mint-head type=\"application/ld+json\">{\"@context\":\"https://schema.org\",\"@graph\":[{\"@type\":\"Organization\",\"@id\":\"https://docs.regatta.dev/#organization\",\"name\":\"Regatta\",\"url\":\"https://docs.regatta.dev\",\"logo\":{\"@type\":\"ImageObject\",\"url\":\"https://mintcdn.com/regatta/HR4-Kyi3p6WFSWx7/logo/Regatta_Logo_Colors_Black_RGB_1.svg?fit=max\u0026auto=format\u0026n=HR4-Kyi3p6WFSWx7\u0026q=85\u0026s=80ecf4af831aaabfecd51ca1c1dab7a7\"}},{\"@type\":\"WebSite\",\"@id\":\"https://docs.regatta.dev#website\",\"name\":\"Regatta\",\"url\":\"https://docs.regatta.dev\",\"publisher\":{\"@id\":\"https://docs.regatta.dev/#organization\"}},{\"@type\":\"WebPage\",\"@id\":\"https://docs.regatta.dev/self-hosted-deployment/kubernetes/configuration/storage#webpage\",\"url\":\"https://docs.regatta.dev/self-hosted-deployment/kubernetes/configuration/storage\",\"name\":\"Storage\",\"description\":\"Configure RDB block storage, repo and log storage, and raw block device access.\",\"dateModified\":\"2026-09-28T14:37:08.888Z\",\"isPartOf\":{\"@id\":\"https://docs.regatta.dev#website\"},\"breadcrumb\":{\"@id\":\"https://docs.regatta.dev/self-hosted-deployment/kubernetes/configuration/storage#breadcrumb\"}},{\"@type\":\"BreadcrumbList\",\"@id\":\"https://docs.regatta.dev/self-hosted-deployment/kubernetes/configuration/storage#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Kubernetes Deployment\",\"item\":\"https://docs.regatta.dev/self-hosted-deployment/kubernetes/introduction\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Configuration\",\"item\":\"https://docs.regatta.dev/self-hosted-deployment/kubernetes/configuration/overview\"},{\"@type\":\"ListItem\",\"position\":3,\"name\":\"Storage\",\"item\":\"https://docs.regatta.dev/self-hosted-deployment/kubernetes/configuration/storage\"}]},{\"@type\":[\"Article\",\"TechArticle\"],\"@id\":\"https://docs.regatta.dev/self-hosted-deployment/kubernetes/configuration/storage#article\",\"headline\":\"Storage\",\"name\":\"Storage\",\"description\":\"Configure RDB block storage, repo and log storage, and raw block device access.\",\"url\":\"https://docs.regatta.dev/self-hosted-deployment/kubernetes/configuration/storage\",\"mainEntityOfPage\":{\"@id\":\"https://docs.regatta.dev/self-hosted-deployment/kubernetes/configuration/storage#webpage\"},\"dateModified\":\"2026-09-28T14:37:08.888Z\",\"publisher\":{\"@id\":\"https://docs.regatta.dev/#organization\"},\"isPartOf\":{\"@id\":\"https://docs.regatta.dev#website\"}}]}\u003c/script>","agentPointerHref":"/self-hosted-deployment/kubernetes/configuration/storage.md","siteName":"Regatta","nav":{"global":null,"anchors":[{"anchor":"Docs Home","icon":"house","pages":[{"title":"Docs Home","href":"/home"}]},{"anchor":"Quickstart","pages":[{"title":"Quickstart","href":"/getting-started/getting-started-using-regatta-cloud"}]},{"anchor":"SQL","icon":"code","pages":[{"title":"SQL","href":"/sql/introduction"}]},{"anchor":"Regatta Cloud","icon":"cloud","pages":[{"title":"Regatta Cloud","href":"/regatta-cloud/regatta-cloud/regatta-cloud"}]},{"anchor":"Self-Hosted Deployment","icon":"server","groups":[{"group":"Self-Hosted Deployment","pages":[{"title":"Prerequisites","href":"/self-hosted-deployment/prerequisites"}]},{"group":"Manual Deployment","pages":[{"title":"RegattaDB Software Modules","href":"/self-hosted-deployment/manual-deployment/regattadb-software-modules"},{"title":"Prepare for Deployment","href":"/self-hosted-deployment/manual-deployment/prepare-for-deployment"},{"title":"High-Level Deployment Steps","href":"/self-hosted-deployment/manual-deployment/high-level-deployment-steps"},{"title":"Deployment Example","href":"/self-hosted-deployment/manual-deployment/deployment-example"}]},{"group":"Regatta Deployment Tool","pages":[{"title":"Introduction","href":"/self-hosted-deployment/rdt/introduction"},{"title":"Prerequisites","href":"/self-hosted-deployment/rdt/prerequisites"},{"title":"Installation","href":"/self-hosted-deployment/rdt/installation"},{"title":"Command Reference","href":"/self-hosted-deployment/rdt/command-reference"},{"group":"Configuration","pages":[{"title":"Configuration Overview","href":"/self-hosted-deployment/rdt/configuration/overview"},{"title":"Creating \u0026 Managing Configs","href":"/self-hosted-deployment/rdt/configuration/creating-and-managing-configs"}]},{"group":"System Setup","pages":[{"title":"System Setup Overview","href":"/self-hosted-deployment/rdt/system-setup/overview"},{"title":"RegattaDB Lifecycle","href":"/self-hosted-deployment/rdt/system-setup/lifecycle"}]},{"group":"Examples","pages":[{"title":"Quickstart: Single-Node RegattaDB","href":"/self-hosted-deployment/rdt/examples/quickstart-single-node"},{"title":"Example: Multi-Node Deployment","href":"/self-hosted-deployment/rdt/examples/multi-node-deployment"},{"title":"Config Recipes","href":"/self-hosted-deployment/rdt/examples/config-recipes"},{"title":"Example: Collecting Debug Information","href":"/self-hosted-deployment/rdt/examples/collecting-debug-info"}]},{"group":"Advanced","pages":[{"title":"Global Options \u0026 Credentials","href":"/self-hosted-deployment/rdt/advanced/global-options-and-credentials"},{"title":"Running RDT in a Container","href":"/self-hosted-deployment/rdt/advanced/running-rdt-in-a-container"},{"title":"Offline Installation","href":"/self-hosted-deployment/rdt/advanced/offline-installation"},{"title":"What Changes on Your Nodes","href":"/self-hosted-deployment/rdt/advanced/node-system-changes"},{"title":"Module \u0026 NUMA Configuration","href":"/self-hosted-deployment/rdt/advanced/module-and-numa-configuration"}]},{"title":"Troubleshooting","href":"/self-hosted-deployment/rdt/troubleshooting"},{"title":"Release Notes","href":"/self-hosted-deployment/rdt/release-notes"}]},{"group":"Kubernetes Deployment","pages":[{"title":"Introduction","href":"/self-hosted-deployment/kubernetes/introduction"},{"title":"Prerequisites","href":"/self-hosted-deployment/kubernetes/prerequisites"},{"title":"Installation","href":"/self-hosted-deployment/kubernetes/installation"},{"group":"Configuration","pages":[{"title":"Configuration Overview","description":"The RegattaCluster resource: object header, version and image, and module settings.","href":"/self-hosted-deployment/kubernetes/configuration/overview"},{"title":"Storage","href":"/self-hosted-deployment/kubernetes/configuration/storage"},{"title":"Networking","description":"How the operator exposes SM and RDB Pods inside and outside your Kubernetes cluster.","href":"/self-hosted-deployment/kubernetes/configuration/networking"},{"title":"Security \u0026 Lifecycle","href":"/self-hosted-deployment/kubernetes/configuration/security-and-lifecycle"},{"title":"Resources \u0026 Scheduling","href":"/self-hosted-deployment/kubernetes/configuration/resources-and-scheduling"}]},{"group":"Examples","pages":[{"title":"Quickstart: Single-Node RegattaCluster","href":"/self-hosted-deployment/kubernetes/examples/quickstart-single-node"},{"title":"Example: Two Local NVMe Devices, One RDB Replica","href":"/self-hosted-deployment/kubernetes/examples/static-storage-local-nvme"}]},{"title":"Operations","href":"/self-hosted-deployment/kubernetes/operations"},{"title":"Troubleshooting","href":"/self-hosted-deployment/kubernetes/troubleshooting"},{"title":"Release Notes","href":"/self-hosted-deployment/kubernetes/release-notes"}]},{"group":"Collecting Data","hidden":true,"pages":[{"title":"Installation","href":"/self-hosted-deployment/collecting-data/installation"},{"title":"Setup","href":"/self-hosted-deployment/collecting-data/setup"},{"title":"Execution","href":"/self-hosted-deployment/collecting-data/execution"}]}]},{"anchor":"Drivers \u0026 Clients","icon":"download","pages":[{"title":"Drivers \u0026 Clients","href":"/drivers-and-clients/connecting-applications-to-regatta"}]},{"anchor":"Tuning Performance","icon":"rocket","pages":[{"title":"Tuning Performance","href":"/tuning-performance/introduction/introduction"}]}]},"basePath":"","title":"Storage - Regatta","buildId":"dpl_41S5Z2jG9QnfDRwN1KZrLdBwj7DM","deploymentId":"dpl_41S5Z2jG9QnfDRwN1KZrLdBwj7DM","dynamics":[],"chunks":[]}