How to create Kubernetes Persistent Volumes

Kubernetes Persistent Volumes (PVs) play a crucial role in the efficient management of data in Kubernetes clusters. They abstract data and allow consistent storage over the lifecycles of pods.

What is a Kubernetes Persistent Volume?

A Kubernetes Persistent Volume (PV) is a fundamental resource within the Kubernetes orchestration, designed for efficient and scalable management of data in container clusters. The purpose of a PV is to provide a standardised and persistent storage area. A PV can be used by different pods, regardless of which physical storage resources the cluster accesses. This creates a higher level of abstraction by separating the storage details from the application logic.

PVs come in static and dynamic forms. Static provisioning means that storage resources are manually predefined, while dynamic provisioning means that PVs are automatically created when a pod has specific storage requirements. This flexibility ensures efficient management of persistent data in Kubernetes clusters, making applications robust and scalable.

Tip

Managed Kubernetes from IONOS automatically sets up Kubernetes clusters for you on high-performance virtual servers. Thanks to the flexible configuration of the worker nodes, you can adapt resources precisely to your needs. Use SDKs and config management tools for smooth integration and optimised operation.

What’s the difference between volume und persistent volume?

There are two basic types of storage volumes in Kubernetes: volumes and persistent volumes. A normal volume is bound to the lifetime of a single pod. It’s declared directly in the pod configuration and is mainly used for temporary data storage during the execution of the associated pod. When the pod is terminated, the normal volume is also released and all the data it contains is deleted.

In contrast, a Kubernetes Persistent Volume has a longer lifetime and is independent of a specific pod. It can be claimed and released by multiple pods in different lifecycles. Persistent volumes are declared separately from the pods and then bound to Persistent Volume Claims (PVCs). The binding between a PVC and a PV is done dynamically or manually. Persistent 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 persistent volumes are there?

In Kubernetes, there are different types of persistent volumes that represent different storage solutions and technologies. Here are some of the most common types of persistent volumes:

  • hostPath: The hostPath type binds a persistent volume to a path on the host node in the Kubernetes cluster. This allows access to local storage resources of the host and is well suited to development and test environments. However, it should be used with caution in production environments as the data is not replicated 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 containers within the same pod. However, the volume is deleted when the pod is terminated.
  • GCEPersistentDisk, AWSElasticBlockStore, AzureDisk, AzureFile: These types bind a Kubernetes Persistent Volume to external cloud storage solutions such as Google Compute Engine Persistent 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 applications deployed in cloud environments.
  • 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 utilise external block storage devices in Kubernetes clusters and provides a flexible and scalable solution for persistent data.
  • local: The local type enables direct access to physical storage resources on the local node in the Kubernetes cluster. This is particularly useful for applications that rely on fast local storage. However, you should exercise caution as local storage resources are not replicated 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 integrated via the Container Storage Interface. Container orchestration systems such as Kubernetes can thus communicate with various third-party storage solutions. This creates flexibility and allows the use of a wide range of storage systems that support the CSI.
  • cephfs: CephFS is a distributed file system and persistent volumes of type CephFS are bound to this distributed file system. This type of PV is used for applications that require shared file access and are operated in a distributed storage environment, as is the case with Ceph.
  • fc (Fibre Channel): FC-based persistent volumes are bound to Fibre Channel storage devices. This type allows you to access external Fibre Channel-based storage solutions. It’s common in environments 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 particularly advantageous in distributed storage environments with high scalability.

Kubernetes Persistent Volume Access Modes

In Kubernetes, Persistent Volume Access Modes determine how pods can access the persistent volumes bound to them. There are three main types of access modes:

  • ReadWriteOnce (RWO): This mode allows a single pod to mount the persistent volume in read and write mode simultaneously. It’s useful for applications 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 persistent volume simultaneously in read-only mode. This is useful for applications that can share data in a common mode, but where write access is restricted. Multiple pods can access the data in parallel but only in read-only mode.
  • ReadWriteMany (RWX): With ReadWriteMany, multiple pods can mount the persistent volume simultaneously in both read and write access mode. This mode is used in situations 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 application 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 underlying storage infrastructure and the specific persistent volume type. Therefore, it’s advisable to check the documentation of the respective storage class and persistent volume type to make sure that the access patterns you want are permitted.

The lifecycle of a persistent volume (PV)

The lifecycles of Kubernetes Persistent Volumes can be divided into different phases that represent the process of provisioning, using and releasing persistent storage in the cluster.

  1. Provisioning : The lifecycle of a PV begins with creation or provisioning. A cluster administrator creates a persistent volume and configures it either statically with fixed storage resources or dynamically by using a storage class that enables dynamic provisioning.
  2. Binding: A PV is bound to a PVC (Persistent Volume Claim) when a pod declares a storage requirement that matches the PV’s specifications. This step ensures that the PV meets the requirements 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. Expiration of use: When a pod ends its service or is deleted, the associated 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 explicitly released by disconnecting 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 automatically if PV replication is set by the storage class.

How to create a Kubernetes Persistent Volume

Creating a persistent volume in Kubernetes is a multi-stage process that requires careful configuration.

Step 1: Configuring the persistent volume

The first step involves opening a text editor and creating a YAML file that contains the configuration of the Kubernetes Persistent Volumes. You could name this file pv.yaml, for instance. Below, we give you a simple example of a PV configuration:

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 Kubernetes API version. Here it’s v1.
  • kind: The type of the Kubernetes object, in this case PersistentVolume.
  • metadata: Contains metadata for the persistent volume, for example the name of the volume. spec: Defines the specification 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 persistent volume.
  • hostPath: Defines the path in the host file system that’s used as storage for the persistent volume.

Step 2: Applying the configuration

Once you have described the PV configuration file, you can activate it with Kubelet:

kubectl apply -f pv.yaml
shell

This command sends the configuration file to the Kubernetes cluster, which creates the resources it contains.

Step 3: Checking the configuration

To make sure that the Kubernetes Persistent Volume has been successfully created, you can use the following command:

kubectl get pv
shell

This lists all existing persistent 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 Persistent Volume Claim (PVC)

Fill a YAML file that defines the configuration of the Persistent Volume Claim:

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

Apply the PVC configuration file to the Kubernetes cluster:

kubectl apply -f pvc.yaml
shell

To check if the Persistent Volume Claim has been successfully 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 demonstrate the dynamic provisioning of a Persistent Volume Claim (PVC) in Kubernetes. The manifest automatically creates and claims a new Kubernetes Persistent 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 configurations 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 configuration for the pod that will use the persistent 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 configuration to the Kubernetes cluster to create the pod:

kubectl apply -f pod.yaml
shell

If you’re just getting started with Kubernetes, you’ll find everything you need to know about installing and setting up a cluster in the Kubernetes tutorial in our guide.

IONOS Cloud Managed Kubernetes
Container workloads in expert hands

The ideal platform for demanding, highly scalable container applications. Managed Kubernetes works with many cloud-native solutions and includes 24/7 expert support.

Was this article helpful?
Page top