Ku­ber­netes Per­sis­tent Volumes (PVs) play a crucial role in the efficient man­age­ment of data in Ku­ber­netes clusters. They abstract data and allow con­sis­tent storage over the life­cy­cles of pods.

What is a Ku­ber­netes Per­sis­tent Volume?

A Ku­ber­netes Per­sis­tent Volume (PV) is a fun­da­men­tal resource within the Ku­ber­netes or­ches­tra­tion, designed for efficient and scalable man­age­ment of data in container clusters. The purpose of a PV is to provide a stan­dard­ized and per­sis­tent storage area. A PV can be used by different pods, re­gard­less of which physical storage resources the cluster accesses. This creates a higher level of ab­strac­tion by sep­a­rat­ing the storage details from the ap­pli­ca­tion logic.

PVs come in static and dynamic forms. Static pro­vi­sion­ing means that storage resources are manually pre­de­fined, while dynamic pro­vi­sion­ing means that PVs are au­to­mat­i­cal­ly created when a pod has specific storage re­quire­ments. This flex­i­bil­i­ty ensures efficient man­age­ment of per­sis­tent data in Ku­ber­netes clusters, making ap­pli­ca­tions robust and scalable.

Tip

Managed Ku­ber­netes from IONOS au­to­mat­i­cal­ly sets up Ku­ber­netes clusters for you on high-per­for­mance virtual servers. Thanks to the flexible con­fig­u­ra­tion of the worker nodes, you can adapt resources precisely to your needs. Use SDKs and config man­age­ment tools for smooth in­te­gra­tion and optimized operation.

What’s the dif­fer­ence between volume und per­sis­tent volume?

There are two basic types of storage volumes in Ku­ber­netes: volumes and per­sis­tent volumes. A normal volume is bound to the lifetime of a single pod. It’s declared directly in the pod con­fig­u­ra­tion and is mainly used for temporary data storage during the execution of the as­so­ci­at­ed pod. When the pod is ter­mi­nat­ed, the normal volume is also released and all the data it contains is deleted.

In contrast, a Ku­ber­netes Per­sis­tent Volume has a longer lifetime and is in­de­pen­dent of a specific pod. It can be claimed and released by multiple pods in different life­cy­cles. Per­sis­tent volumes are declared sep­a­rate­ly from the pods and then bound to Per­sis­tent Volume Claims (PVCs). The binding between a PVC and a PV is done dy­nam­i­cal­ly or manually. Per­sis­tent volumes are ideal for data that needs to last beyond the lifetime of a single pod and provide a way to share and store data between different pods, even if pods are created or deleted.

What types of per­sis­tent volumes are there?

In Ku­ber­netes, there are different types of per­sis­tent volumes that represent different storage solutions and tech­nolo­gies. Here are some of the most common types of per­sis­tent volumes:

  • hostPath: The hostPath type binds a per­sis­tent volume to a path on the host node in the Ku­ber­netes cluster. This allows access to local storage resources of the host and is well suited to de­vel­op­ment and test en­vi­ron­ments. However, it should be used with caution in pro­duc­tion en­vi­ron­ments as the data is not repli­cat­ed between the nodes.
  • emptyDir: emptyDir creates a temporary and idle volume each time a pod is created. It’s suitable for temporary data or data exchange between con­tain­ers within the same pod. However, the volume is deleted when the pod is ter­mi­nat­ed.
  • GCEPersistentDisk, AWSElasticBlockStore, AzureDisk, AzureFile: These types bind a Ku­ber­netes Per­sis­tent Volume to external cloud storage solutions such as Google Compute Engine Per­sis­tent Disks, Amazon EBS Volumes, or Azure Disks and Azure File Shares. They provide a way to persist data across pods and even clusters and are well suited to ap­pli­ca­tions deployed in cloud en­vi­ron­ments.
  • nfs (Network File System): NFS-type PVs bind to a network share that is made available via the Network File System (NFS). This allows data to be shared between different pods and is useful when multiple pods need to access shared files.
  • iscsi (Internet Small Computer System Interface): ISCSI-based PVs bind to block storage devices that are available via the ISCSI protocol. It’s a way to utilize external block storage devices in Ku­ber­netes clusters and provides a flexible and scalable solution for per­sis­tent data.
  • local: The local type enables direct access to physical storage resources on the local node in the Ku­ber­netes cluster. This is par­tic­u­lar­ly useful for ap­pli­ca­tions that rely on fast local storage. However, you should exercise caution as local storage resources are not repli­cat­ed between the nodes and data may be lost if the node fails.
  • csi (Container Storage Interface): The CSI type allows external storage providers to be in­te­grat­ed via the Container Storage Interface. Container or­ches­tra­tion systems such as Ku­ber­netes can thus com­mu­ni­cate with various third-party storage solutions. This creates flex­i­bil­i­ty and allows the use of a wide range of storage systems that support the CSI.
  • cephfs: CephFS is a dis­trib­uted file system and per­sis­tent volumes of type CephFS are bound to this dis­trib­uted file system. This type of PV is used for ap­pli­ca­tions that require shared file access and are operated in a dis­trib­uted storage en­vi­ron­ment, as is the case with Ceph.
  • fc (Fibre Channel): FC-based per­sis­tent volumes are bound to Fibre Channel storage devices. This type allows you to access external Fibre Channel-based storage solutions. It’s common in en­vi­ron­ments where Fibre Channel networks are used to provide block-based storage.
  • rbd (RADOS Block Device): The RBD type binds to block-based storage devices in the Ceph cluster that act as RADOS Block Devices. This type allows you to access the block-based storage system of Ceph, which is par­tic­u­lar­ly ad­van­ta­geous in dis­trib­uted storage en­vi­ron­ments with high scal­a­bil­i­ty.

