Guided Exercise: Deploy Applications from Images and Templates

·

6 min read

Deploy a database from a container image and from a template by using the OpenShift command-line interface and compare the resources and attributes generated by each method.

Outcomes

In this exercise, you deploy two MySQL database server pods to compare deployment methods and the resources that each creates.

  • Deploy a database from a template.

  • Deploy a database from a container image.

As the student user on the workstation machine, use the lab command to prepare your system for this exercise.

This command ensures that resources are available for the exercise.

[student@workstation ~]$ lab start deploy-newapp

Procedure 4.1. Instructions

  1. As the developer user, create a project and verify that it is not empty after creation.

    1. Log in as the developer user with the developer password.

       [student@workstation ~]$ oc login -u developer -p developer \
         https://api.ocp4.example.com:6443
       ...output omitted...
      
    2. Create a project named deploy-newapp.

       [student@workstation ~]$ oc new-project deploy-newapp
       Now using project "deploy-newapp" on server ...output omitted...
      

      The new project is automatically selected.

    3. Observe that resources for the new project are not returned with the oc get all command.

       [student@workstation ~]$ oc get all
       No resources found in deploy-newapp namespace.
      

      IMPORTANT

      Commands that use all for the resource type do not include every available resource type. Instead, all is a shorthand form for a predefined subset of types. When you use this command argument, ensure that all includes any types that you intend to address.

    4. Observe that the new project contains other types of resources.

       [student@workstation ~]$ oc get serviceaccounts
       NAME       SECRETS   AGE
       builder    1         20s
       default    1         20s
       deployer   1         20s
      
       [student@workstation ~]$ oc get secrets
       NAME                       TYPE                                  DATA   AGE
       builder-dockercfg-sczxg    kubernetes.io/dockercfg               1      36m
       builder-token-gsnqj        kubernetes.io/service-account-token   4      36m
       default-dockercfg-6f8nm    kubernetes.io/dockercfg               1      36m
       ...output omitted...
      
  2. Create two MySQL instances by using the oc new-app command with different options.

    1. View the mysql-persistent template definition to see the resources that it creates. Specify the project that houses the template by using the -n openshift option.

       [student@workstation ~]$ oc describe template mysql-persistent -n openshift
       Name:        mysql-persistent
       Namespace:    openshift
       ...output omitted...
       Objects:
           Secret                                  ${DATABASE_SERVICE_NAME}
           Service                                 ${DATABASE_SERVICE_NAME}
           PersistentVolumeClaim                   ${DATABASE_SERVICE_NAME}
           DeploymentConfig.apps.openshift.io      ${DATABASE_SERVICE_NAME}
      

      The objects attribute specifies several resource definitions that are applied on using the template. These resources include one of each of the following types: secret, service (svc), persistent volume claim (pvc), and deployment configuration (dc).

    2. Create an instance by using the mysql-persistent template. Specify a name option and attach a custom team=red label to the created resources.

       [student@workstation ~]$ oc new-app -l team=red --template mysql-persistent \
         -p MYSQL_USER=developer \
         -p MYSQL_PASSWORD=developer
       ...output omitted...
       --> Creating resources with label team=red ...
           secret "mysql" created
           service "mysql" created
           persistentvolumeclaim "mysql" created
           deploymentconfig.apps.openshift.io "mysql" created
       --> Success
       ...output omitted...
      

      The template creates resources of the types from the preceding step.

    3. View and wait for the pod to start, which takes a few minutes to complete. You might need to run the command several times before the status changes to Running.

       [student@workstation ~]$ oc get pods
       NAME              READY   STATUS      RESTARTS  AGE
       mysql-1-deploy    0/1     Completed   0         93s
       mysql-1-qmxbf     1/1     Running     1         60s
      

      Your pod names might differ from the previous output.

    4. Create an instance by using a container image. Specify a name option and attach a custom team=blue label to the created resources.

       [student@workstation ~]$ oc new-app --name db-image -l team=blue \
         --image registry.ocp4.example.com:8443/rhel9/mysql-80:1 \
         -e MYSQL_USER=developer \
         -e MYSQL_PASSWORD=developer \
         -e MYSQL_ROOT_PASSWORD=redhat
       ...output omitted...
       --> Creating resources with label team=blue ...
           imagestream.image.openshift.io "db-image" created
       Warning: would violate PodSecurity "restricted:v1.24": ...output omitted...
           deployment.apps "db-image" created
           service "db-image" created
       --> Success
       ...output omitted...
      

      The command creates predefined resources that are needed to deploy an image. These resource types are image stream (is), deployment, and service (svc). Image streams and services are discussed in more detail elsewhere in the course.

      NOTE

      It is safe to ignore pod security warnings for exercises in this course. OpenShift uses the Security Context Constraints controller to provide safe defaults for pod security.

    5. Wait for the pod to start. After a few moments, list all pods that contain team as a label.

       [student@workstation ~]$ oc get pods -L team
       NAME                       READY   STATUS      RESTARTS   AGE    TEAM
       db-image-8d4b97594-6jb85   1/1     Running     1          55s    blue
       mysql-1-deploy             0/1     Completed   0          2m
       mysql-1-hn64v              1/1     Running     0          1m30s
      

      Your pod name might differ from the previous output. Without a readinessProbe, this pod shows as ready before the MySQL service is ready for requests. Readiness probes are discussed in more detail elsewhere in the course.

      Notice that only the db-image pod has a label that contains the word team. Pods that the mysql-persistent template creates do not have the team=red label, because the template does not define this label in its pod specification template.

  3. Compare the resources that each image and template method creates.

    1. View the template-created pod and observe that it contains a readiness probe.

       [student@workstation ~]$ oc get pods -l deploymentconfig=mysql \
         -o jsonpath='{.items[0].spec.containers[0].readinessProbe}' | jq
       {
         "exec": {
           "command": [
             "/bin/sh",
             "-i",
             "-c",
             "MYSQL_PWD=\"$MYSQL_PASSWORD\" mysqladmin -u $MYSQL_USER ping"
           ]
         },
         "failureThreshold": 3,
         "initialDelaySeconds": 5,
         "periodSeconds": 10,
         "successThreshold": 1,
         "timeoutSeconds": 1
       }
      

      NOTE

      The results of the preceding oc command are passed to the jq command, which formats the JSON output.

    2. Observe that the image-based pod does not contain a readiness probe.

       [student@workstation ~]$ oc get pods -l deployment=db-image \
         -o jsonpath='{.items[0].spec.containers[0].readinessProbe}' | jq
       no output expected
      
    3. Observe that the template-based pod has a memory resource limit, which restricts allocated memory to the resulting pods. Resource limits are discussed in more detail elsewhere in the course.

       [student@workstation ~]$ oc get pods -l deploymentconfig=mysql \
         -o jsonpath='{.items[0].spec.containers[0].resources.limits}' | jq
       {
         "memory": "512Mi"
       }
      
    4. Observe that the image-based pod has no resource limits.

       [student@workstation ~]$ oc get pods -l deployment=db-image \
         -o jsonpath='{.items[0].spec.containers[0].resources}' | jq
       {}
      
    5. Retrieve secrets in the project. Notice that the template produced a secret, whereas the pod that was created with only an image did not.

       [student@workstation ~]$ oc get secrets
       NAME                       TYPE                                  DATA   AGE
       ...output omitted...
       mysql                      Opaque                                4      3m
      
  4. Explore filtering resources via labels.

    1. Observe that not supplying a label shows all services.

       [student@workstation ~]$ oc get services
       NAME       TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)    AGE
       db-image   ClusterIP   172.30.38.113   <none>        3306/TCP   1m30s
       mysql      ClusterIP   172.30.95.52    <none>        3306/TCP   2m30s
      
    2. Observe that supplying a label shows only the services with the label.

       [student@workstation ~]$ oc get services -l team=red
       NAME    TYPE        CLUSTER-IP     EXTERNAL-IP   PORT(S)    AGE
       mysql   ClusterIP   172.30.95.52   <none>        3306/TCP   2m43s
      
    3. Observe that not all resources include the label, such as the pods that are created with the template.

       [student@workstation ~]$ oc get pods -l team=red
       No resources found in deploy-newapp namespace.
      
  5. Use labels to delete only the resources that are associated with the image-based deployment.

    1. Delete only the resources that use the team=red label by using it with the oc delete command. List the resource types from the template to ensure that all relevant resources are deleted.

       [student@workstation ~]$ oc delete all -l team=red
       replicationcontroller "mysql-1" deleted
       service "mysql" deleted
       deploymentconfig.apps.openshift.io "mysql" deleted
      
       [studen@workstation ~]$ oc delete secret,pvc -l team=red
       secret "mysql" deleted
       persistentvolumeclaim "mysql" deleted
      

      NOTE

      By using the oc delete all -l team=red command, some resources are deleted, but the persistent volume claim and secret remain.

    2. Observe that the resources that the template created are deleted.

       [student@workstation ~]$ oc get secret,svc,pvc,dc -l team=red
       No resources found in deploy-newapp namespace.
      
    3. Observe that the image-based resources remain unchanged.

       [student@workstation ~]$ oc get is,deployment,svc
       NAME                                      IMAGE REPOSITORY ...output omitted...
       imagestream.image.openshift.io/db-image   image-registry.openshift...output omitted...
       NAME                       READY   UP-TO-DATE   AVAILABLE   AGE
       deployment.apps/db-image   1/1     1            1           46m
      
       NAME               TYPE        CLUSTER-IP    EXTERNAL-IP   PORT(S)    AGE
       service/db-image   ClusterIP   172.30.71.0   <none>        3306/TCP   46m
      

Finish

On the workstation machine, use the lab command to complete this exercise. This step is important to ensure that resources from previous exercises do not impact upcoming exercises.

[student@workstation ~]$ lab finish deploy-newapp