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:
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:
$ 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:
$ 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:
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:
$ 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:
$ 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:
$ 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:
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:
$ 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:
$ kubectl exec -it helloworld-pvc sh
/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:
$ minikube ssh
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.