Ku­ber­netes Per­sis­tent Volume Access Modes

In Ku­ber­netes, Per­sis­tent Volume Access Modes determine how pods can access the per­sis­tent volumes bound to them. There are three main types of access modes:

  • ReadWriteOnce (RWO): This mode allows a single pod to mount the per­sis­tent volume in read and write mode si­mul­ta­ne­ous­ly. It’s useful for ap­pli­ca­tions that require exclusive write access control. A PV with this mode can only be mounted by one pod at a time.
  • ReadOnlyMany (ROX): ReadOnlyMany allows multiple pods to mount the per­sis­tent volume si­mul­ta­ne­ous­ly in read-only mode. This is useful for ap­pli­ca­tions that can share data in a common mode, but where write access is re­strict­ed. Multiple pods can access the data in parallel but only in read-only mode.
  • ReadWriteMany (RWX): With ReadWriteMany, multiple pods can mount the per­sis­tent volume si­mul­ta­ne­ous­ly in both read and write access mode. This mode is used in sit­u­a­tions where a shared database is required and where multiple pods can have write access to the data.

When defining the access mode, you should consider the type of data access your ap­pli­ca­tion requires and check that the selected mode supports the required access patterns.

Please note that not all storage classes and volume types support all three access modes. The support depends on the un­der­ly­ing storage in­fra­struc­ture and the specific per­sis­tent volume type. Therefore, it’s advisable to check the doc­u­men­ta­tion of the re­spec­tive storage class and per­sis­tent volume type to make sure that the access patterns you want are permitted.

The lifecycle of a per­sis­tent volume (PV)

The life­cy­cles of Ku­ber­netes Per­sis­tent Volumes can be divided into different phases that represent the process of pro­vi­sion­ing, using and releasing per­sis­tent storage in the cluster.

  1. Pro­vi­sion­ing : The lifecycle of a PV begins with creation or pro­vi­sion­ing. A cluster ad­min­is­tra­tor creates a per­sis­tent volume and con­fig­ures it either sta­t­i­cal­ly with fixed storage resources or dy­nam­i­cal­ly by using a storage class that enables dynamic pro­vi­sion­ing.
  2. Binding: A PV is bound to a PVC (Per­sis­tent Volume Claim) when a pod declares a storage re­quire­ment that matches the PV’s spec­i­fi­ca­tions. This step ensures that the PV meets the re­quire­ments of a specific pod.
  3. Usage by the pod: After the binding process is complete, the PV can be used by a pod. The pod can read or write to the mounted volume, depending on the access modes set during PV creation.
  4. Ex­pi­ra­tion of use: When a pod ends its service or is deleted, the as­so­ci­at­ed PV can be reused by another pod. The PV is retained until it is deleted manually or by a dynamic storage class.
  5. Release: A PV can be ex­plic­it­ly released by dis­con­nect­ing it from a PVC. This allows the PV to be re-bonded, possibly from another PVC or pod.
  6. Delete: Finally, you can also delete a PV if it’s no longer required. This can be done manually or au­to­mat­i­cal­ly if PV repli­ca­tion is set by the storage class.

How to create a Ku­ber­netes Per­sis­tent Volume

Creating a per­sis­tent volume in Ku­ber­netes is a multi-stage process that requires careful con­fig­u­ra­tion.

Step 1: Con­fig­ur­ing the per­sis­tent volume

The first step involves opening a text editor and creating a YAML file that contains the con­fig­u­ra­tion of the Ku­ber­netes Per­sis­tent Volumes. You could name this file pv.yaml, for instance. Below, we give you a simple example of a PV con­fig­u­ra­tion:

apiVersion: v1
kind: PersistentVolume
metadata:
    name: my-pv
