OpenShift Build and Deploy a JEE Application with S2I

From NovaOrdis Knowledge Base
Revision as of 21:25, 27 November 2017 by Ovidiu (talk | contribs) (→‎Build)
Jump to navigation Jump to search

External

Internal

Overview

This article describes the process of setting up a project that builds from sources and deploys a simple JEE application. The source of the application is exposed in GitHub. We will use https://github.com/NovaOrdis/novaordis-session-servlet (Session Servlet Example). The final artifact will be deployed in a EAP 7 instance.

Create the OpenShift Project

The application will be hosted in its own OpenShift project:

oc new-project s2i-build-example \
  --display-name='S2I Build Example' \
  --description='A JEE Application that builds from source and deploys onto a EAP 7 instance'

Identify the Application Template

Since we intend to deploy our JEE application in top of a JEE container, the simplest method is to identify the application template that matches our requirements and use it. OpenShift comes with a series of application templates, which are pre-loaded in the "openshift" project:

oc get templates -n openshift

The application template that matches our requirements is "eap70-basic-s2i"

It can be explored with:

oc get -o yaml template eap70-basic-s2i -n open shift

The template can be used "as-is", or it can be downloaded locally and modified - for example, we can change the labels applied by the template to the objects it creates, so instead of "app=eap70-basic-s2i", we can use a more custom name for our application. Some of the parameters, including the application name, are allowed to be changed on command line. It is a good idea to review the application template and identify all parameters that can be customized.

Create the Application

oc new-app eap70-basic-s2i \
  --param APPLICATION_NAME=<application-name> \
  --param HOSTNAME_HTTP=<custom-hostname-instead-of-application_name.project.default_routing_subdomain> \
  --param SOURCE_REPOSITORY_URL=<git-repository-url> \
  --param SOURCE_REPOSITORY_REF=<git-branch/tag-reference> \
  --param CONTEXT_DIR=<path-withing-git-project-to-build> \
  --param GITHUB_WEBHOOK_SECRET=<github-webhook-secret> \
  --param IMAGE_STREAM_NAMESPACE=<imagestream-namespace> \
  --param MAVEN_MIRROR_URL=<maven-mirror-to-use-for-S2I-builds> 


Example:

oc new-app eap70-basic-s2i \
  --param APPLICATION_NAME=session-servlet \
  --param HOSTNAME_HTTP=session-servlet.apps.openshift.novaordis.io \
  --param SOURCE_REPOSITORY_URL=https://github.com/NovaOrdis/novaordis-session-servlet.git \
  --param SOURCE_REPOSITORY_REF=master \
  --param CONTEXT_DIR=/ \
  --param GITHUB_WEBHOOK_SECRET=n2h6dtHw7Gw3 \
  --param IMAGE_STREAM_NAMESPACE=openshift

Once executed, the "new-app" command creates the following:

Build

The build process starts immediately and its logs can be monitored with:

oc logs -f build/session-servlet-1

If successful, the build results in the creation of a new deployable image that gets uploaded into the integrated docker registry:

oc get is
NAME              DOCKER REPO                                                          TAGS      UPDATED
session-servlet   docker-registry.default.svc:5000/s2i-build-example/session-servlet   latest    5 minutes ago

S2i-build-example IntegratedDockerRegistry.png

How do I build new images and how do I control the tag?

More build operations:

Build Operations

Deployment

The deployment process begins immediately, triggered by an image change in the project's image stream, and results in the creation of a backing pod:

oc get pod
NAME                      READY     STATUS      RESTARTS   AGE
...
session-servlet-1-d8f2b   1/1       Running     0          14m

The pod provides the backing functionality exposed internally by the service, and externally by the route.

External Route

The route created by the new application template is incomplete, in that it does not specify the target port, and in that, it is not usable. It either has to be edited and fixed with oc edit or it can be dropped and recreated as shown below:

oc delete route session-servlet
oc expose service session-servlet --hostname=session-servlet.apps.openshift.novaordis.io --port=8080

More details about route operations are available here:

OpenShift Route Operations


Process

"Join" Projects

If the source repository pod runs in a collocated OpenShift project, and we want to use the internal DNS name, we need to join the projects.

oadm pod-network join-projects --to=cicd lab


oc new-app <openshift-project-template-name> \
 --param APPLICATION_NAME=<application-name> \
 --param SOURCE_REPOSITORY_URL=<git-url> \ 
 --param SOURCE_REPOSITORY_REF=master \
 --param CONTEXT_DIR=/
oc new-app eap64-basic-s2i \
 --param APPLICATION_NAME=tasks \
 --param SOURCE_REPOSITORY_URL=http://gogs.cicd.svc.cluster.local:3000/gogs/openshift-tasks-private \ 
 --param SOURCE_REPOSITORY_REF=master \
 --param CONTEXT_DIR=/

This command uses openshift project's "eap64-basic-s2i" template and creates:

  • a build configuration
  • an image stream
  • a deployment configuration
  • a route
  • a service
--> Deploying template "openshift/eap64-basic-s2i" to project lab

     Red Hat JBoss EAP 6.4 (no https)
     ---------
     Application template for EAP 6 applications built using S2I.

     A new EAP 6 based application has been created in your project.

     * With parameters:
        * Application Name=tasks
        * Custom http Route Hostname=
        * Git Repository URL=https://gogs.cicd.svc.cluster.local:3000/gogs/openshift-tasks-private
        * Git Reference=master
        * Context Directory=/
        * Queues=
        * Topics=
        * HornetQ Password=VvEf5H0S # generated
        * Github Webhook Secret=8Xk5LAnr # generated
        * Generic Webhook Secret=mn5K7NNA # generated
        * ImageStream Namespace=openshift
        * JGroups Cluster Password=r1Elwibf # generated
        * Deploy Exploded Archives=false
        * Maven mirror URL=
        * ARTIFACT_DIR=

--> Creating resources ...
    service "tasks" created
    route "tasks" created
    imagestream "tasks" created
    buildconfig "tasks" created
    deploymentconfig "tasks" created
--> Success
    Build scheduled, use 'oc logs -f bc/tasks' to track its progress.
    Run 'oc status' to view your app.

Because the Git repository is private and protected by username/password, the initial build attempt will fail:

oc logs -f build/tasks-1
...
error: build error: failed to fetch requested repository "http://gogs.cicd.svc.cluster.local:3000/gogs/openshift-tasks-private" with provided credentials

Add Source Repository Secrets

If the source repository is protected, we need to place credentials into the builder configuration, and the builder service account environment:

oc secrets new-basicauth gogs-basicauth --username=gogs --password=...
oc secrets link builder gogs-basicauth
oc set build-secret --source bc/tasks gogs-basicauth

Restart the Build

oc start-build tasks