Description: During this lab, we will re-architect our solution towards a stateless nature by using a database to store the content. In a second phase, we will get familiar with persistent volumes and persitent volume claims and see how they help us to achieve data persistence inside a Cluster.
Duration: 60m
List the goals using bullet point per goal, eg: At the end of this lab, each participant will have: - a working local environment to perform the k8s labs on a remote k8s cluster, inside its own namespace. - a working local environment to perform the k8s labs on a remote k8s cluster, inside its own namespace.
In the LAB-K8S-05 - Deployment, we have seen one important limitation of our architecture for the simple todo list, that prevents us to use gracefully the scaling and services features of the kubernetes cluster: the application is not stateless.
Our development team has been hard at work to completely rewrite the backend part of the application and use an external PostgreSQL database to store its state outside of the application, and has come up with version 3.0 of the todo list.
For this task, we gonna use Secrets and Deployments to deploy this database into our namespace.
-
✅ Read the documentation of the PostgreSQL container image to get familiar with the requirements, and especially the section around environment variables
-
✅ Write a Secret named postgres-secret that will define 3 variables necessary to create a working empty database:
kubectl create secret generic postgres-secret \
--from-literal=POSTGRES_DB=swdb \
--from-literal=POSTGRES_USER=obiwankenobi \
--from-literal=POSTGRES_PASSWORD=masterjedi
-
✅ Create a deployment for the database, with the following requirements: (solution here)
- replica of 1 instance only
- The image to use is postgres:10.4-alpine
- Container port 5432
- the environment variables will be defined from the secret postgres-secret using an all-keys injection (see here)
-
✅ Expose the datase with a ClusterIP service named postgres-service, accessible on port 5432 as well (solution here)
In order to connect to an external database, the application now needs the follow environment variables:
DB_USER: database user DB_HOST: database server DB_NAME: database name DB_PORT: database server port DB_PASSWORD: database user's password
-
✅ Use the previous deployment specification and update the image to version 3.0, use the secret postgre-secret keys to maps to these new environment variables (DB_USER, DB_PASSWORD, DB_NAME), as well as the postgres service DNS name and port for DB_HOST and DB_PORT. (solution here)
-
✅ Once working, scale the replicas to 2
-
✅ Can you confirm the application is now stateless ?
-
✅ Stop your application deployment and the database. Launch the database deployment. Launch the application deployment. What has happened?
They provide an abstraction between producers of storage space (admins on the cluster providing storage elements called persistent volumes) and consumers (applications requesting a storage volume through a claim).
- ✅ Read the documentation on PersistentVolumes
- ✅ Try to create a persistent volume (pv.yml), what's happening?
- ✅ Why ?
- ✅ In which namespace is the persistent volume created ?
There can't be more than 1 PVC per PV. The association to a PV depends on the PVC request capacity and the capacity of the first unbound PV, as well as the modes and access modes desired. The volume remains bound until the pvc is deleted, and the reclaim policy defines what happens upon release.
The reclaim policy for a PersistentVolume tells the cluster what to do with the volume after it has been released of its claim. Currently, volumes can either be Retained, Recycled, or Deleted
The cluster admin has provisioned 20 persistent volumes of capacity 50Mi, with an access mode of ReadWriteOnce and volume mode Filesystem. The storageclass to specify to claim these volumes is small-nfs.
- ✅ Create a persistent volume claim called dbclaim that will request one of these volumes. Set a capacity of 10Mi in the claim. (solution here)
- ✅ Verify your claim has a Bound status.
Now we will use our claim for our database.
-
✅Read the documention and Rewrite the deployment of the database to use the dbclaim as a volume. PostgreSQL stores the database data inside the /var/lib/postgresql path in the container.
-
✅ Verify the persistency of the data from your todo by inserting data and starting/stopping the deployments
A more elegant and efficient way than having cluster administrators pre-creating a set of PersistentVolumes for the claims to come is to use StorageClasses, which allows for the dynamic provisioning of the volumes behind a claim.
In our target cluster, we have a storage class called jelastic-dynamic-volume:
kubectl describe sc jelastic-dynamic-volume
Name: jelastic-dynamic-volume
IsDefaultClass: Yes
Annotations: storageclass.kubernetes.io/is-default-class=true
Provisioner: cluster.local/nfs-client-provisioner
Parameters: archiveOnDelete=true
AllowVolumeExpansion: True
MountOptions:
soft
proto=tcp
ReclaimPolicy: Delete
VolumeBindingMode: Immediate
Events: <none>
This storage class is based on the nfs client provisioner and provides immediate binding of the pvc and the pv's created. Upon unbinding, the underlying volume is deleted.
- ✅ Stop your deployment, and delete your previous persistent volume claim
- ✅ Rewrite your pvc specifying the storageClassName: jelastic-dynamic-volume and apply it
- ✅ Restart your database & application deployments
- ✅ What is the size of the claim ?