spec:
    capacity:
        storage: 1Gi
    volumeMode: Filesystem
    accessModes:
        - ReadWriteOnce
    persistentVolumeReclaimPolicy: Retain
    storageClassName: manual
    hostPath:
        path: "/mnt/data"
yaml
  • apiVersion: Specifies the Ku­ber­netes API version. Here it’s v1.
  • kind: The type of the Ku­ber­netes object, in this case Per­sis­tentVol­ume.
  • metadata: Contains metadata for the per­sis­tent volume, for example the name of the volume. spec: Defines the spec­i­fi­ca­tion of the volume.
  • capacity: Specifies the storage capacity, in this example 1 GB.
  • volumeMode: The mode for the volume is specified here, either Filesystem or Block. In this example, we use Filesystem.
  • accessModes: Defines the access modes. Here ReadWriteOnce stands for exclusive read and write access.
  • persistentVolumeReclaimPolicy: Specifies how the volume should be handled when it’s no longer required. Retain means that the volume must be deleted manually.
  • storageClassName: Assigns a storage class to the per­sis­tent volume.
  • hostPath: Defines the path in the host file system that’s used as storage for the per­sis­tent volume.

Step 2: Applying the con­fig­u­ra­tion

Once you have described the PV con­fig­u­ra­tion file, you can activate it with Kubelet:

kubectl apply -f pv.yaml
shell

This command sends the con­fig­u­ra­tion file to the Ku­ber­netes cluster, which creates the resources it contains.

Step 3: Checking the con­fig­u­ra­tion

To make sure that the Ku­ber­netes Per­sis­tent Volume has been suc­cess­ful­ly created, you can use the following command:

kubectl get pv
shell

This lists all existing per­sis­tent volumes in the cluster.

NAME   CAPACITY  ACCESS MODES  RECLAIM POLICY  STATUS  CLAIM  STORAGECLASS  REASON  AGE
my-pv    1Gi          RWX          Retain     Available           manual             1h
shell

Step 4: Creating a Per­sis­tent Volume Claim (PVC)

Fill a YAML file that defines the con­fig­u­ra­tion of the Per­sis­tent Volume Claim:

apiVersion: v1
kind: PersistentVolumeClaim
metadata:
    name: my-pvc
spec:
    accessModes:
        - ReadWriteOnce
    resources:
        requests:
            storage: 1Gi
    storageClassName: manual
yaml

Apply the PVC con­fig­u­ra­tion file to the Ku­ber­netes cluster:

kubectl apply -f pvc.yaml
shell

To check if the Per­sis­tent Volume Claim has been suc­cess­ful­ly created, use the following command:

kubectl get pvc
shell

The output should look similar to this:

NAME      STATUS   VOLUME   CAPACITY   ACCESS MODES   STORAGECLASS   AGE
my-pvc     Bound    my-pv     1Gi           RWO          manual       1m
shell

Now we create the YAML manifest pvc-dynamic.yaml to demon­strate the dynamic pro­vi­sion­ing of a Per­sis­tent Volume Claim (PVC) in Ku­ber­netes. The manifest au­to­mat­i­cal­ly creates and claims a new Ku­ber­netes Per­sis­tent Volume with a size of 1 gigabyte, which is supported by the storage class standard.

apiVersion: v1
kind: PersistentVolumeClaim
metadata:
    name: pvc-dynamic
spec:
    accessModes:
        - ReadWriteOnce
    resources:
        requests:
            storage: 1Gi
    storageClassName: standard
yaml

Once the con­fig­u­ra­tions have been defined, we activate the manifest:

kubectl apply -f pvc-dynamic.yaml
shell

Step 5: Attaching PVCs to pods

To pair the PVC with the pod, you need to set up the con­fig­u­ra­tion for the pod that will use the per­sis­tent storage.

apiVersion: v1
kind: Pod
metadata:
    name: mypod
spec:
    volumes:
    - name: mypvc-volume
        persistentVolumeClaim:
            claimName: my-pvc
    containers:
    - name: mycontainer
        image: myimage
        volumeMounts:
        - mountPath: "/app/data"
            name: mypvc-volume
yaml

Apply the pod con­fig­u­ra­tion to the Ku­ber­netes cluster to create the pod:

kubectl apply -f pod.yaml
shell

If you’re just getting started with Ku­ber­netes, you’ll find every­thing you need to know about in­stalling and setting up a cluster in the Ku­ber­netes tutorial in our guide.

IONOS Cloud Managed Ku­ber­netes
Container workloads in expert hands

The ideal platform for demanding, highly scalable container ap­pli­ca­tions. Managed Ku­ber­netes works with many cloud-native solutions and includes 24/7 expert support.

Go to Main Menu