1.8. Persistent storage

By default, data stored in containers is not persistent. This means that any data written inside a container is lost when the container no longer exists, as is also the case with our current MariaDB. To prevent this, we can use persistent storage.

Requesting Storage

Attaching persistent storage to a Pod involves two steps.

First, we create a PersistentVolumeClaim (PVC) within our namespace. This claim specifies details such as the required storage size.

A PVC is merely a request for storage, not the storage itself. Kubernetes automatically binds the claim to an available PersistentVolume (PV) that meets or exceeds the requested size.

  • If only larger volumes are available, one of them will be assigned, and the PVC will be updated with the new size.
  • If no suitable volume exists, the request remains unfulfilled until a matching or larger volume is created.

In modern Kubernetes environments, Container Storage Interface (CSI) drivers or storage operators automatically create a PV with the requested size upon PVC creation. This eliminates the need to manually provision PVs in advance.

Attaching a Volume to a Pod

In the second step, we attach the previously created PVC to a Pod.

Similar to how we previously edited the Deployment configuration to add a readiness probe, we now modify it to include the persistent volume.

Task 1.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 frontend deployment, our application automatically creates the database schema at startup time. Wait for the database pod to be started fully before restarting the frontend pods.

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

kubectl rollout restart deployment example-frontend --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 1.8.2: Persistence check

Add some data through the frontend to your Database. Scale your MariaDB Pod to 0 replicas and back to 1. Observe that the new Pod didn’t lose any data.