To solve the problem of ephemeral container storage, Kubernetes provides an abstraction that separates the management of storage infrastructure from its consumption by applications. This is accomplished through two distinct but related API objects: PersistentVolumes and PersistentVolumeClaims. This division of responsibility allows cluster administrators to manage the storage resources and developers to request those resources without needing to know the implementation details.
A PersistentVolume (PV) is a piece of storage in the cluster that has been provisioned by an administrator. It is a resource in the cluster, just like a node is a cluster resource. PVs are volume plugins like Volumes, but have a lifecycle independent of any individual Pod that uses the PV. This API object captures the details of the storage implementation, whether it is an NFS share, an iSCSI volume, or a cloud-provider-specific storage system like AWS EBS or GCE Persistent Disk.
An administrator creates a PV to represent a real piece of backing storage. When defining a PersistentVolume, you specify its characteristics, such as capacity, access modes, and reclaim policy.
capacity: The amount of storage the volume contains, for example, 10Gi.accessModes: Defines how the volume can be mounted. This is an important property that must be supported by the underlying storage provider.
ReadWriteOnce (RWO): The volume can be mounted as read-write by a single node.ReadOnlyMany (ROX): The volume can be mounted as read-only by many nodes.ReadWriteMany (RWX): The volume can be mounted as read-write by many nodes.persistentVolumeReclaimPolicy: What happens to the PV after the claim it was bound to is deleted.
Retain: The volume is not automatically cleaned up. The data remains, and the volume must be manually reclaimed by an administrator. This is the safest, and often default, policy.Delete: The volume and the associated storage asset in the external infrastructure are deleted.Recycle: (Deprecated) Performs a basic scrub on the volume, making it available again for a new claim.Here is an example of a PersistentVolume manifest that provisions a 5Gi volume using a local directory on a worker node. This hostPath type is suitable for single-node development clusters like Minikube.
# pv-definition.yaml
apiVersion: v1
kind: PersistentVolume
metadata:
name: task-pv-volume
labels:
type: local
spec:
storageClassName: manual
capacity:
storage: 5Gi
accessModes:
- ReadWriteOnce
hostPath:
path: "/mnt/data"
Once created, a PV exists in the cluster and is in the Available state, waiting to be claimed by a PersistentVolumeClaim.
A PersistentVolumeClaim (PVC) is a request for storage by a developer or user. If a PV is the supply of storage, a PVC is the demand. It is similar to a Pod. Pods consume node resources like CPU and memory; PVCs consume PV resources.
A developer creates a PVC to specify the amount of storage and the access modes they require for their application, without any knowledge of the underlying storage infrastructure.
Here is a manifest for a PersistentVolumeClaim that would request storage compatible with the PV we defined above.
# pvc-definition.yaml
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: task-pvc-claim
spec:
storageClassName: manual
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 3Gi
When this PVC is created, the Kubernetes control plane looks for an available PV that can satisfy the claim's requirements. In this case, our 5Gi PV satisfies the 3Gi request and also matches the ReadWriteOnce access mode. If a match is found, the control plane binds the PV to the PVC. The PV's status then changes from Available to Bound.
This diagram illustrates the relationship between Kubernetes storage objects. A Pod references a
PersistentVolumeClaimto request storage. The PVC binds to a suitablePersistentVolume, which in turn represents a physical storage resource managed by the infrastructure.
Once a claim is bound to a volume, it is bound exclusively. The binding is a one-to-one mapping between the PersistentVolume and the PersistentVolumeClaim. This binding ensures that no other PVC can claim the same PV.
Manually creating PersistentVolumes works for small-scale or specialized setups, but it doesn't scale well. In most production environments, especially in the cloud, storage is provisioned dynamically. This is handled in Kubernetes by an object called a StorageClass.
A StorageClass provides a way for administrators to describe the "classes" of storage they offer. Different classes might map to quality-of-service levels, backup policies, or arbitrary policies determined by the cluster administrator.
When a PVC is created, it can specify a storageClassName. If it does, the StorageClass's configured provisioner will automatically create a matching PV and bind it to the PVC.
For example, a cloud provider might offer a StorageClass named gp2 for general-purpose SSD storage and another named st1 for throughput-optimized HDD storage. A developer can then simply request the type of storage they need:
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: my-database-pvc
spec:
storageClassName: gp2 # Request a specific class of storage
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 100Gi
Upon creation of this PVC, the cloud provider's storage provisioner would automatically create a 100Gi gp2 volume, create a corresponding PV object for it in Kubernetes, and bind it to the my-database-pvc claim.
The PV and PVC mechanism provides a powerful way to manage storage resources. Administrators can manage the underlying storage fleet, and developers can consume storage with simple requests. With this understanding of how to claim persistent storage, the next step is to learn how to mount these claims into your Pods to make the storage available to your applications.
Was this section helpful?
© 2026 ApX Machine LearningEngineered with