OpenShift Persistent Volumes (PV) and Persistent Volume Claims (PVC)
Learn how Persistent Volumes and Persistent Volume Claims work in OpenShift. Understand persistent storage architecture, Storage Classes, dynamic provisioning, Spring Boot integration, and enterprise storage best practices.
Introduction
Containers are ephemeral by nature.
This means when a Pod is:
- Restarted
- Deleted
- Rescheduled
- Recreated
all the data stored inside the container filesystem is lost.
Imagine a Spring Boot application that uploads customer documents.
If the Pod restarts, every uploaded file disappears.
This is unacceptable for enterprise applications.
OpenShift solves this problem using:
- Persistent Volumes (PV)
- Persistent Volume Claims (PVC)
Persistent storage ensures application data survives Pod failures, deployments, upgrades, and scaling operations.
Learning Objectives
By the end of this article, you will understand:
- Why persistent storage is required
- What is a Persistent Volume (PV)?
- What is a Persistent Volume Claim (PVC)?
- Storage Classes
- Dynamic provisioning
- Spring Boot file uploads
- Database persistence
- Enterprise storage architecture
- Best practices
Ephemeral Container Storage
Container filesystem:
flowchart LR
Pod[Spring Boot Pod]
--> LocalStorage[Container File System]
LocalStorage --> Files[Uploaded Files]
Pod -. Restart .-> Lost[❌ Data Lost]
When the Pod restarts, data disappears.
Persistent Storage
flowchart LR
Pod[Spring Boot Pod]
--> PVC[Persistent Volume Claim]
--> PV[Persistent Volume]
--> Storage[(Cloud Storage)]
Even if the Pod restarts, data remains safe.
What is a Persistent Volume (PV)?
A Persistent Volume is a storage resource available in the OpenShift cluster.
It can represent storage from:
- AWS EBS
- Azure Disk
- Google Persistent Disk
- NFS
- NetApp
- Ceph
- SAN
- Local Storage
Think of it as a virtual hard disk managed by Kubernetes/OpenShift.
What is a Persistent Volume Claim (PVC)?
A Persistent Volume Claim is a request for storage made by an application.
Instead of selecting a physical disk, the application simply requests:
- Size
- Access Mode
- Storage Class
OpenShift automatically binds the request to an available Persistent Volume.
PV/PVC Architecture
flowchart TD
SpringBoot[Spring Boot Pod]
PVC[Persistent Volume Claim]
PV[Persistent Volume]
Storage[(Cloud Storage)]
SpringBoot --> PVC
PVC --> PV
PV --> Storage
Applications never interact directly with the Persistent Volume.
Storage Workflow
sequenceDiagram
participant Pod
participant PVC
participant PV
participant Storage
Pod->>PVC: Request Storage
PVC->>PV: Bind Volume
PV->>Storage: Allocate Disk
Storage-->>Pod: Persistent Storage Ready
Static vs Dynamic Provisioning
| Static Provisioning | Dynamic Provisioning |
|---|---|
| Admin creates PV manually | OpenShift creates PV automatically |
| Manual management | Automatic |
| Suitable for legacy storage | Recommended for cloud environments |
Most cloud platforms use Dynamic Provisioning.
Storage Classes
A StorageClass defines how storage should be provisioned.
Examples:
- gp3 (AWS)
- managed-premium (Azure)
- standard-rwo (OpenShift)
- fast-ssd
- premium-storage
Storage Architecture
flowchart LR
Application
--> PVC
PVC
--> StorageClass
StorageClass
--> PV
PV
--> CloudStorage[(AWS EBS / Azure Disk)]
Persistent Volume Example
apiVersion: v1
kind: PersistentVolume
metadata:
name: payment-pv
spec:
capacity:
storage: 10Gi
accessModes:
- ReadWriteOnce
hostPath:
path: /data/payment
Create:
oc apply -f persistent-volume.yaml
Persistent Volume Claim Example
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: payment-pvc
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 5Gi
Apply:
oc apply -f pvc.yaml
Verify PVC
oc get pvc
Example:
NAME
payment-pvc
STATUS
Bound
Verify PV
oc get pv
Example:
payment-pv
STATUS
Bound
Mount PVC into Spring Boot
Deployment YAML
spec:
containers:
- name: payment-api
volumeMounts:
- mountPath: /data/uploads
name: upload-storage
volumes:
- name: upload-storage
persistentVolumeClaim:
claimName: payment-pvc
Storage Mount Flow
flowchart LR
PVC["PersistentVolumeClaim"]
PV["PersistentVolume"]
POD["Spring Boot Pod"]
CONTAINER["Spring Boot Container"]
STORAGE["/data/uploads"]
PVC --> PV
PV --> POD
POD --> CONTAINER
CONTAINER --> STORAGE
Spring Boot File Upload
@PostMapping("/upload")
public String upload(
@RequestParam MultipartFile file)
throws Exception {
Path path = Paths.get(
"/data/uploads/" + file.getOriginalFilename());
Files.copy(file.getInputStream(), path);
return "Uploaded Successfully";
}
Files are now stored on persistent storage.
Pod Restart Scenario
flowchart LR
Pod1[Pod Running]
--> UploadFiles
UploadFiles
--> Restart
Restart
--> Pod2[New Pod]
Pod2
--> ExistingFiles[Files Still Available]
The files survive Pod recreation.
Database Storage
Databases must always use Persistent Volumes.
flowchart TD
PostgreSQL
--> PVC
PVC
--> PV
PV
--> SSD[(Persistent Disk)]
Without persistent storage, database data would be lost.
Banking Example
flowchart TD
CUSTOMER["Customer"]
API["Payment API"]
DOCS["Uploaded Documents"]
PVC["PersistentVolumeClaim"]
STORAGE[("AWS EBS")]
CUSTOMER --> API
API --> DOCS
DOCS --> PVC
PVC --> STORAGE
Customer KYC documents remain available after deployments.
Healthcare Example
flowchart LR
PORTAL["Hospital Portal"]
IMAGES["Medical Images"]
PVC["PersistentVolumeClaim"]
DISK[("Azure Managed Disk")]
PORTAL --> IMAGES
IMAGES --> PVC
PVC --> DISK
Medical records remain permanently available.
Access Modes
| Mode | Description |
|---|---|
| ReadWriteOnce (RWO) | Mounted by one node |
| ReadOnlyMany (ROX) | Read by many nodes |
| ReadWriteMany (RWX) | Read and Write by many nodes |
Most Spring Boot applications use ReadWriteOnce.
Reclaim Policies
| Policy | Behavior |
|---|---|
| Delete | Remove storage after PVC deletion |
| Retain | Preserve storage |
| Recycle | Deprecated |
Production environments typically use Retain for critical data.
Dynamic Provisioning
flowchart LR
PVC["PersistentVolumeClaim"]
SC["StorageClass"]
PROVISIONER["CSI Provisioner"]
PV["PersistentVolume"]
EBS["AWS EBS Volume"]
PVC --> SC
SC --> PROVISIONER
PROVISIONER --> PV
PV --> EBS
No administrator intervention required.
Resize PVC
Increase storage:
resources:
requests:
storage: 20Gi
Apply:
oc apply -f pvc.yaml
Many Storage Classes support online expansion.
Useful Commands
Create PVC
oc apply -f pvc.yaml
List PVCs
oc get pvc
Describe PVC
oc describe pvc payment-pvc
List PVs
oc get pv
Delete PVC
oc delete pvc payment-pvc
Enterprise Architecture
Enterprise Architecture
flowchart TD
USERS["Users"]
ROUTE["Route"]
SERVICE["Service"]
PODS["Spring Boot Pods"]
PVC["Application PVC"]
SC["StorageClass"]
CLOUD[("AWS EBS / Azure Disk")]
POSTGRES["PostgreSQL"]
DBPVC["Database PVC"]
SSD[("Persistent Database Storage")]
USERS --> ROUTE
ROUTE --> SERVICE
SERVICE --> PODS
PODS --> PVC
PVC --> SC
SC --> CLOUD
PODS --> POSTGRES
POSTGRES --> DBPVC
DBPVC --> SSD
Common Problems
PVC Pending
Check:
oc get pvc
Possible causes:
- No StorageClass
- No available PV
- Insufficient storage
Pod Cannot Mount Volume
Verify:
oc describe pod payment-api
Permission Denied
Ensure:
- Correct Security Context
- Proper file permissions
- RWX/RWO compatibility
Storage Full
Check:
df -h
Increase PVC size if supported.
Best Practices
- Always use PVCs for databases.
- Never store production data inside container filesystems.
- Use Storage Classes for dynamic provisioning.
- Separate application storage from database storage.
- Enable regular backups.
- Monitor storage usage.
- Choose appropriate access modes.
- Use Retain policy for production databases.
Common Mistakes
❌ Saving uploaded files inside the container.
❌ Running PostgreSQL without a PVC.
❌ Deleting PVCs accidentally.
❌ Using local storage for production workloads.
❌ Ignoring storage capacity monitoring.
Advantages
- Persistent storage
- Data survives Pod restarts
- Dynamic provisioning
- Cloud-native storage
- High availability
- Better scalability
- Enterprise reliability
- Simplified storage management
Summary
Persistent Volumes and Persistent Volume Claims provide reliable storage for cloud-native applications.
Key takeaways:
- Containers are ephemeral, but Persistent Volumes are not.
- Applications request storage using Persistent Volume Claims.
- Storage Classes automate volume provisioning.
- Spring Boot applications use PVCs for uploads, reports, and persistent data.
- Databases should always use persistent storage.
- PVs and PVCs are essential for production-grade OpenShift deployments.
Interview Questions
- What is a Persistent Volume?
- What is a Persistent Volume Claim?
- Why are Pods considered ephemeral?
- What is the difference between a PV and a PVC?
- What is a StorageClass?
- What is dynamic provisioning?
- What are the different PVC access modes?
- Why should databases always use Persistent Volumes?
- What happens when a Pod restarts with a mounted PVC?
- What are the best practices for persistent storage in OpenShift?