Outcomes
You should be able to deploy applications with persistent storage and create volumes from a storage class. The storage class must meet the application storage requirements.
As the student user on the workstation machine, use the lab command to prepare your system for this exercise.
This command ensures that all resources are available for this exercise.
[student@workstation ~]$ lab start storage-classes
Instructions
Log in to the OpenShift cluster as the
developeruser with thedeveloperpassword. Use thestorage-classesproject.Log in to the OpenShift cluster.
[student@workstation ~]$
oc login -u developer -p developer \ https://api.ocp4.example.com:6443Login successful. ...output omitted...Set the
storage-classesproject as the active project.[student@workstation ~]$
oc project storage-classes...output omitted...
Examine the available storage classes on the cluster. Identify an appropriate storage class to use for a database application.
Use the
getcommand to retrieve a list of storage classes in the cluster. You can use thestorageclassshort name,sc, in the command.[student@workstation ~]$
oc get scNAME PROVISIONER ... nfs-storage (default) k8s-sigs.io/nfs-subdir-external-provisioner ... lvms-vg1 topolvm.io ...Because an administrator can change the default storage, applications must specify a storage class that meets the application requirements.
Use the
oc describecommand to view the details of thelvms-vg1storage class.[student@workstation ~]$
oc describe sc lvms-vg1Name: lvms-vg1 IsDefaultClass: No Annotations: description=Provides RWO and RWOP Filesystem & Block volumes Provisioner: topolvm.io Parameters: csi.storage.k8s.io/fstype=xfs,topolvm.io/device-class=vg1 AllowVolumeExpansion: True MountOptions: <none> ReclaimPolicy: Delete VolumeBindingMode: WaitForFirstConsumer Events: <none>The description annotation states that the storage class provides support for block volumes. For some applications, such as databases, block volumes can provide a performance advantage over file system volumes. In the
lvms-vg1storage class, theAllowVolumeExpansionfield is set toTrue. With volume expansion, cluster users can edit their PVC objects and specify a new size for the PVC. Kubernetes then uses the storage back end to automatically expand the volume to the requested size. Kubernetes also expands the file system of pods that use the PVC. Enabling volume expansion can help to protect an application from failing due to the data growing too fast. With these features, thelvms-vg1storage class is a good choice for the database application.
Use the
registry.ocp4.example.com:8443/rhel8/mysql-80container image to create a MySQL deployment nameddb-pod. Add the missing environment variables for the pod to run.Create the
db-poddeployment.[student@workstation ~]$
oc create deployment db-pod --port 3306 \ --image registry.ocp4.example.com:8443/rhel8/mysql-80deployment.apps/db-pod createdAdd the environment variables.
[student@workstation ~]$
oc set env deployment/db-pod \ MYSQL_USER=user1 \ MYSQL_PASSWORD=mypa55w0rd \ MYSQL_DATABASE=itemsdeployment.apps/db-pod updatedVerify that the pod is running.
[student@workstation ~]$
oc get podsNAME READY STATUS RESTARTS AGE db-pod-b4ccfb74-nn4s5 1/1 Running 0 5sExpose the
db-poddeployment to create a service.[student@workstation ~]$
oc expose deployment/db-podservice/db-pod exposed
Add a 1 Gi, RWO PVC named
db-pod-pvcto the deployment. Specify the volume name aslvm-storage, and set the/var/lib/mysqldirectory as the mount path. Use thelvms-vg1storage class.Use the
oc set volumecommand to create a PVC for the deployment.[student@workstation ~]$
oc set volumes deployment/db-pod \ --add --name lvm-storage --type pvc \ --claim-mode rwo --claim-size 1Gi --mount-path /var/lib/mysql \ --claim-class lvms-vg1 \ --claim-name db-pod-pvcdeployment.apps/db-pod volume updatedThe
claim-classoption specifies a non-default storage class.Note
The
oc set volumescommand does not have an option to set the volume mode property. Thus, theoc set volumescommand results in using the defaultFilesystemvolume mode. Use a declarative manifest to set the volume mode to block. The use of declarative manifests is out of scope for this course.Use the
oc get pvccommand to view the status of the PVC. Identify the name of the PV, and confirm that the PVC uses thelvms-vg1non-default storage class.[student@workstation ~]$
oc get pvcNAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS ... db-pod-pvc Bound pvc-72...035a 1Gi RWO lvms-vg1 ...Use the
oc describe pvccommand to inspect the details of thedb-pod-pvcPVC.[student@workstation ~]$
oc describe pvc db-pod-pvcName: db-pod-pvc Namespace: storage-classes StorageClass: lvms-vg1 Status: Bound Volume: pvc-b3084a46-3f32-435e-987b-4ad3b9026021 Labels: <none> Annotations: pv.kubernetes.io/bind-completed: yes pv.kubernetes.io/bound-by-controller: yes volume.beta.kubernetes.io/storage-provisioner: topolvm.io volume.kubernetes.io/selected-node: master01 volume.kubernetes.io/storage-provisioner: topolvm.io Finalizers: [kubernetes.io/pvc-protection] Capacity: 1Gi Access Modes: RWO VolumeMode: Filesystem Used By: db-pod-568888457d-qmxn9 Events: ...output omitted...The
Used Byattribute confirms that the PVC is bound to a pod.
Connect to the database to verify that it is working.
[student@workstation ~]$
oc run query-db -it --rm \ --image registry.ocp4.example.com:8443/rhel8/mysql-80 \ --restart Never --command \ -- /bin/bash -c "mysql -uuser1 -pmypa55w0rd --protocol tcp \ -h db-pod -P3306 items -e 'show databases;'"mysql: [Warning] Using a password on the command line interface can be insecure. +--------------------+ | Database | +--------------------+ | information_schema | | items | | performance_schema | +--------------------+ pod "query-db" deletedDelete the
db-poddeployment and thedb-pod-pvcPVC.Delete the
db-poddeployment.[student@workstation ~]$
oc delete all -l app=db-podpod "db-pod-568888457d-fvklp" deleted service "db-pod" deleted deployment.apps "db-pod" deleted replicaset.apps "db-pod-568888457d" deleted ...output omitted...Verify that the PVC still exists without the deployment.
[student@workstation ~]$
oc get pvcNAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS ... db-pod-pvc Bound pvc-72...035a 1Gi RWO lvms-vg1 ...Delete the
db-pod-pvcPVC.[student@workstation ~]$
oc delete pvc db-pod-pvcpersistentvolumeclaim "db-pod-pvc" deleted
Create a PVC for an application that requires a shared storage volume from the
nfs-storagestorage class.Create a PVC YAML manifest file named
nfs-pvc.yamlwith the following contents:apiVersion: v1 kind: PersistentVolumeClaim metadata: name: nfs-pvc spec: accessModes: - ReadWriteOnce resources: requests: storage: 1Gi storageClassName: nfs-storageCreate the PVC by using the
oc create -fcommand and the YAML manifest file.[student@workstation ~]$
oc create -f nfs-pvc.yamlpersistentvolumeclaim/nfs-pvc createdUse the
oc describe pvccommand to view the details of the PVC resource.[student@workstation ~]$
oc describe pvc nfs-pvcName: nfs-pvc Namespace: storage-classes StorageClass: nfs-storage Status: Bound Volume: pvc-9f462124-d96e-43e5-96a7-f96dd9375579 Labels: <none> Annotations: pv.kubernetes.io/bind-completed: yes pv.kubernetes.io/bound-by-controller: yes volume.beta.kubernetes.io/storage-provisioner: k8s-sigs.io/nfs-subdir-external-provisioner volume.kubernetes.io/storage-provisioner: k8s-sigs.io/nfs-subdir-external-provisioner Finalizers: [kubernetes.io/pvc-protection] Capacity: 1Gi Access Modes: RWO VolumeMode: Filesystem Used By: <none> Events: ...output omitted...The
Used By: <none>attribute shows that no pod is using the PVC. TheStatus: Boundvalue and theVolumeattribute assignment confirm that the storage class has itsVolumeBindingModeset toImmediate.
Use the
registry.ocp4.example.com:8443/ubi9/httpd-24:1-321container image to create a web application deployment namedweb-pod.Create the
web-poddeployment.[student@workstation ~]$
oc create deployment web-pod --port 8080 \ --image registry.ocp4.example.com:8443/ubi9/httpd-24:1-321deployment.apps/web-pod createdCreate a service for the
web-podapplication.[student@workstation ~]$
oc expose deployment web-podservice/web-pod exposedExpose the service to create a route for the
wep-podapplication. Specifyweb-pod.apps.ocp4.example.comas the hostname.[student@workstation ~]$
oc expose svc web-pod \ --hostname web-pod.apps.ocp4.example.comroute.route.openshift.io/web-pod exposedView the route that is assigned to the
web-podapplication.[student@workstation ~]$
oc get routesNAME HOST/PORT PATH SERVICES PORT ... web-pod web-pod.apps.ocp4.example.com web-pod 8080 ...Use the
curlcommand to view the index page of theweb-podapplication.[student@workstation ~]$
curl http://web-pod.apps.ocp4.example.com/<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd"> <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en"> <head> <title>Test Page for the HTTP Server on Red Hat Enterprise Linux</title> ...output omitted...
Add the
nfs-pvcPVC to theweb-poddeployment.Use the
oc set volumecommand to add the PVC to the deployment. Specify the volume name asnfs-volume, and set the mount path to the/var/www/htmldirectory.[student@workstation ~]$
oc set volumes deployment/web-pod \ --add --name nfs-volume \ --claim-name nfs-pvc \ --mount-path /var/www/htmldeployment.apps/web-pod volume updatedThe volume
mount-pathis set to the/var/www/htmldirectory. The server uses this path to serve HTML content.
Use the
registry.ocp4.example.com:8443/redhattraining/do180-rostercontainer image to create a custom web application deployment namedapp-pod.Create the
app-poddeployment and specify port9090as the target port.[student@workstation ~]$
oc create deployment app-pod --port 9090 \ --image registry.ocp4.example.com:8443/redhattraining/do180-rosterdeployment.apps/app-pod createdCreate a service for the
app-podapplication.[student@workstation ~]$
oc expose deployment app-podservice/app-pod exposedExpose the service to create a route for the
app-podapplication. Useapp-pod.apps.ocp4.example.comfor the hostname.[student@workstation ~]$
oc expose svc app-pod \ --hostname app-pod.apps.ocp4.example.comroute.route.openshift.io/app-pod exposed
Add the
nfs-pvcPVC to theapp-podapplication deployment.Use the
oc set volumecommand to add the PVC to the deployment. Set the volume name tonfs-volumeand the mount path to the/var/tmpdirectory.[student@workstation ~]$
oc set volumes deployment/app-pod \ --add --name nfs-volume \ --claim-name nfs-pvc \ --mount-path /var/tmpdeployment.apps/app-pod volume updatedAt this point, the
web-podand theapp-podapplications are sharing a PVC. Kubernetes does not have a mechanism to prevent data conflicts between the two applications. In this case, theapp-podapplication is a writer and theweb-podapplication is a reader, and thus they do not have a conflict. The application implementation, not Kubernetes, prevents data corruption from the two applications that use the same PVC. The RWO access mode does not protect data integrity. The RWO access mode means that a single node can mount the volume as read/write, and pods that share the volume must exist on the same node.
Use the
app-podapplication to add content to the shared volume.Open a web browser to the
http://app-pod.apps.ocp4.example.com/pageIn the form, enter your information and then click . The application adds your information to the list after the form.
Click to create the
/var/tmp/People.htmlfile on the shared volume.
Open another tab on the browser and navigate to the
http://web-pod.apps.ocp4.example.com/People.htmlpage. Theweb-podapplication displays thePeople.htmlfile from the shared volume.