Skip to main content
Version: main

Storage Pools

Storage pools let each node offer one or more named storage locations (for example, an NVMe pool and an HDD pool), each backed by its own filesystem with independent capacity reservations. This enables storage tiering - workloads select a tier by referencing the pool name in the StorageClass.

Configure Storage Pools

Pools are defined in the Helm chart values under node.storagePools. A node.defaultPool is required and must reference one of the defined pools.

node:
defaultPool: hdd
storagePools:
hdd:
path: /var/local/openebs/rawfile/hdd/
reservedCapacity: "10%"
reservedCapacityMode: plain
nvme:
path: /mnt/nvme/rawfile/
reservedCapacity: 20GiB
reservedCapacityMode: subtract-from-total

Apply the updated values:

helm upgrade rawfile-localpv rawfile-localpv/rawfile-localpv -n openebs -f values.yaml

Pool Naming Rules

Pool names must be DNS-compatible:

  • Length: 3–63 characters
  • Characters: letters (uppercase or lowercase), digits, and hyphens only
  • Cannot start or end with a hyphen

Reserved Capacity Modes

Each pool defines how much disk space is reserved for non-pool use.

ModeBehavior
plainThe pool grows until the specified capacity remains free on the backing filesystem. Suitable for shared disks.
subtract-from-totalThe pool is capped at total disk size − reserved amount. Suitable for dedicated disks.

plain example: A 1 TB disk with reservedCapacity: "10%" allows the pool to use up to 900 GB.

subtract-from-total example: A 1 TB disk with reservedCapacity: 20GiB caps the pool at 980 GB regardless of other filesystem usage.

Validation Rules

The driver validates pool configuration on startup:

  • Pool paths must exist or be creatable on each node.
  • Each pool must be on a distinct backing filesystem - multiple pools cannot share the same device.
  • The defaultPool must reference an existing pool entry.
  • Pool paths must be unique per node.

Copy-on-Write (CoW) Capable Pools

Snapshots and clones are always available, but pools backed by CoW-capable filesystems make them fast and space-efficient (reflinks, nearly instant). Pools without CoW support perform a full data copy.

FilesystemCoW Support
btrfsNative
XFSWith mkfs.xfs -m reflink=1
ext4No reflink support (full copy)

To create an XFS pool with reflink enabled:

mkfs.xfs -m reflink=1 /dev/sdb
mount /dev/sdb /mnt/nvme/rawfile/

Create StorageClasses per Pool

Create a separate StorageClass for each pool tier and reference the pool by name via the storagePool parameter:

apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
name: rawfile-nvme
provisioner: rawfile.csi.openebs.io
volumeBindingMode: WaitForFirstConsumer
reclaimPolicy: Delete
parameters:
csi.storage.k8s.io/fstype: xfs
storagePool: nvme
---
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
name: rawfile-hdd
provisioner: rawfile.csi.openebs.io
volumeBindingMode: WaitForFirstConsumer
reclaimPolicy: Delete
parameters:
csi.storage.k8s.io/fstype: ext4
storagePool: hdd
important

volumeBindingMode: WaitForFirstConsumer is required. Using Immediate will fail with "No preferred topology set" because the driver needs to know which node the pod will land on to select the correct pool.

A StorageClass without a storagePool parameter uses node.defaultPool.

Monitor Pool Capacity

Pool metrics are exposed on port 9100. Use these PromQL queries to track capacity:

# Remaining capacity per pool
rawfile_pool_remaining_capacity_bytes

# Alert when a pool has less than 10 GiB free
rawfile_pool_remaining_capacity_bytes < 10 * 1024^3

See Monitoring for the full metrics reference.

Support

If you encounter issues or have a question, file a Github issue, or talk to us on the #openebs channel on the Kubernetes Slack server.

See Also