Persistent volumes in practice
A PersistentVolumeClaim (PVC) is how your workload requests storage from the cluster. You declare the size and storage class you need, commit the manifest to your repo, and ArgoCD syncs it — the Cinder CSI provisioner creates the underlying volume automatically.
Requesting a PVC
Section titled “Requesting a PVC”A single-writer volume uses ReadWriteOnce against the default class:
apiVersion: v1kind: PersistentVolumeClaimmetadata: name: my-data namespace: <your-tenant>-prodspec: accessModes: - ReadWriteOnce storageClassName: csi-cinder-sc-delete resources: requests: storage: 10GiBoth Cinder storage classes are block volumes and support ReadWriteOnce only. A PVC bound to csi-cinder-sc-delete (the default) is destroyed when the claim is deleted; use csi-cinder-sc-retain if you need the underlying volume to survive accidental PVC deletion. See Storage classes for the comparison.
Replace <your-tenant> with your actual tenant name. The namespace must start with your tenant prefix — see Namespace prefix for the enforcement rule.
The storageClassName field
Section titled “The storageClassName field”storageClassName selects which Cinder storage class provisions the volume. Kestrel allows exactly two:
csi-cinder-sc-delete— block storage,ReadWriteOnce, reclaim policyDelete. This is the cluster default; omittingstorageClassNameselects it.csi-cinder-sc-retain— block storage,ReadWriteOnce, reclaim policyRetain.
See Storage classes for the full comparison, including reclaim policy and backup behaviour.
These are the only two classes the cluster accepts. If you name any other storageClassName, the PVC is rejected at admission and stays Pending — it never binds.
Shared (RWX) volumes: static NFS
Section titled “Shared (RWX) volumes: static NFS”Neither Cinder class supports ReadWriteMany, so a shared, multi-writer volume cannot be requested through a storage class. When a tenant needs RWX storage, RCS provisions a per-tenant NFS export and binds it in as a static PersistentVolume. Open a ticket with RCS to request one.
Once RCS has created the PV for your tenant, claim it with a PVC that has an empty storageClassName (so the dynamic Cinder provisioner is bypassed) and matches the PV’s access mode and capacity. A real tenant export looks like this — an NFS-backed PV created by RCS on server rsfshare.uvic.ca:
apiVersion: v1kind: PersistentVolumemetadata: name: my-nfs-pvspec: capacity: storage: 10Ti accessModes: - ReadWriteMany storageClassName: "" nfs: server: rsfshare.uvic.ca path: /mlpYou then bind it from your namespace with a matching PVC:
apiVersion: v1kind: PersistentVolumeClaimmetadata: name: shared-uploads namespace: <your-tenant>-prodspec: accessModes: - ReadWriteMany storageClassName: "" volumeName: my-nfs-pv resources: requests: storage: 10TiThe PV is cluster-scoped and created by RCS; the PVC lives in your namespace and binds to it by volumeName. Multiple Pods across nodes can mount an RWX NFS volume concurrently.
Sizing guidance
Section titled “Sizing guidance”Request what you need, not what you think the ceiling should be. The requested size counts against your tenant’s storage quota immediately, regardless of how much your workload actually writes.
- Start small, grow later. Increasing a volume’s size means editing
spec.resources.requests.storagein the PVC manifest. Whether expansion can be applied to an existing PVC without recreating it depends on the storage class’sallowVolumeExpansionsetting — confirm with RCS before relying on in-place growth for a live workload. Shrinking is never supported. - Watch for quota exhaustion. The total requested storage across all PVCs in all namespaces of your tenant counts against one shared pool. If you exceed your quota, new PVCs stay
Pendingand existing workloads are unaffected.
Quota interaction
Section titled “Quota interaction”Storage quota is part of your tenant’s ResourcePool, shared across all namespaces in the tenant. The quota tracks the sum of spec.resources.requests.storage across every PVC — actual bytes on disk do not matter, only what you requested.
When quota is exhausted:
- New PVCs stay
Pendingwith an event likeexceeded quota. - Existing PVCs and their Pods continue to run — quota enforcement does not evict running workloads.
- Resizing an existing PVC larger also fails if the new size would exceed quota.
To free quota, delete PVCs you no longer need. See Resource pools and quotas for the tier numbers and the accounting model.
Mounting a PVC in a Pod
Section titled “Mounting a PVC in a Pod”Reference the PVC in your Pod spec’s volumes and volumeMounts:
spec: containers: - name: app image: your-image:latest volumeMounts: - name: data mountPath: /data volumes: - name: data persistentVolumeClaim: claimName: my-dataThe Pod and PVC must be in the same namespace. Both Cinder classes are ReadWriteOnce, so the volume can be mounted by one node at a time — schedule the consuming Pods accordingly. If the PVC binds an RCS-provisioned NFS PV (RWX), multiple Pods can mount it concurrently.
Troubleshooting
Section titled “Troubleshooting”| Symptom | Likely cause |
|---|---|
PVC stays Pending | Storage quota exceeded, or storageClassName names a class other than csi-cinder-sc-delete / csi-cinder-sc-retain (rejected at admission) |
Pod stays Pending with volume error | PVC is RWO and already mounted by another Pod on a different node |
Permission denied writing to mount | Pod security context does not match the volume’s filesystem permissions — check fsGroup in your Pod spec |
| Data missing after Pod restart | You mounted an emptyDir or wrote to the container filesystem instead of the PVC path — ephemeral storage is lost on restart |