pixelpiloten "articles and tutorials into all things Docker containers, Kubernetes,
CI/CD and automating infrastructure"
Go back to blogposts
Wednesday, 11 September 2019

Persistent volumes in Kubernetes

Persistent volumes in Kubernetes

When you run Kubernetes on a Cloud provider like Amazon AWS, Google cloud, Azure or OpenStack creating Volumes on the fly for your persistent storage needs is easy peasy. So come along and I’ll show you how you can use this functionality and get your persistent storage goodness.

Steps

In this example our cluster is in Amazon AWS so we can use EBS volumes (look here for other Cloud storage provisioners: https://kubernetes.io/docs/concepts/storage/storage-classes/#provisioner).

  1. Create a Storage class definition in a file called storageclass.yaml.

     apiVersion: storage.k8s.io/v1
     kind: StorageClass
     metadata:
       name: generalssd
     provisioner: kubernetes.io/aws-ebs
       parameters:
         type: gp2 # This is different for each Cloud provider and what disk types they have and what they name them.
         fsType: ext4
    
  2. Create the StorageClass with Kubectl.

     $ kubectl apply -f storageclass.yaml
    
  3. Create a Persistent volume claim that uses the Storage class we created above and define how much storage you need by creating a file called pvc.yaml and paste this into it.

     apiVersion: v1
     kind: PersistentVolumeClaim
     metadata:
       name: mycoolvolumeclaim
     spec:
       accessModes:
         - ReadWriteOnce
       resources:
         requests:
           storage: 1Gi # Specify the size of the volume you want.
       storageClassName: generalssd # This is the name of the Storage class we created above.
    
  4. Create the PersistentVolumeClaim with Kubectl.

     $ kubectl apply -f pvc.yaml
    
  5. You can now use that volume and mount it inside your container. In this example we use a database container and mount the database folder inside the container. Create a file called deployment.yaml and past this:

     apiVersion: apps/v1
     kind: Deployment
     metadata:
       name: mysql
       labels:
         app: mysql
     spec:
       replicas: 1
       selector:
         matchLabels:
         app: mysql
       template:
         metadata:
         labels:
           app: mysql
         spec:
           containers:
           - name: mysql
             image: mysql
             volumeMounts:
               - name: mycoolvolume # Name of the volume you define below.
                 mountPath: /var/lib/mysql # Path inside the container you want to mount the volume on.
             ports:
             - containerPort: 80
           volumes:
             - name: mycoolvolume # This pods definition of the volume.
               persistentVolumeClaim:
                 claimName: mycoolvolumeclaim # The PersistentVolumeClaim we created above.
    
  6. Create the Deployment with your database Pod with Kubectl.

     $ kubectl apply -f deployment.yaml
    

So to re-itterrate the steps:

  • Create a StorageClass where you define a name and what type of disk you want (depends on the Cloud provider)
  • Create a PersistentVolumeClaim where you define a name and how much disk space you want.
  • Define what volumes you want to use in your Pod definition and reference what PersistentVolumeClaim you want to use and mount it on a path inside your container.

Tadaa!

You have now deployed mysql with a volume attached to the container so whenever you deploy it the database(s) will actually persist because of our Volume :)