Appearance
Storage
To keep files when a pod restarts or moves to another node, request storage with a Kubernetes PersistentVolumeClaim (PVC). Mount that storage in the container at the path where your application saves its files.
Set spec.storageClassName to choose the type of storage and spec.resources.requests.storage to choose how much space you need.
Supported storage profiles
Choose block storage for use on one node, or shared storage for access from pods on different nodes:
| Profile | Storage class | Access mode | Use case |
|---|---|---|---|
| Block storage | storage-standard | ReadWriteOnce | Read-write storage for one node |
| Shared storage | storage-shared-standard | ReadWriteMany | Read-write storage across nodes |
A node is a machine that runs your pods. Block storage can be mounted for reading and writing on one node at a time. Choose shared storage when pods on multiple nodes need to read and write the same files.
PVC manifest fields
PVC manifests use these fields.
| Field | Required | Supported value |
|---|---|---|
spec.storageClassName | Yes | storage-standard or storage-shared-standard |
spec.resources.requests.storage | Yes | 8Gi, 16Gi, 32Gi, 64Gi, 128Gi, 256Gi, 512Gi, 1Ti, 2Ti, 4Ti, or 8Ti |
spec.accessModes | No | Omit, or set the access mode for the selected storage class |
spec.volumeMode | No | Filesystem |
If you omit spec.accessModes, RemoteGPU sets it from spec.storageClassName. If you set it explicitly, use ReadWriteOnce with storage-standard and ReadWriteMany with storage-shared-standard.
Namespace storage quota
Each namespace can have up to 64 PVCs, with a combined requested size of up to 32Ti. Kubernetes rejects a new PVC if it would exceed either limit.
For StatefulSets, each volumeClaimTemplates entry creates one PVC for each replica. For example, one claim template and three replicas creates three PVCs.
Create a PVC
Choose the example for your storage type and save it as a YAML file. Use a storage class and size from the tables above.
Block storage PVC
This example requests 128 GiB of block storage:
yaml
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: workspace
spec:
storageClassName: storage-standard
resources:
requests:
storage: 128GiSave the YAML as pvc.yaml and apply it:
bash
kubectl --kubeconfig ./kubeconfig-team-ml.yaml apply -f pvc.yaml
kubectl --kubeconfig ./kubeconfig-team-ml.yaml get pvc workspaceThe second command shows the PVC's status and capacity. Bound means it has been assigned storage.
Shared storage PVC
This example requests 128 GiB of storage that pods on different nodes can share:
yaml
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: shared-workspace
spec:
storageClassName: storage-shared-standard
resources:
requests:
storage: 128GiSave the YAML as shared-pvc.yaml and apply it:
bash
kubectl --kubeconfig ./kubeconfig-team-ml.yaml apply -f shared-pvc.yaml
kubectl --kubeconfig ./kubeconfig-team-ml.yaml get pvc shared-workspaceCheck the second command's output for the PVC's status and capacity.
Attach storage to a deployment
This Deployment makes the workspace PVC available at /workspace inside the container. Files saved there use the PVC's storage. You can use the same volume and mount settings in StatefulSet, Job, and CronJob pod templates.
yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: persistent-demo
spec:
replicas: 1
selector:
matchLabels:
app: persistent-demo
template:
metadata:
labels:
app: persistent-demo
remotegpu.ai/runtime-sku: cpu-shared-8g
spec:
containers:
- name: app
image: nginx:1.27-alpine
volumeMounts:
- name: workspace
mountPath: /workspace
volumes:
- name: workspace
persistentVolumeClaim:
claimName: workspaceSave the YAML as deployment.yaml and apply it with your namespace kubeconfig:
bash
kubectl --kubeconfig ./kubeconfig-team-ml.yaml apply -f deployment.yamlExpand a PVC
To expand a PVC, increase spec.resources.requests.storage to a larger supported size:
yaml
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: workspace
spec:
storageClassName: storage-standard
resources:
requests:
storage: 256GiApply the manifest again:
bash
kubectl --kubeconfig ./kubeconfig-team-ml.yaml apply -f pvc.yamlYou can increase a PVC's size, but you cannot shrink it. If you need a smaller volume, create a new PVC and copy your files to it.
Keep or delete your data
Deleting a Deployment, StatefulSet, Job, or CronJob keeps its PVCs and their files. The same applies when you scale an application to 0.
You continue paying for PVC storage while the PVC exists. To stop those storage charges, delete the PVC after backing up any files you need.
Troubleshooting
| Symptom | What to check |
|---|---|
| PVC creation is rejected | Check the storage class, requested size, and, if set, access mode. |
| PVC quota is exceeded | Delete PVCs whose data you no longer need, or request less storage when creating new PVCs. Reducing replicas does not remove existing PVCs. |
| PVC stays pending | Check the PVC events with kubectl describe pvc; confirm the requested size is one of the supported sizes. |
| Workload does not see the mounted data | Confirm the workload references the correct claimName and the volumeMounts path matches the container path you expect. |
| Expansion does not apply | Increase the request to a larger supported size; shrinking an existing PVC is not supported. |
| Data disappeared after cleanup | Confirm whether the PVC was deleted; delete a PVC only when the stored data is no longer needed. |
If PVC creation is rejected because of spec.accessModes, omit the field or set the access mode for the selected storage class.
Read next
- Read Deployments to mount a PVC in an application.
- Read Services to expose a deployment inside the cluster.