Azure Kubernetes Service Storage Provisioning
Introduction
Storage is an important element for application deployment in any environment, on-prem or cloud. Even if we are running our application in a container some application may need storage to store the data they need for processing.
So if we are using Kubernetes to deploy the application we need to configure the underline storage that needs to run Pods. But the beauty of Kubernetes is it abstract the complex deployment of storage for the application. As a Developer, he/she doesn’t need to worry about how the storage are provisioned to application.
If you decide to deploy the application to AKS (Azur Kubernetes Service) some application may need temporary storage, some may need persistent volume, some may need fast SSD storage. Luckily Kubernetes can cover most of the storage option and some advance features too.
In this blog, we will discuss following Kubernetes storage concepts.
- Volumes
- Persistent Volume
- Storage Classes
- Persistent Volume Claims
Volumes
When deploying application to AKS its often to see provisioning storage to retrieve application data. In Kubernetes world Pods are treat as ephemeral, disposable resources, there for we have different approaches to use persistent data for application. A volume represents a way to store, retrieve, and persist data across pods and through the application lifecycle.
In AKS to provisioned persistent disk it use Azure Disks and Azure Files. There are few methods we can provisioned data disks to Pods, we can create disk manually and attached it to the pod when its provisioned or can use dynamic provisioned.
Azure Disks
This can be use to create Kubernetes DataDisk resource. These disks can be premium SSD disk or Azure standard storage, backed by HDDs. For most production environment its best to use premium SSDs. Azure disks are mount to Pod as ReadWriteOnce, therefor its only available to a single node. For storage that need to access by multiple nodes simultaneously, use Azure Files.
Azure Files
This can be used to mount an SMB 3.0 share backed by an Azure Storage account to pods. Files let you share data across multiple nodes and pods.
Other than above two storage types Kubernetes support various storage types including Fiber, ISCSI etc. You can refer more about on supported storage from Kubernetes Storage documentation.
Following is an example Kubernetes manifest to attach a volume to Pod.
apiVersion: v1
kind: Pod
metadata:
name: mongodb-azure
spec:
volumes:
- name: mongodb-data
azureDisk:
diskName: mongovol
diskURI: /subscriptions/<Sub-ID>/resourceGroups/<Resource-Group>/providers/Microsoft.Compute/disks/mongovol
kind: Managed
fsType: ext4
containers:
- image: mongo
name: mongodb
volumeMounts:
- name: mongodb-data
mountPath: /data/db
ports:
- containerPort: 27017
protocol: TCP
Note
Before we create the pod we need to provision the Azure Disk. Then add the disk ID to the diskURI parameter.
Following is short demo how we can do it in Azure.
PersistentVolumes
Managing storage is a complex problem for compute resources. To make this easy Kubernetes introduce PersistentVolume subsystem an API for users and administrators that abstracts details of how storage is provided from how it is consumed. To do this we need to have few Kubernetes resources called StorageClass, PersistentVolume, and PersistentVolumeClaim. PersistentVolumes are use full when creating ReplicaSet, Deployment, and StatefulSets.
Cluster Administrator can create PersistentVolume by manually or dynamically created by the Kubernetes API server. If a pod is scheduled and requests storage that is not currently available, Kubernetes can create the underlying Azure Disk or Files storage and attach it to the pod. Dynamic provisioning uses a StorageClass to identify what type of Azure storage needs to be created.
*"A PersistentVolume is a piece of storage in the cluster that has been provisioned by an administrator. It is a resource in the cluster just like a node is a cluster resource. PVs are volume plugins like Volumes, but have a lifecycle independent of any individual pod that uses the PV. This API object captures the details of the implementation of the storage, be that NFS, iSCSI, or a cloud-provider-specific storage system.
A PersistentVolumeClaim is a request for storage by a user. It is similar to a pod. Pods consume node resources and PVCs consume PV resources. Pods can request specific levels of resources (CPU and Memory). Claims can request specific size and access modes (e.g., can be mounted once read/write or many times read-only)."*[kubernetes.io]
Provisioning PersistentVolumes (Manual)
When we create a PersistentVolume from manual, first we need to create an Azure Disk manually as we did in Volumes above. For create, an Azure Disk refer this documentation.
Following is the Kubernetes manifest for PersistentVolumes.
apiVersion: v1
kind: PersistentVolume
metadata:
name: mongodb
spec:
capacity:
storage: 32Gi
accessModes:
- ReadWriteOnce
- ReadOnlyMany
persistentVolumeReclaimPolicy: Retain
azureDisk:
diskName: mongodb-pv
diskURI: /subscriptions/<Sub-Number>/resourceGroups/<Resource-Group>/providers/Microsoft.Compute/disks/mongodb-pv
kind: Managed
fsType: ext4
After that we need to create a PersistentVolumeClaim to Pod.
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: mongodb-pvc
spec:
resources:
requests:
storage: 32Gi
accessModes:
- ReadWriteOnce
storageClassName: ""
Next we need to attach this PersistentVolumeClaim to Pod.
apiVersion: v1
kind: Pod
metadata:
name: mongodb-pvc
spec:
containers:
- image: mongo
name: mongodb
volumeMounts:
- name: mongodb-data
mountPath: /data/db
ports:
- containerPort: 27017
protocol: TCP
volumes:
- name: mongodb-data
persistentVolumeClaim:
claimName: mongodb-pvc
Following is a demo for manually creating PV, PVC.
Provisioning PersistentVolumes (Dynamic)
When we use dynamic we do not need to provisioned the PersistentVolume upfront. To work with dynamic provisioned first we need to create a StorageClass. After creating StorageClass add StorageClass to the PersistentVolumeClaim. When we deploy the Pod it automatically provisioned the storage required for it.
Following is the yamlmanifest.
#Yaml for the StorageClass
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
name: premium-ssd
provisioner: kubernetes.io/azure-disk
parameters:
kind: managed
storageaccounttype: Premium_LRS
---
#Yaml for the PersistentVolumeClaim
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: mongodb-pvc
spec:
resources:
requests:
storage: 32Gi
accessModes:
- ReadWriteOnce
storageClassName: "premium-ssd" #Specify the StorageClass
---
#Yaml for the Pod
apiVersion: v1
kind: Pod
metadata:
name: mongodb-pvc
spec:
containers:
- image: mongo
name: mongodb
volumeMounts:
- name: mongodb-data
mountPath: /data/db
ports:
- containerPort: 27017
protocol: TCP
volumes:
- name: mongodb-data
persistentVolumeClaim:
claimName: mongodb-pvc
Demo for dynamic storage creation.