Get to Grips with Kubernetes Volumes: A Practical Tutorial
Data persistence is a critical aspect of any containerized application, and Kubernetes provides a robust solution for managing storage volumes. In this article, we’ll explore the basics of Kubernetes volumes, the different types of volumes you can use, and provide a step-by-step hands-on session to help you understand how to use volumes in your own cluster. Whether you’re just starting with Kubernetes or looking to expand your knowledge, this article is a must-read for anyone looking to become a Kubernetes volume expert.
Before we begin, it is important to note that there are some concepts that you should be familiar with in order to get the most out of this course. You should be conversant with the following topics:
1. What is Kubernetes?
2. How do you establish your own Pod?
3. Setting up your k8s cluster (locally or using a cloud provider).
If you have checked the above boxes, you can continue with the course; otherwise, you can visit Here to learn the fundamentals before taking this course.
What are Kubernetes Volumes?
Volumes in Kubernetes are a way to persist data in your containers. They are like a storage area that your containers can use to save data, even if the containers themselves are deleted or recreated.
Think of it like a USB drive that you can plug into your computer. The data on the USB drive is stored separate from the computer, so you can take it with you and use it on other computers. Similarly, data in a Kubernetes volume can be stored separate from the containers, so it can be accessed even if the containers are deleted. In simple terms, Volumes in Kubernetes can be plugged and unplugged into Kubernetes, what this means is that, the Containers/Pods and Volumes both have different lifecycles; more on this later.
Below is an Illustration of a container without a Volume and a container with a Volume:
+-------------+
| Container |
+-------------+
| Code |
+-------------+
-> Container without Volume
+-------------+
| Container |
+-------------+
| Code |
+-------------+
| Volume |
+-------------+
-> Container with attached Volume
In this illustration, the “Container” is the running application, and the “Code” is the code for the application. The “Volume” is the storage area for data generated by the application.
In this way, Kubernetes volumes allow you to persist data even if the containers are deleted or recreated, making it easier to manage data in a containerized environment.
Kubernetes has a mature, feature-rich storage subsystem called the Persistent Volume Subsystem. This is in-charge of creating and mounting storage within your Kubernetes Cluster.
The Persistent Volume (PV) subsystem in Kubernetes, is a system for managing storage resources in a cluster. It allows you to dynamically provision storage resources and manage their lifecycle, so you can easily store data for your containers and ensure that it persists even if the containers themselves are deleted or recreated.
Here’s how it works:
- A Persistent Volume (PV) is created and defined in the cluster, specifying the type and size of storage that is available.
- A Storage Class is created, which defines the characteristics and provisioning policies for a specific type of storage. This can include things like the type of storage (e.g., NFS, iSCSI), the performance characteristics (e.g., IOPS, latency), and the cost.
- A Persistent Volume Claim (PVC) is created by a user, which requests a certain amount of storage from the cluster. The PVC also specifies the desired Storage Class.
- The PV subsystem matches the PVC with an available PV that meets the desired Storage Class, and binds the two together, making the storage from the PV available to the user.
- The user can then mount the storage from the PV into a container, using it to store data that needs to persist even if the container itself is deleted or recreated.
The PV subsystem, along with Storage Classes, provides a flexible and scalable solution for managing storage in a Kubernetes cluster, allowing you to dynamically allocate storage resources as needed, choose the right type of storage for your needs, and ensuring that your data is always available and safe.
Note: While the Persistent Volume method of creating storage resources is static and beneficial when working with a few pods, StorageClasses offers you dynamic methods of creating storage resources, which are handy when working with a big number of pods.
This means that any time you construct a storage class, you must provide the storage type that you want to use as well as the storage backend. You can also construct a PVC with the name of the storage class and the storage’s size in it if that is what you want. A Persistent Volume is subsequently created by the Storage Class for the PVC to utilize or claim. This allows you to build as many Pods as you like without having to create a PV each time you want to create a volume.
Also, one thing that helps us connect with different storage backend’s( AWS, Azure, , Google, Digital Ocean) is the Container Storage Interface.
The Container Storage Interface (CSI) is a specification for creating and managing storage solutions in container orchestration systems like Kubernetes. It provides a common API for communication between a storage provider (such as a storage vendor or cloud provider) and a container orchestration system like Kubernetes , enabling storage providers to easily integrate their storage solutions with Kubernetes and other container orchestration systems.
With CSI, storage providers can implement plugins that provide specific storage functionalities, such as creating and deleting volumes, resizing volumes, and attaching/detaching volumes to/from nodes. The CSI plugins can then be deployed and used by container orchestration systems like Kubernetes to manage storage resources dynamically.
The use of CSI helps to decouple the storage provider from the container orchestration system, making it easier for storage providers to integrate with multiple container orchestration systems and for users to choose the best storage solution for their needs.
Hands-On Session
For this tutorial, we will be using the Linode Cloud provider as it’s easy to setup and connect to.
Here are the general steps to create a Kubernetes cluster on Linode:
- Sign up for a Linode account: If you don’t already have a Linode account, sign up for one and log in to the Linode Cloud Manager.
- Click on Kubernetes at the left sidebar and Create Cluster.
- Set your Cluster name, Kubernetes Version and Node Specifications and create your cluster.
Once you’re done creating your cluster and nodes are up and running, download your kubernetes configuration file from the Linode Cloud dashboard. Using the kubectl command, you will now be able to access your Cluster from your local machine.
Now on your Local machine you need to do some other things to your configuration file;
- To improve security, change the
kubeconfig.yaml
file permissions to be only accessible by the current user:chmod go-r /Downloads/kubeconfig.yaml
- Open a terminal shell and save your kubeconfig file’s path to the
$KUBECONFIG
environment variable. In the example command, the kubeconfig file is located in theDownloads
folder, but you should alter this line with this folder’s location on your computer:export KUBECONFIG=~/Downloads/kubeconfig.yaml
If you followed the steps above, you should be able to see your cluster nodes from your local machine using the kubectl get nodes command.
you should see something like this:
Before we get started with creating our volumes , we need to give our Kubernetes Cluster Authorization to create volumes.
On the Linode Cloud manager, Create a Personal Access Token granting all access to the token.
This will come in handy when Kubernetes tries to create and mount volumes.
After Successfully creating the token copy the token and create a secrets.yaml file and paste the code below
apiVersion: v1
kind: Secret
metadata:
name: linode
namespace: kube-system
stringData:
token: "************************************************************"
region: "us-east"
Next, run the kubectl apply -f secrets.yaml command to create the secret object.
Next, you need to create a pvs.yaml file and paste in the below code snippets:
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: pvc1
spec:
accessModes:
- ReadWriteOnce
storageClassName: linode-block-storage-retain
resources:
requests:
storage: 10Gi
---
apiVersion: v1
kind: Pod
metadata:
name: cm-pod
labels:
app: cm-pod
spec:
volumes:
- name: data
persistentVolumeClaim:
claimName: pvc1
containers:
- name: ubuntu-ctr
image: ubuntu:latest
command: ["/bin/sh", "-c", "sleep 100000"]
volumeMounts:
- mountPath: "/data"
name: data
Note that we didn’t create a storage class and we went ahead and referenced the linode-block-storage-retain
StorageClass. The linode-block-storage-retain
StorageClass in Kubernetes refers to a specific StorageClass provided by Linode, which is a cloud hosting provider. This StorageClass is used to create Persistent Volumes (PVs) in Linode’s Block Storage service.
The linode-block-storage-retain
StorageClass is designed for data persistence, meaning that the data stored in a PV created by this StorageClass will persist even if the pod that used the PV is deleted. This is achieved by creating a Block Storage volume in Linode, and attaching it to the node where the pod is running.
When a Persistent Volume Claim (PVC) is created that requests storage from the linode-block-storage-retain
StorageClass, the Kubernetes control plane will dynamically provision a new Block Storage volume in Linode, and bind it to the PVC.
There are a few thing to note from the pvs.yaml file:
1. The above PVC will request a 10gb storage volume.
2. The volume will be mounted at /data path in the container.
3. We used the ReadWriteOnce accessMode for our PVC
Next, run the kubectl apply -f pvs.yaml command to create both the PVC and the Pod.
After creating both objects, run the kubectl get pods command, you should get something like the one below
Next, let’s Exec into our Container to confirm our volume was mounted successfully.
kubectl exec -it cm-pod — /bin/sh | ls /
The above command should display something similar to the image below:
From the image above , we can see that the data volume was successfully mounted on our Pod/Container.
In conclusion, volumes play a crucial role in storing and managing data in Kubernetes. With different types of volumes and the Persistent Volume Subsystem, it’s easy to achieve data persistence, even if the pod that used the data is deleted. Understanding the different types of volumes and the persistent volume subsystem is key to effectively managing data in your Kubernetes cluster.
Additionally, the Container Storage Interface (CSI) provides a standard interface for creating and managing volumes in Kubernetes, making it easier to integrate with different storage providers. By using volumes and the persistent volume subsystem, you can ensure that your data is secure, available, and accessible even if a pod or node fails.
I hope this article has helped you understand the different types of volumes in Kubernetes, the persistent volume subsystem, and how to effectively use them in your cluster. With these tools and knowledge, you can now manage data with confidence and keep your applications running smoothly in a test/production environment.
For more information you can reach out to me on Twitter or Linkedin. Thank you for Reading🚀