Storage Volumes in Kubernetes

Introduction

In previous post, we learn the basics of how storage works in kubernetes. We learned that for statefull application, we need to persist data beyond container or pod life and how kubneretes have volume plugin mechanism to help us using existing storage solutions for our applications.

We then started with a very basic type of volume i.e. emptyDir which is an ephemeral type of storage and we saw that data is lost when a pod dies. However, this example helped us taking our first step in learning storage options.

Today we will take next step and work with persistence storage. Now, for our statefull application, we need a volume that refers to a persistent storage e.g. to an NFS server running remotely outside of the node, outside of the cluster. We can use an NFS server or storage option from a cloud provider. For the demo part, I will be using an AWS EBS volume, but the principals are same for other storage services as well.

Setting the Scene

I will be using the same application and kubernetes cluster which we setup in previous post and the source-code can be downloaded from this git repository (branch: k8storage).

Here is how the volume (emptyDir) is currently setup:

We will be replacing emptyDir ephemeral storage with a persistent storage (AWS EBS) which exists outside of our cluster.

Creating an AWS EBS volume

First thing we need to do is create an EBS volume before we can use it with a pod. Following command can be executed using AWS CLI:

aws ec2 create-volume --availability-zone=eu-central-1a --size=10 --volume-type=gp2

Also check that the zone matches the zone you brought up your cluster in. We are doing simple tests and for our purpose gp2 type and 10gb is ok for now. Please check what is suitable for your use cases.

here is the command output:

Here is the web console, showing our volume created:

Using an EBS Volume with Kubernetes

Lets update the deployment for postgres for volume part with information of AWS volume as shown below:

As you can see that change is very straight-forward, instead of emptyDir, we are using awsElasticBlockStore settings. Also, I added a subPath for the mount as shown above.

with these changes in place, lets deploy it to cluster and Test.

Testing the Storage

First delete the existing deployment for database pod:

kubectl delete -f .\accounting-db.deploymet.yml

next apply the deployment with volume changes:

kubectl apply -f .\accounting-db.deploymet.yml

With changes deployed, we can access the application and enter some data to it:

Now, lets delete the pod and then recreate it and see if our data is not lost in between:

as you can see that pod was deleted and then a new pod was created.

Now, if we refresh the web browser, we can see that our data from first pod is persisted and is not lost like the case with emptyDir:

So, this is better, but we are still far from end. One reason because in our current solution, volume information is hard-coded in Pod definition and this is not portable. If we change the storage, we have to change all the pods and redeploy those pods. In next posts, we will see how to overcome portability issues and some other storage options from kubernetes.

Summary

In this post, we learn how to provide persistent storage to statefull applications running inside a kubernetes cluster. We created and used AWS EBS Volume and saw that data is persisted even pod is deleted. You can use a different cloud provider and storage mechanism as per your requirements.

Source code can be downloaded from this git repository (branch: k8storage).

Let me know if you have some comments or questions. Till next time, Happy Coding.

1 thought on “Storage Volumes in Kubernetes”

Comments are closed.