Module 4 - Introduction to Persistent Volumes

In this lab, we will create PersistentVolumes, and provide them to Pods via PersistentVolumeClaims. We'll learn the basics of how to manage persistent storage, and how to supply this storage to running Pods.

In general, our microservices are stateless, so they won't need any persistent storage. However, microservices are almost never truly "stateless", and this can be important to understand why that is. For instance, you might be running a Database in your Kubernetes cluster, and want to provide it Kubernetes-managed persistent storage.

Steps

Module 4 - Introduction to Persistent Volumes

Step1 of 4

Local Volumes

To start off, let's create a local emptyDir volume for a Pod. An emptyDir volume has the same lifecycle as the Pod. If the container(s) in the Pod restart or ccrash, the volume will live on and persist data. However, if the Pod is removed, then the volume will be removed as well.

In this Manifest file, we create a Pod and provide a container specification to run nginx. In this scenario, we are creating a local volume for nginx. It will be mounted inside of the nginx container at /data/nginx.

On the host system, Kubernetes will provide an empty directory for storage.

Next, let's launch this Pod, and store some data:

kubectl create -f ./resources/nginx-local.yaml

We can see that the Pod was started:

kubectl get pods --watch

Once it has successfully started, let's go into the nginx container and drop a file.

kubectl exec -it nginx -- touch /data/nginx/test.txt

Now, let's force the nginx container in the Pod to restart.
At this point, the Kubelet will destroy that container, and start a new one.

pkill nginx & kubectl get pods --watch

Now, we can open up another bash session into the container, and we'll find that our file is still there:

kubectl exec nginx -- ls /data/nginx/

Creating a PersistentVolume

PersistentVolumes abstract away the low-level details of a storage device, and provide a high-level API to provide such storage to Pods.

PersistentVolumes are storage inside of your cluster that has been provisioned by your administrator. Their lifecycle is external to your Pods or other objects.

There are many different types of PersistentVolumes that can be used with Kubernetes. As an example, you can use a local filesystem, NFS, and there are plugins for cloud vendor storage solutions like Elastic Block Storage.

This describes a single PersistentVolume. It is mounted to /mnt/data on a node. It is of type Filesystem, with 3 GB of storage.

Note: hostPath are only appropriate for testing in single node environments.

We can create this PersistentVolume:

kubectl create -f ./resources/pv-local.yaml

We can then view it with:

kubectl get pv

We can get even more information with:

kubectl describe pv local-pv -o yaml

Creating a PersistentVolumeClaim

Now that we have a PersistentVolume, let's make a PersistentVolumeClaim to provide storage to a Pod. PersistentVolumeClaims enable you to request a certain amount of storage from a PersistentVolume, and reserve it for your Pod.

This PersistentVolumeClaim is requesting 10 GB of storage from a local Filesystem PersistentVolume. When a Pod uses this Claim, Kubernetes will attempt to satisfy the claim by enumerating all PersistentVolumes, and matching the requirements in this Claim to what is present in the cluster.

If we were to match this Claim to PersistentVolume, it would succeed, because we have a PersistentVolume of type Filesystem with 100 GB of storage.

Let's create the PersistentVolumeClaim:

kubectl create -f ./resources/pv-claim.yaml

and wait until the resource is available:

kubectl get pvc --watch

We can also use label selectors to aid in matching Claims with PersistentVolumes.

This Claim is identical to the previous one, but it will only be matched with PersistentVolumes that have the label env: dev. You can use this to have more control over which Claims bind to a particular PersistentVolume.

Adding Storage to Pods

Now that we have PersistentVolumes and a PersistentVolumeClaim, we can provide the Claim to a Pod, and Kubernetes will provision storage.

This is very similar to the first Pod that we initially created with local storage. Now, we have basically changed what provides the Storage with the addition of those bottom two lines. To deploy our pod, execute the following:

kubectl create -f ./resources/nginx-persistent.yaml

We can see that the Pod was created, and that the Claim was fulfilled:

Debugging Scenarios

Help

Katacoda offerings an Interactive Learning Environment for Developers. This course uses a command line and a pre-configured sandboxed environment for you to use. Below are useful commands when working with the environment.

cd <directory>

Change directory

ls

List directory

echo 'contents' > <file>

Write contents to a file

cat <file>

Output contents of file

Vim

In the case of certain exercises you will be required to edit files or text. The best approach is with Vim. Vim has two different modes, one for entering commands (Command Mode) and the other for entering text (Insert Mode). You need to switch between these two modes based on what you want to do. The basic commands are: