Adding a Database Application Description

In this lab, we’re going to deploy a Mongo database that will be used to store the data for the nationalparks application. We will also connect the nationalparks service with the newly deployed Mongo database, so that the nationalparks service can load and query the database for the corresponding information.

Finally, we will mark the nationalparks application as a backend for the map visualization tool, so that it can be dynamically discovered by the parksmap component using the OpenShift discovery mechanism and the map will be displayed automatically.

roadshow-app-architecture-nationalparks-2

Background: Storage

Most useful applications are "stateful" or "dynamic" in some way, and this is usually achieved with a database or other data storage. In this next lab we are going to add MongoDB to our nationalparks application and then rewire it to talk to the database using environment variables.

We are going to use the MongoDB image that is included with OpenShift.

By default, this will use EmptyDir for data storage, which means if the Pod disappears the data does as well. In a real application you would use OpenShift’s persistent storage mechanism to attach real-world storage (NFS, Gluster, EBS, etc) to the Pods to give them a persistent place to store their data.

Background: Environment Variables

As you’ve seen so far, the web console makes it very easy to deploy things onto OpenShift. When we deploy the database, we pass in some environment variables. These environment variables are used to set the username, password, and name of the database. You can change the values of these environment variables to anything you would like. The variables we are going to be setting are as follows:

  • MONGODB_USER

  • MONGODB_PASSWORD

  • MONGODB_DATABASE

  • MONGODB_ADMIN_PASSWORD

The database image is built in a way that it will automatically configure itself using the supplied information (assuming there is no data already present in the persistent storage!). The image will ensure that:

  • A database exists with the specified name

  • A user exists with the specified name

  • The user can access the specified database with the specified password

In the web console in your project-userXY project, again click the "Add to Project" button, and then find the mongodb-ephemeral template, and click it. You will notice that there are several MongoDB templates available, some of which come with application servers pre-configured. We just need a database, though, so mongodb-ephemeral is what you should choose.

ocp-mongodb-template

When we performed the application build we selected the builder image to use and OpenShift presented us the standard build workflow. Now we are using a template, a preconfigured set of resources that includes parameters that can be customized. In our case, the parameters we are concerned with are the environment variables discussed before (user, password, database, and admin password).

ocp-mongo-template-deploy

You can see that some of the fields say "generated if empty". This is a feature of Templates in OpenShift that will be covered in the next lab. For now, be sure to use the following values in their respective fields:

  • MONGODB_USER : mongodb

  • MONGODB_PASSWORD : mongodb

  • MONGODB_DATABASE: mongodb

  • MONGODB_ADMIN_PASSWORD : mongodb

You can leave the rest of the values as their defaults, and then click "Create". Then click Continue to overview. The MongoDB instance should quickly be deployed.

mongo-group-db-1

You can group services in OpenShift Console in order to display related services together in one panel. Click on the chain icon on the right-top corner of the nationalparks service, choose mongodb from the drop-down list in the Group Service to nationalparks dialog and click on OK. The nationalparks and mongodb services are groups and displayed together.

mongo-group-db-2

Exercise: Wiring the Application and the Database

When we initially created the nationalparks application, we provided no environment variables. The application is looking for a database, but can’t find one, and it fails gracefully (you don’t see an error).

We need to configure the nationalparks Pod(s) to have the right values in the right environment variables so that the application knows how and where to find MongoDB.

If you think way back to the beginning of the labs, you will recall that a DeploymentConfiguration tells OpenShift how to deploy something. This includes things like what environment variables to configure. So, to set up the right environment variables, we simply need to modify the DeploymentConfiguration (DC). This can easily be done from either the web interface or via the command line.

The command line takes a little less time, so let’s use that option. First, find the name of the DC:

$ oc get dc
NAME            REVISION   DESIRED   CURRENT   TRIGGERED BY
mongodb         1          1         1         config,image(mongodb:3.2)
nationalparks   1          1         1         config,image(nationalparks:latest)
parksmap        2          1         1         config,image(parksmap:1.2.0)

Then, use the oc env command to set environment variables directly on the DC:

$ oc env dc nationalparks -e DB_USERNAME=mongodb -e DB_PASSWORD=mongodb -e DB_NAME=mongodb -e DB_HOST=mongodb
deploymentconfig "nationalparks" updated

After you have modified the DeploymentConfig object, you can verify the environment variables have been added by viewing the YAML for it:

oc get dc nationalparks -o yaml

You should see the following section:

apiVersion: v1
kind: DeploymentConfig
metadata:
  annotations:
    openshift.io/generated-by: OpenShiftWebConsole
  creationTimestamp: 2017-07-04T09:41:51Z
  generation: 4
  labels:
    app: nationalparks
  name: nationalparks
  namespace: project-ksoong
  resourceVersion: "4074573"
  selfLink: /oapi/v1/namespaces/project-ksoong/deploymentconfigs/nationalparks
  uid: 020a0704-609d-11e7-bbc1-0682973451aa
spec:
  replicas: 1
  selector:
    deploymentconfig: nationalparks
  strategy:
    activeDeadlineSeconds: 21600
    resources: {}
    rollingParams:
      intervalSeconds: 1
      maxSurge: 25%
      maxUnavailable: 25%
      timeoutSeconds: 600
      updatePeriodSeconds: 1
    type: Rolling
  template:
    metadata:
      creationTimestamp: null
      labels:
        app: nationalparks
        deploymentconfig: nationalparks
    spec:
      containers:
      - env:
        - name: DB_USERNAME
          value: mongodb
        - name: DB_PASSWORD
          value: mongodb
        - name: DB_NAME
          value: mongodb
        - name: DB_HOST
          value: mongodb
        image: 172.30.160.227:5000/project-ksoong/nationalparks@sha256:07375820fba423add40b6e201a638a6b922e15c44194aff68d320598927c5b09
        imagePullPolicy: Always
        name: nationalparks
        ports:
        - containerPort: 8080
          protocol: TCP
        resources: {}
        terminationMessagePath: /dev/termination-log
      dnsPolicy: ClusterFirst
      restartPolicy: Always
      securityContext: {}
      terminationGracePeriodSeconds: 30
  test: false
  triggers:
  - imageChangeParams:
      automatic: true
      containerNames:
      - nationalparks
      from:
        kind: ImageStreamTag
        name: nationalparks:latest
        namespace: project-ksoong
      lastTriggeredImage: 172.30.160.227:5000/project-ksoong/nationalparks@sha256:07375820fba423add40b6e201a638a6b922e15c44194aff68d320598927c5b09
    type: ImageChange
  - type: ConfigChange
status:
  availableReplicas: 1
  conditions:
  - lastTransitionTime: 2017-07-04T09:42:55Z
    lastUpdateTime: 2017-07-04T09:42:55Z
    message: Deployment config has minimum availability.
    status: "True"
    type: Available
  - lastTransitionTime: 2017-07-04T10:25:21Z
    lastUpdateTime: 2017-07-04T10:25:23Z
    message: replication controller "nationalparks-2" successfully rolled out
    reason: NewReplicationControllerAvailable
    status: "True"
    type: Progressing
  details:
    causes:
    - type: ConfigChange
    message: config change
  latestVersion: 2
  observedGeneration: 4
  readyReplicas: 1
  replicas: 1
  unavailableReplicas: 0
  updatedReplicas: 1

You can also just ask OpenShift to tell you about the environment variables on the DC:

$ oc env dc/nationalparks --list
# deploymentconfigs nationalparks, container nationalparks
DB_USERNAME=mongodb
DB_PASSWORD=mongodb
DB_NAME=mongodb
DB_HOST=mongodb

Exercise: Exploring OpenShift Magic

As soon as we set the environment variables on the DeploymentConfiguration, some magic happened. OpenShift decided that this was a significant enough change to warrant updating the internal version number of the DeploymentConfiguration. You can verify this by looking at the output of oc get dc:

$ oc get dc
NAME            REVISION   DESIRED   CURRENT   TRIGGERED BY
mongodb         1          1         1         config,image(mongodb:3.2)
nationalparks   2          1         1         config,image(nationalparks:latest)
parksmap        2          1         1         config,image(parksmap:1.2.0)

Something that increments the version of a DeploymentConfiguration, by default, causes a new deployment. You can verify this by looking at the output of oc get rc:

$ oc get rc
NAME              DESIRED   CURRENT   READY     AGE
mongodb-1         1         1         1         11m
nationalparks-1   0         0         0         48m
nationalparks-2   1         1         1         6m
parksmap-1        0         0         0         4h
parksmap-2        1         1         1         1h

We see that the desired and current number of instances for the "-1" deployment is 0. The desired and current number of instances for the "-2" deployment is 1. This means that OpenShift has gracefully torn down our "old" application and stood up a "new" instance.

Exercise: Data, Data, Everywhere

Now that we have a database deployed, we can again visit the nationalparks web service to query for data:

And the result?

[]

Where’s the data? Think about the process you went through. You deployed the application and then deployed the database. Nothing actually loaded anything INTO the database, though.

The application provides an endpoint to do just that:

And the result?

"Inserted 2740 items."

If you then go back to /ws/data/all you will see tons of JSON data now. That’s great. Our parks map should finally work!

Hmm…​ There’s just one thing. The main map STILL isn’t displaying the parks. That’s because the front end parks map only tries to talk to services that have the right Label.

Exercise: Working With Labels

We explored how a Label is just a key=value pair earlier when looking at Services and Routes and Selectors. In general, a Label is simply an arbitrary key=value pair. It could be anything.

  • pizza=pepperoni

  • wicked=googly

  • openshift=awesome

In the case of the parks map, the application is actually querying the OpenShift API and asking about the Routes in the project. If any of them have a Label that is type=parksmap-backend, the application knows to interrogate that service’s endpoints to look for map data.

Fortunately, the command line provides a convenient way for us to manipulate labels. describe the nationalparks service:

$ oc describe route nationalparks
Name:			nationalparks
Namespace:		project-ksoong
Created:		About an hour ago
Labels:			app=nationalparks
Annotations:		openshift.io/generated-by=OpenShiftWebConsole
			openshift.io/host.generated=true
Requested Host:		nationalparks-project-ksoong.apps.na1.openshift.opentlc.com
			  exposed on router router about an hour ago
Path:			<none>
TLS Termination:	<none>
Insecure Policy:	<none>
Endpoint Port:		8080-tcp

Service:	nationalparks
Weight:		100 (100%)
Endpoints:	10.1.7.60:8080

You see that it only has one label: app=nationalparks. Now, use oc label:

$ oc label route nationalparks type=parksmap-backend
route "nationalparks" labeled

If you check your browser now:

parksmap-new-parks

You’ll notice that the parks suddenly are showing up. That’s really cool!

results matching ""

    No results matching ""