Lightweight approach to create a custom image for deploying App Connect on OpenShift

 View Only
Sat August 15, 2020 05:43 AM

This article provides step by step instruction on how to create a custom image for App Connect on OpenShift without the overhead of creating and maintaining a separate image registry or build automation toolchain.

When deploying an App Connect integration on OpenShift, you have a choice between uploading the bar file to the App Connect dashboard and "baking it in" to a custom image. There are pros and cons of each of these. Uploading via the dashboard works out of the box and you do not need any additional infrastructure. If you create a baked image, you can automate the whole process and there is no need to use any UI.

Further to this, creating a baked image provides more control over customisation of the container. You could add multiple bar files, bar file overrides, user defined extension or third party libraries etc. The steps described below can be followed to achieve some of the benefits of creating a custom image by using only what is available out of the box with a App Connect installed on a plain vanilla OpenShift cluster.

The Solution



Out of the box, OpenShift provides some resources that can be configured to build images and store them in the cluster's own image registry. There are a few build strategies available and different options for triggering and for loading or pulling your code into those builds.

In the recipe below, we use the dockerStrategy and will trigger the build manually from command line.
View of the components and interactions


You begin with a bar file on your local workstation. You then start the build by uploading a bar file via the `oc` command line utility. On starting the build, OpenShift will create a `build` pod which pulls the ACE image from either IBM Entitled Registry or from Dockerhub. The result of the build is a new image, which extends the ACE image by adding the bar file. This new image is published to the image registry on the OpenShift cluster. Finally an IntegrationServer is created and each of its pods pulls the custom image from the ImageRegistry to run in its containers.

System diagram overlaid with details of the configuration resources required to define that system

To configure the system, we shall create the following:
  • Source Image We define an ImageStream with an ImageStreamTag with a reference to the App Connect base image.
  • Build Configuration An OpenShift BuildConfig stores the configuration (e.g Dockerfile) necessary to build the custom image.
  • Target Image We define another ImageStream containing an ImageStreamTag with a reference to the resulting custom image.



The Recipe

Prerequisites


  1. An OpenShift cluster
  2. OpenShift project created on that cluster that you have access to
  3. App Connect Operator installed on your cluster and available in your project
  4. oc Command line tool installed on your local workstation
  5. [Optional] App Connect Toolkit, App Connect Designer or access to and instance of App Connect service on IBM Cloud. Either one of these is needed to develop the integration and create the bar file. However, if you just want to follow the steps here to learn the process, you can use the sample HTTPEcho bar file 
  6. [Optional] An IBM Entitled Registry key or credentials to a private registry containing the base App Connect images. If you decide to use the developer image, then this is optional. The steps below explain what is needed to use the production images and how to configure the use of the credentials to pull that image. If you are using the developer edition images, then these steps can be simplified because no credentials are necessary. Release 11.0.0.9-r1 or later is assumed in these instructions although a similar approach may work on earlier releases.

Steps

1. Setup environment variables

