8. Persistent storage

By default, data in containers is not persistent as was the case e.g. in 7. Attaching a database. This means that the data written in a container is lost as soon as it does not exist anymore. We want to prevent this from happening. One possible solution to this problem is to use persistent storage.

Request storage

Attaching persistent storage to a Pod happens in two steps. The first step includes the creation of a so-called PersistentVolumeClaim (PVC) in our namespace. This claim defines amongst other things what size we would like to get.

The PersistentVolumeClaim only represents a request but not the storage itself. It is automatically going to be bound to a PersistentVolume by Kubernetes, one that has at least the requested size. If only volumes exist that have a bigger size than was requested, one of these volumes is going to be used. The claim will automatically be updated with the new size. If there are only smaller volumes available, the claim cannot be fulfilled as long as no volume with the exact same or larger size is created.

Attaching a volume to a Pod

In a second step, the PVC from before is going to be attached to the Pod. In 5. Scaling we edited the deployment configuration in order to insert a readiness probe. We are now going to do the same for inserting the persistent volume.

Task 8.1: Add a PersistentVolume

The following command creates a PersistentVolumeClaim which requests a volume of 1Gi size. Save it to pvc.yaml:

apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: mariadb-data
spec:
  accessModes:
    - ReadWriteOnce
  resources:
    requests:
      storage: 1Gi

And create it with:

kubectl apply -f pvc.yaml --namespace <namespace>

We now have to insert the volume definition in the correct section of the MariaDB deployment.

Change your local mariadb.yaml file and add the volumeMounts and volumes parts:

          resources:
            limits:
              cpu: 500m
              memory: 512Mi
            requests:
              cpu: 50m
              memory: 128Mi
          # start to copy here
          volumeMounts:
          - name: mariadb-data
            mountPath: /var/lib/mysql
      volumes:
      - name: mariadb-data
        persistentVolumeClaim:
          claimName: mariadb-data

Then apply the change with:

kubectl apply -f mariadb.yaml --namespace <namespace>

We need to redeploy the application pod, our application automatically creates the database schema at startup time. Wait for the database pod to be started fully before restarting the application pod.

If you want to force a redeployment of a Pod, you can use this:

kubectl rollout restart deployment example-web-app --namespace <namespace>

Using the command kubectl get persistentvolumeclaim or kubectl get pvc, we can display the freshly created PersistentVolumeClaim:

kubectl get pvc --namespace <namespace>

Which gives you an output similar to this:

NAME             STATUS   VOLUME                                     CAPACITY   ACCESS MODES   STORAGECLASS   AGE
mariadb-data     Bound    pvc-2cb78deb-d157-11e8-a406-42010a840034   1Gi        RWO            standard       11s

The two columns STATUS and VOLUME show us that our claim has been bound to the PersistentVolume pvc-2cb78deb-d157-11e8-a406-42010a840034.

Error case

If the container is not able to start it is the right moment to debug it! Check the logs from the container and search for the error.

kubectl logs mariadb-f845ccdb7-hf2x5 --namespace <namespace>

Task 8.2: Persistence check

Restore data

Repeat the task to import a database dump .

Test

Scale your MariaDB Pod to 0 replicas and back to 1. Observe that the new Pod didn’t loose any data.