PV and PVC in OpenSHift - unix1998/technical_notes GitHub Wiki

In Kubernetes and OpenShift, both PersistentVolume (PV) and PersistentVolumeClaim (PVC) are typically used together, and each serves a distinct purpose. Here's why you need both:

PersistentVolume (PV)

  • Purpose: A PersistentVolume is a cluster-wide resource that represents a piece of storage in the cluster. It could be a local disk, NFS share, or cloud storage (e.g., AWS EBS, GCE Persistent Disk).
  • Lifecycle: It exists independently of any specific pod and can be created by an administrator or dynamically provisioned based on storage classes.
  • Specification: Defines the storage capacity, access modes, and other parameters.

PersistentVolumeClaim (PVC)

  • Purpose: A PersistentVolumeClaim is a request for storage by a user. It claims a PersistentVolume and binds to it. PVCs are namespaced and used by pods to request storage.
  • Lifecycle: It is created by users to consume PVs, and its lifecycle is tied to the namespace and the pods that use it.
  • Specification: Defines the storage requirements (size, access modes) and the desired storage class.

Why Both Are Needed

  • Decoupling: PV abstracts the physical storage details, while PVC abstracts the storage consumption. This separation allows for more flexibility and better management of storage resources.
  • Dynamic Provisioning: In many Kubernetes environments, you might not manually create PVs. Instead, StorageClasses enable dynamic provisioning, where PVCs can automatically trigger the creation of PVs as needed.
  • Reusability: PVs can be reused by different PVCs over time, providing efficient storage management.

Example: Using Both PV and PVC

For clarity, here’s an example of both PV and PVC being defined and used.

persistent-volume.yaml

apiVersion: v1
kind: PersistentVolume
metadata:
  name: pv-postgresql
spec:
  capacity:
    storage: 10Gi
  accessModes:
    - ReadWriteOnce
  persistentVolumeReclaimPolicy: Retain
  hostPath:
    path: "/mnt/data/postgresql"

persistent-volume-claim.yaml

apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: pvc-postgresql
spec:
  accessModes:
    - ReadWriteOnce
  resources:
    requests:
      storage: 10Gi

statefulset.yaml

apiVersion: apps/v1
kind: StatefulSet
metadata:
  name: postgresql
spec:
  serviceName: "postgresql"
  replicas: 1
  selector:
    matchLabels:
      app: postgresql
  template:
    metadata:
      labels:
        app: postgresql
    spec:
      containers:
      - name: postgresql
        image: postgres:13
        ports:
        - containerPort: 5432
          name: postgres
        envFrom:
        - configMapRef:
            name: postgresql-config
        volumeMounts:
        - name: postgresql-storage
          mountPath: /var/lib/postgresql/data
  volumeClaimTemplates:
  - metadata:
      name: postgresql-storage
    spec:
      accessModes: [ "ReadWriteOnce" ]
      resources:
        requests:
          storage: 10Gi

Summary

  • PV: Defines and provisions the actual storage.
  • PVC: Requests storage resources as needed by applications.
  • Dynamic Provisioning: Often, dynamic provisioning with StorageClasses makes managing storage easier, as PVCs can automatically create PVs without needing to manually define them.

In conclusion, while Kubernetes supports dynamic provisioning where you might not explicitly define PVs (relying instead on PVCs and StorageClasses), both PV and PVC are essential components for managing persistent storage in a Kubernetes cluster, ensuring decoupling and flexible management of storage resources.