Open a bash terminal and set the environment variable `OPEN_SHIFT_PROJECT` to the name of the OpenShift project that you created for [Prerequisite #2](#Prerequisites) and set `IBM_ENTITLEMENT_KEY` to the value of your IBM entitlement key. NOTE: it is not necessary to set `IBM_ENTITLEMENT_KEY` if you intend to use the developer edition from docker hub.

For example, in your terminal, run the following, replacing `my-project` with the name of your project and replacing <your ibm entitlement key> with your key for the IBM Entitled Registry:

export OPEN_SHIFT_PROJECT=my-project
export IBM_ENTITLEMENT_KEY=<your ibm entitlement key>


NOTE: If you are intending to use the developer edition image from docker hub, then you do not need to set IBM_ENTITLEMENT_KEY

2. Create the pull secret for the base image

If you are intending to use the developer edition image, then you may skip this step.

Run the following in the same bash terminal

oc create secret docker-registry ibm-entitlement-key --docker-username=cp --docker-password=${IBM_ENTITLEMENT_KEY} --docker-server=cp.icr.io

3. Tag the input image

Run the following in your bash terminal to create an ImageStream:

oc apply -f - <<EOF
apiVersion: image.openshift.io/v1
kind: ImageStream
metadata:
name: ace-server-prod
namespace: ${OPEN_SHIFT_PROJECT}
EOF

The name we give here can be anything that you chose but we will use `ace-server-prod` so that it is descriptive of its purpose.

If you are using the developer edition, then it would make sense to change the `name` of the `ImageStream` to `ace-server`

Run the following in your terminal to create an `ImageStreamTag`

oc tag -n ${OPEN_SHIFT_PROJECT} cp.icr.io/cp/appc/ace-server-prod@sha256:04bc376391a00ff1923d9122f93911b0f8e9700c7dda132f24676e383c0283cc ace-server-prod:latest-amd64

This will use release 11.0.0.9-r2 production images. Refer to the App Connect Knowledge Center for the tags for other releases of the production image and refer to https://hub.docker.com/r/ibmcom/ace-server/tags for the tags relating to the developer edition.

If this is successful, then it validates that you have performed step 2 correctly.
oc get ImageStreamTags -n ${OPEN_SHIFT_PROJECT}
Should return something like
NAME                           IMAGE REFERENCE                                                                                             UPDATED

ace-server-prod:latest-amd64 cp.icr.io/cp/appc/ace-server-prod@sha256:04bc376391a00ff1923d9122f93911b0f8e9700c7dda132f24676e383c0283cc 16 seconds ago

4. Define the output image stream

Run the following in your terminal to create an ImageStream

oc apply -f - <<EOF
apiVersion: image.openshift.io/v1
kind: ImageStream
metadata:
name: my-custom-ace-image
namespace: ${OPEN_SHIFT_PROJECT}
EOF

The name can be anything you chose. You will likely create a new ImageStream for every bar file that you intend to deploy so it would make sense to give a name that makes it easy to associate with the bar file and the purpose of that integration.

5. Specify the build configuration

Run the following in your terminal to create the BuildConfig object

oc apply -f - <<EOF
apiVersion: build.openshift.io/v1
kind: BuildConfig
metadata:
name: my-custom-ace-image
namespace: ${OPEN_SHIFT_PROJECT}
labels:
name: my-custom-ace-image
spec:
triggers: []
source:
type: dockerfile
dockerfile: |
FROM ace-server-prod:latest-amd64
COPY HTTPEcho.bar /home/aceuser/initial-config/bars/HTTPEcho.bar
strategy:
type: Docker
dockerStrategy:
from:
kind: ImageStreamTag
name: 'ace-server-prod:latest-amd64'
namespace: ${OPEN_SHIFT_PROJECT}
output:
to:
kind: ImageStreamTag
name: 'my-custom-ace-image:latest-amd64'
namespace: ${OPEN_SHIFT_PROJECT}
EOF


NOTE: If you are using developer edition and you changed the name of the ImageStream in step 3, then you need to update the yaml here accordingly.

6. Set the pull secret for the build

As with step 2, this is optional if you are using the developer edition images from Dockerhub.


oc set build-secret --pull bc/my-custom-ace-image ibm-entitlement-key


If you now inspect the BuildConfig that you created in step 5

oc get BuildConfig my-custom-ace-image -o yaml

You will notice that it has a spec.strategy.pullSecret field added. We could have included this in the yaml as part of step 5 but I added it as a separate step to make it more obvious to you and also because it is an optional step if you are using the developer edition from Docker Hub.


7. Start the build

oc start-build my-custom-ace-image --from-file ./HTTPEcho.bar


8. Inspect the result

Run the following command to see the status of the build

oc describe builds


You should see a pod created which runs the builds

oc get pod


Run the following to view the buid logs

oc logs <build-pod-name>


Run the following to see the ImageStreamTag

oc get imagestreamtags


You should see something like


NAME IMAGE REFERENCE UPDATED
ace:11.0.0.9-r1-amd64 image-registry.openshift-image-registry.svc:5000/my-project/ace@sha256:318a3874c8283a3a9ea4c6a7cbf7d0764fbd0e609f57e901cc66711b51c3dc86 3 minutes ago
my-custom-ace-image:latest-amd64 image-registry.openshift-image-registry.svc:5000/my-project/my-custom-ace-image@sha256:cc30ef236e8250b6529a3acfafe792c57537fe9426898f74eb3031eb248b52c9 1 minute ago


We see 2 ImageStreamTags. The one that we explicitly created in step 3 and the other is a result of running the build.

9. Create an integration server using that image



Edit the following by accepting the license and providing the license value. Then enter it into your terminal to create an integration server


oc apply -f - <<EOF
apiVersion: appconnect.ibm.com/v1beta1
kind: IntegrationServer
metadata:
name: my-integration-server
spec:
version: 11.0.0
pod:
containers:
runtime:
image: image-registry.openshift-image-registry.svc:5000/my-project/my-custom-ace-image:latest-amd64
license:
accept: true
license: L-AMYG-BQ2E4U
use: AppConnectEnterpriseProduction
barURL: ''
designerFlowsOperationMode: disabled
service:
endpointType: http
useCommonServices: false
replicas: 1
EOF

10. Invoke the API

curl http://$(oc get route my-integration-server-http -o jsonpath='{.status.ingress[0].host}')/Echo

11. Cleanup

oc delete IntegrationServer my-integration-server
oc delete build my-custom-ace-image-1
oc delete BuildConfig my-custom-ace-image
oc delete ImageStream my-custom-ace-image
oc delete ImageStream ace-server-prod
oc delete secret ibm-entitlement-key

Conclusion

We created 2 ImageStreams and in each of those we created an ImageStreamTag.  The BuildConfig defined how to take the image from one ImageStreamTag and create a new image and tag it as the 2nd ImageStreamTag. This resulting ImageStreamTag was then used to specify a custom image to use on an IntegrationServer operand.

​​


#AppConnect
#Openshift
#Integration
#custom-image

Comments

Thu April 01, 2021 10:06 AM

Hi John:

I get the following error in Step 9, please let me know how to get around it.

Error from server: error when creating "STDIN": admission webhook "validate.version.appconnect.ibm.com" denied the request: App version must be fully qualified if any custom images are specified. Check version is not channel version.
Thanks.

Mon November 02, 2020 06:25 AM

Hi John,
This is really helpful and very elaborate. Thanks for sharing it.

Thanks,
Santhosh