Kubernetes For Developers Part 5 – Volume Objects and Persistent Volumes

Kubernetes For Developers Part 5 – Volume Objects and Persistent Volumes

 

Image Credit: Pixabay, https://www.pexels.com/photo/black-and-white-blur-chrome-close-up-209666/

 

In previous posts of this series, we discussed in detail how Kubernetes enables enterprise-level scalability and how pods can heal automatically giving us almost 100% uptime. In this edition of our series, we will highlight an important component of the Kubernetes lifecycle, without which Kubernetes would not be such a powerful container orchestration platform.

We know that pods can exit at any point if the application running in the container dies. We also know that Kubernetes will take care of spinning up a new pod quickly, typically within seconds. Containers are ephemeral and without additional features, may lose previous state and data. This limits pods from being useful, especially for stateful applications. Very often there is a requirement to store data/state in pods deployed on a Kubernetes cluster.

Volumes to the rescue!

In this post, we will see how persistent volumes help to overcome the problems we just discussed. The persistent volume abstraction provided by Kubernetes has a prolonged lifetime, often lasting beyond the lifetime of a container and in some cases lasting beyond the lifetime of a pod. Fundamentally, volumes are block or file storage devices that are made accessible to containers as simple directories that applications can then easily access. Since Kubernetes is such a widely used platform, it supports a wide range of volume types.

Some of the most commonly used volume types are:

  • awsElasticBlockStore
  • azureDisk
  • gcePersistentDisk
  • persistentVolumeClaim
  • secret
  • emptyDir
  • downwardAPIconfigMap

 

Volumes sound like a great solution to our persistence related problems, but, how we do we use them with our pods. Let’s see some YAML:

apiVersion: v1
kind: Pod
metadata:
  name: volumes-demo
spec:
  containers:
  - name: test
    image: mysql
    volumeMounts:
    - name: volume
      mountPath: /etc/config/demo
  volumes:
  - name: volume-config
    configMap:
      name: test-config-map
      items:
      - key: logs
        path: /logs

 

The YAML file above creates a new pod. To start using volumes, we define the volume in the pod spec. Additionally, in volumeMounts under containers, we can allow containers to specify the path to mount the data from the volume.

In the list of volumes above, the cloud provided volumes like azureDisk, awsElasticBlockStore, and gcePersistentDisk are persistent volumes. Persistent volumes are different from general volumes because their life cycle is independent of the lifecycle of the pod,  whereas non-persistent volumes last only for the lifetime of a pod.

Persistent volumes are low-level objects, which are best used via other abstractions. There are mainly two types of provisioning:

  • Static – These types of volumes are created by the administrator.
  •  Dynamic – Created by the users and the containers need to file a Persistent Volume Claim (PVC).

Highly scalable applications prefer dynamic provisioning over static provisioning because dynamic provisioning allows volumes to be created on demand. There are good reasons why dynamic provisioning is preferred. Without it, the cluster administrators would have to manually make calls to their cloud providers to create storage volumes and in turn, create Persistent Volumes objects in Kubernetes. It is not recommended to create resources unless absolutely necessary. Dynamic provisioning helps us use this approach with volumes.

To optimize the use of your data storage, consider using dynamic provisioning for Kubernetes to automatically manage transitions of data between the pods.

Using Dynamic Provisioning

Before you can start using dynamic provisioning you will have to create one or more storage classes. Storage classes, in simple words, are profiles for volumes. When you want your resource to use a type of volume, you tell kubernetes to use a specific ‘Setting’ for that volume. Kubernetes is un-opinionated about what these classes represent. By settings, we mean configuring provisioner, parameters, and reclaimPolicy. There also might be cases where the PVCs don’t ask for these ‘Settings’ or StorageClasses. Kubernetes has a way around this too, by giving the administrators to have a ‘Default Setting’ or also known as a Default Storage Class in kubernetes. This is analogous to the default avatars that show up when you don’t have a profile picture on any of the social media platforms.

And a typical storage class YAML would look something like below

kind: StorageClass
apiVersion: storage.k8s.io/v1
metadata:
  name: dynamic-settings-demo
provisioner: kubernetes.io/aws-ebs
parameters:
  type: gp2
reclaimPolicy: Retain
mountOptions:
   - debug
     volumeBindingMode: Immediate

A typical PVC using one of the storage classes called ‘dynamic-settings-demo’ created by the administrator would look something like below

apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: demo-claim
spec:
  accessModes:
    - ReadWriteOnce
  storageClassName: dynamic-settings-demo
  resources:
    requests:
      storage: 10Gi

Once we have created a claim, we can use the claim when creating a pod. A sample YAML for creating a pod with a claim is as shown below 

kind: Pod
apiVersion: v1
metadata:
  name: server-pod
spec:
  containers:
    - name: backend-server
      image: nginx
      volumeMounts:
      - mountPath: "/var/www/html"
        name: volume-config
  volumes:
    - name: volume-config
      persistentVolumeClaim:
        claimName: demo-claim

It’s that simple. After creating these resources on Kubernetes, your app will automatically be able to store data independently of the lifetime of pods, containers, and nodes. Similar to other areas, Kubernetes provides many options for persistent storage to suit your application setup and business needs.

Conclusion

In this blog post, we learned about volumes, persistent volumes, and persistent volume claims. We saw the importance of data persistence for scalability of pods and in turn scalability of applications.

It is very important for developers using Kubernetes to leverage dynamic provisioning, not only as an effective way to manage and save data but also to reduce the hassle of manually configuring volumes, ]allowing Kubernetes to do its job.

At Nirmata, we support persistent volumes and also go one step further by automatically creating default storage classes for your cloud provider with a single click of a button.

If you haven’t checked our product yet, visit https://try.nirmata.io

 

Kubernetes Namespaces
Managing Kubernetes Workloads on EKS using Nirmata
No Comments

Sorry, the comment form is closed at this time.