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

  1. What is a Persistent Volume?
  2. What is a Persistent Volume Claim?
  3. Why are Pods considered ephemeral?
  4. What is the difference between a PV and a PVC?
  5. What is a StorageClass?
  6. What is dynamic provisioning?
  7. What are the different PVC access modes?
  8. Why should databases always use Persistent Volumes?
  9. What happens when a Pod restarts with a mounted PVC?
  10. What are the best practices for persistent storage in OpenShift?