2022-07-03

PV and PVC in Kubernetes

Introduction

Kubernetes orchestrates container workloads by managing their lifecycle inside Pods. Each Pod can be viewed as a virtual host, acting as an ephemeral entity. The volatile nature of Pods means they can disappear at any time, posing a significant problem for data persistence.

Although one can mount ConfigMaps or Secrets as ReadOnly Volumes inside Pods, this approach is not ideal for data that needs to persist, such as database files. In scenarios where a Pod disappears, so does its associated data, resulting in a potential loss of information.

The solution to this issue lies in storing data not at the Pod level, but on the Node itself using a feature called Persistent Volume (PV). This component plays a pivotal role in maintaining data even when Pods cease to exist.

Persistent Volume (PV)

A Persistent Volume (PV) is a piece of storage in a Kubernetes cluster that has been provisioned by an administrator. PVs are a resource in the cluster, just like nodes, that allow users to store data persistently beyond the lifecycle of individual Pods.

Creating a PV

To persistently store data, one can create a PV on the Node. This can be achieved using the kubectl apply -f command with a configuration file defining the properties of the PV. For example, the following YAML configuration file specifies a PV with 100M storage, a manual storage class, and a ReadWriteOnce access mode, residing at /mnt/pvc on the host:

persistent_volume.yaml
apiVersion: v1
kind: PersistentVolume
metadata:
  name: pv
spec:
  storageClassName: manual
  capacity:
    storage: 100M
  accessModes:
    - ReadWriteOnce
  hostPath:
    path: "/mnt/pvc"

You can apply this configuration using:

bash
$ kubectl apply -f persistent_volume.yaml

persistentvolume/pv created

Inspecting the PV

Once a PV is created, its details can be fetched using the kubectl describe pv command:

bash
$ kubectl describe pv pv

This command returns a description of the PV, including its storage capacity, access modes, reclaim policy, status, and any bound PVCs. The information obtained from this command can be crucial in understanding the PV's state and diagnosing any potential issues.

Persistent Volume Claim (PVC)

A Persistent Volume Claim (PVC) is a request for storage by a user. It is similar to a pod in that pods consume node resources and PVCs consume PV resources. In other words, PVCs allow a user to claim the storage of a PV within a Kubernetes cluster.

Creating a PVC

To use a PV, you need to create a PVC. A PVC specifies the storage class, access modes, and storage capacity it requires. The following YAML configuration file, for instance, defines a PVC that requests a manual storage class, ReadWriteOnce access mode, and 10M storage:

persistent_volume_claim.yaml
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: pvc
spec:
  storageClassName: manual
  accessModes:
    - ReadWriteOnce
  resources:
    requests:
      storage: 10M

You can create the PVC by applying this configuration using:

bash
$ kubectl apply -f persistent_volume_claim.yaml

persistentvolumeclaim/pvc created

Verifying the PVC

After the PVC is created, you can verify its details by using the kubectl get pvc command:

bash
$ kubectl get pvc

NAME   STATUS   VOLUME   CAPACITY   ACCESS MODES   STORAGECLASS   AGE
pvc    Bound    pv       100M       RWO            manual         11s

This command will return the PVC's name, status, volume it's bound to, its capacity, access modes, storage class, and its age.

Bound PV

If a PVC successfully binds to a PV, you can verify this by listing the PVs with the kubectl get pv command:

bash
$ kubectl get pv

NAME   CAPACITY   ACCESS MODES   RECLAIM POLICY   STATUS   CLAIM         STORAGECLASS   REASON   AGE
pv     100M       RWO            Retain           Bound    default/pvc   manual                  54s

This command will show all the PVs in the cluster, along with their details. If a PVC is bound to a PV, you will see the status as 'Bound' in the output.

Mounting PVC as a Volume in a Pod

Once a PVC is bound to a PV, it can be used as a volume in a Pod. This allows containers in the Pod to access the storage provisioned by the PV.

The PVC can be mounted to a Pod by specifying the PVC's name under the volumes section of the Pod configuration file. This file, typically in YAML format, describes the properties of the Pod, including the containers it should run and the volumes it should mount.

The following YAML shows how to mount a PVC in a Pod configuration:

pod_pvc.yaml
apiVersion: v1
kind: Pod
metadata:
  creationTimestamp: null
  labels:
    run: helloworld-pvc
  name: helloworld-pvc
spec:
  containers:
  - image: bhargavshah86/kube-test:v0.1
    name: helloworld-pvc
    ports:
    - containerPort: 8080
    resources: {}
    volumeMounts:
    - name: my-pv
      mountPath: /mnt/pvc
  volumes:
    - name: my-pv
      persistentVolumeClaim:
        claimName: pvc

This configuration specifies a Pod with a single container. The container mounts a volume at the path /mnt/pvc. The volume refers to the PVC created earlier.

You can create the Pod using the kubectl apply -f command with the Pod configuration file:

bash
$ kubectl apply -f pod_pvc.yaml

pod/helloworld-pvc created

Once the Pod is created, it will have access to the storage specified in the PVC, allowing it to read and write data persistently across Pod restarts and terminations.

File Operations in the Pod

With the PVC mounted as a volume, the Pod can now read and write files to this volume. You can interact with a running Pod and execute commands inside its containers using the kubectl exec command.

To create a new file in the volume, you can execute a shell inside the container and use regular file operation commands. For instance, to create a new file called from_pod.txt, you can execute:

bash
$ kubectl exec -it helloworld-pvc sh
bash
/usr/share/nginx/html # echo "from pod" > /mnt/pvc/from_pod.txt
/usr/share/nginx/html # cat /mnt/pvc/from_pod.txt

from pod

The echo command writes the string "from pod" to the file from_pod.txt at the volume's mount path. The cat command is then used to display the contents of the file, verifying that it was created successfully.

As the PVC is backed by a PV that resides on a Node, you should be able to see the file created in the Pod on the Node itself. To verify this, you can SSH into the Node and inspect the file:

bash
$ minikube ssh
bash
docker@minikube:~$ cat /mnt/pvc/from_pod.txt

from pod

This command should output "from pod", indicating that the file created in the Pod exists persistently on the Node. This confirms that the data written by the Pod will persist across Pod restarts and terminations, solving the issue of data persistence in Kubernetes.

Ryusei Kakujo

researchgatelinkedingithub

Focusing on data science for mobility

Bench Press 100kg!