Skip to main content

OpenShift

Red Hat® OpenShift® is an enterprise-ready Kubernetes container platform with full-stack automated operations to manage hybrid cloud and multicloud deployments.

Repository

The IBM Application Gateway (IAG) image is available from the Docker Hub repository: ibmcom/ibm-application-gateway.

Configuration

There are two mechanisms by which the IAG container can read configuration information:

  1. From YAML files contained in the '/var/iag/config' directory of the container;
  2. From a Custom Object which has been created and is available in the OpenShift environment.

File based configuration

The configuration for the container can be supplied as one or more yaml files, along with other potential supporting files (e.g. PEM certificate files). When the container first starts it will apply the configuration found within the local '/var/iag/config' directory. As such the configuration for the container will need to be placed in this directory before the container is started. This can be achieved in a number of ways, as outlined below.

ConfigMap

The configuration information can be copied into an OpenShift ConfigMap. A volume mount can then be used to mount this ConfigMap to the '/var/iag/config' directory in the pod. Information on creating and managing an OpenShift ConfigMap can be found at: https://docs.openshift.com/container-platform/3.11/dev_guide/configmaps.html.

If, for example, the configuration information is contained in a file called iag-config.yaml the following command can be used to create a ConfigMap which contains this file:

oc create configmap iag-config --from-file=iag-config.yml

OpenShift Build

The configuration can be built into a new Docker image which is based on the IAG image. Information on OpenShift builds can be obtained from the official OpenShift documentation: https://docs.openshift.com/container-platform/3.11/dev_guide/builds/index.html.

The following steps should be completed to define and create a custom build which contains the configuration information:

  1. Create the build definition. An example build definition (iag-build.yaml) is provided below:
kind: "BuildConfig"
apiVersion: "v1"

metadata:
  # The name which will be given to our build.
  name: "iag-sample-build"
  
spec:
  runPolicy: "Serial"
  
  # The source is obtained from the ibm-application-gateway-resources GitHub 
  # repository.  It simply contains a Dockerfile which will be used to create 
  # a new image from the IAG image, and will embed a sample configuration
  # within this image.
  source:
    git:
      uri: "https://github.com/IBM-Security/ibm-application-gateway-resources"
    contextDir: "openshift/build-sample"
    
  # Create the new image using the 'docker build' command.
  strategy:
    dockerStrategy:
      forcePull: false
      
  # The built image will pushed be to the iag-sample-build stream
  # in the OpenShift integrated registry.
  output:
    to:
      kind: "ImageStreamTag"
      name: "iag-sample-build:latest"

The build definition can then be created using the following command:

oc create -f iag-build.yaml
  1. Create the image stream which will hold the build:
oc create imagestream iag-sample-build
  1. Allow the image stream to be referenced during deployment:
oc set image-lookup iag-sample-build
  1. Start the build:
oc start-build iag-sample-build

Once the build has completed a new image will be available in the OpenShift integrated registry. This build can be referenced within a deployment using the 'iag-sample-build:latest' image name.

Custom Object based configuration

The IAG container is also able to retrieve the configuration information from a Custom Object. This Custom Object must be based on an IAG specific Custom Resource Definition (CRD). Information on how to create and manage a CRD can be found at: https://docs.openshift.com/container-platform/3.11/admin_guide/custom_resource_definitions.html.

Custom Resource Definition

The following YAML file (iag-crd.yaml) contains the CRD for the IAG image.

apiVersion: apiextensions.k8s.io/v1beta1
kind: CustomResourceDefinition

metadata:

  #
  # The full identifying name for this custom resource definition, 
  # constructed from the 'plural' and 'group' data.
  #

  name: ibm-application-gateway.security.ibm.com 

spec:
  #
  # The group name and version information to be used in the Rest API.
  #

  group: security.ibm.com 
  version: v1 

  #
  # This custom resource definition is restricted to the current Kubernetes
  # namespace.
  #

  scope: Namespaced

  #
  # The names associated with this custom resource definition.
  #
  
  names:
    plural: ibm-application-gateway
    kind: ibm-application-gateway

  #
  # The validation rules for the data contained with a custom object
  # of this type.  Please note that to keep things simple this
  # only currently includes the top level nodes for the IAG configuration YAML.
  #

  validation:
    openAPIV3Schema:
      type: object
      properties:
        spec:
          type: object
          properties:
            advanced:
              type: object
            resource_servers:
              type: array
            authorization:
              type: object
            identity:
              type: object
            logging:
              type: object
            server:
              type: object
            version:
              type: string

Please note:

  • For the sake of brevity and clarity the schema only includes the definition of the top level configuration nodes. A CRD which contains a full schema definition is available from the ibm-application-gateway-resources GitHub repository.
  • The IAG CRD must have the following properties:
Property Value
name ibm-application-gateway.security.ibm.com
version v1
kind ibm-application-gateway
  • Only cluster admins can create CRDs. This means that the user who is creating the CRD must have the 'cluster-admin' role. The following command shows how to add the 'cluster-admin' role to the 'my-admin' user:
oc adm policy add-cluster-role-to-user cluster-admin my-admin --as=system:admin

The following command can then be used to create the CRD from this file:

oc create -f iag-crd.yaml

Custom Object

Once the CRD has been created it is then possible to create a Custom Object which embeds the configuration for an IAG instance.

In order to be able to create a custom object the user must first be given permission to create custom objects for this CRD. The following yaml file (iag-crd-role.yaml) will define two new roles. One which will allow custom objects to be managed, and another which will allow read-only access to a created custom object:

kind: ClusterRole
apiVersion: rbac.authorization.k8s.io/v1 

metadata:
  name: aggregate-ibm-app-gateway-crd-edit 
  labels:
    rbac.authorization.k8s.io/aggregate-to-admin: "true" 
    rbac.authorization.k8s.io/aggregate-to-edit: "true" 
    
rules:
- apiGroups: ["security.ibm.com"] 
  resources: ["ibm-application-gateway"] 
  verbs: 
    - "get"
    - "list"
    - "watch"
    - "create"
    - "update"
    - "patch"
    - "delete"
    - "deletecollection" 
  
---
kind: ClusterRole
apiVersion: rbac.authorization.k8s.io/v1

metadata:
  name: aggregate-ibm-app-gateway-crd-view 
  labels:
    rbac.authorization.k8s.io/aggregate-to-view: "true" 
rules:
- apiGroups: ["security.ibm.com"] 
  resources: ["ibm-application-gateway"] 
  verbs:
    - "get"
    - "list"
    - "watch"

The 'aggregate-ibm-app-gateway-crd-edit' role should then be added to the user who will be creating and managing the custom object, for example:

oc adm policy add-cluster-role-to-user aggregate-ibm-app-gateway-crd-edit my-user --as=system:admin

An example Custom Object definition is illustrated in the following yaml file (iag-co.yaml):

apiVersion: "security.ibm.com/v1"
kind: ibm-application-gateway

metadata:
  #
  # The identifying name for this custom object.
  #
  name: iag-configuration

spec:
  #
  # The IAG configuration data.
  #
  version: 20.09
  
  server:
    ssl:
      front_end:
        certificate: 
          - B64:LS0tLS1CRUdJTiBQUklWQVRFIEtFWS0tLS0tCk1.....
  identity:
    oidc:
      discovery_endpoint: "https://ibm-app-gw.ice.ibmcloud.com/oidc/endpoint/default/.well-known/openid-configuration"
      client_id: "300141b6-690b-4e4e-862d-2c96da2bb1ba"
      client_secret: "wPP8rM8N0d"

Please note:

  • The YAML configuration for the IAG container resides at the 'spec' YAML node. At this point it will mirror the standard IAG configuration.
  • A Custom Object cannot reference external files. This means that if the IAG configuration relies on an external file (e.g. a certificate file) it should be base-64 encoded and then added directly to the Custom Object.
  • The Custom Object must have the following properties:
Property Value
apiVersion security.ibm.com/v1
kind ibm-application-gateway

The following command can be used to create the Custom Object from this file:

oc create -f iag-co.yaml

Custom Object Identification

The IAG container, when starting, will look for the name of a Custom Object in the 'CONFIG_CUSTOM_OBJECT_NAME' environment variable. If this environment variable is defined the IAG container will attempt to load the configuration from the corresponding Custom Object, otherwise it will load the configuration from the files contained within the '/var/iag/config' directory on the file system.

The following YAML snippet illustrates how to reference the 'iag-configuration' Custom Object when deploying an IAG container:

apiVersion: apps/v1
kind: Deployment

spec:
  ...

  template: 
    ...

    spec:
      ...

      containers:
        - name: iag

          ...
          
          # Environment definition - used to set the Custom Object which
          # holds the configuration information.
          env:
            - name: CONFIG_CUSTOM_OBJECT_NAME
              value: iag-configuration   
              
          ...

Service Accounts

Service accounts can be used to provide an identity for processes that run in a Pod. Information on the usage of service accounts can be found in the official Kubernetes documentation: https://docs.openshift.com/container-platform/3.11/dev_guide/service_accounts.html.

In the example that is provided within this document, the deployment descriptor uses the ‘iag’ service account. The 'oc' command can be used to create the ‘iag’ service account:

oc create serviceaccount iag

If you are using a Custom Object to pass configuration information to the container the service account must also be granted read access to the Custom Object. This can be achieved by adding the 'aggregate-ibm-app-gateway-crd-view' role to the service account user, for example:

oc policy add-role-to-user aggregate-ibm-app-gateway-crd-view -z iag

Language

In order to display the IAG error messages in a language other than English the 'LANG' environment variable should be set to one of the following:

Value Language
pt Brazilian Portuguese
cs Czech
zh_CN Chinese (Simplified)
zh_TW Chinese (Traditional)
C English
fr French
de German
hu Hungarian
it Italian
ja Japanese
ko Korean
pl Polish
es Spanish
ru Russian

Template

An OpenShift template describes a set of objects that can be parameterized and processed to produce a list of objects for creation by the OpenShift Container Platform. A template can be used to define how to deploy an instance of the IAG container. Further information on templates can be found in the official OpenShift documentation: https://docs.openshift.com/container-platform/3.11/dev_guide/templates.html.

The following YAML file (iag-template.yaml) depicts a template definition for the IAG:

apiVersion: v1
kind: Template

# Metadata associated with this template (for example, the template name)
metadata:
  name: ibm-app-gateway
  annotations:
    openshift.io/display-name: IBM Application Gateway
    iconClass: icon-sso
    description: >-
      The IBM Application Gateway (IAG) provides a containerized secure Web 
      Reverse proxy which is designed to sit in front of your application, 
      seamlessly adding authentication and authorization protection to your 
      application.

objects:

# Our deployment definition, which is used to describe the IAG container.
- apiVersion: apps/v1
  kind: Deployment

  # Matadata associated with the container.
  metadata:
    annotations:
      deployment.kubernetes.io/revision: "1"
    generation: 1
    labels:
      app: ${APP_NAME}
    name: ${APP_NAME}

  spec:
    replicas: ${REPLICAS}
    progressDeadlineSeconds: 600
    revisionHistoryLimit: 10

    selector:
      matchLabels:
        app: ${APP_NAME}

    # The strategy used to replace old Pods by new ones.
    strategy:
      rollingUpdate:
        maxSurge: 1
        maxUnavailable: 1
      type: RollingUpdate

    # Details associated with the creation of an IAG container.
    template:
      metadata:
        labels:
          app: ${APP_NAME}
          
      spec:
        # The name of the service account which has the required
        # capabilities enabled for the IAG container.
        serviceAccountName: ${SERVICE_ACCOUNT}

        affinity:
          podAntiAffinity:
            preferredDuringSchedulingIgnoredDuringExecution:
            - weight: 100
              podAffinityTerm:
                labelSelector:
                  matchExpressions:
                  - key: app
                    operator: In
                    values:
                    - ${APP_NAME}
                topologyKey: kubernetes.io/hostname
                
        containers:
        - name: ${APP_NAME}

          env:
          # The language to be used for console error messages.
          - name: LANG
            value: ${LANGUAGE}

          #### Start of Custom Object section.
          # The name of the custom object which holds our configuration
          # information.
          # - name: CONFIG_CUSTOM_OBJECT_NAME
          #   value: ${CUSTOM_OBJECT}
          #### End of Custom Object section.
          
          # The fully qualified name of the IAG image.
          image: docker.io/ibmcom/ibm-application-gateway:${IAG_VERSION}

          # The ports on which the IAG container will be listening for
          # requests.
          ports:
          - containerPort: 8443
            protocol: TCP

          resources: {}

          terminationMessagePath: /dev/termination-log
          terminationMessagePolicy: File

          # The liveness and readiness probes are used by Kubernetes 
          # to obtain the health of the container.  Our health is 
          # governed by the ability to connect to the IAG server.
          livenessProbe:
            exec:
              command:
              - /sbin/health_check.sh
            initialDelaySeconds: 120
            periodSeconds: 10
          readinessProbe:
            exec:
              command:
              - /sbin/health_check.sh
            initialDelaySeconds: 5
            periodSeconds: 10

          #### Start of ConfigMap section.
          # The volume which contains the IAG configuration data.
          volumeMounts:
          - mountPath: /var/iag/config
            name: ${APP_NAME}-config
          #### End of ConfigMap section.

        #### Start of ConfigMap section.
        # The config map which contains the IAG configuration data.
        volumes:
        - name: ${APP_NAME}-config
          configMap:
            name: ${CONFIG_MAP}
        #### End of ConfigMap section.

        # Sundry spec configuration data.
        dnsPolicy: ClusterFirst
        restartPolicy: Always
        schedulerName: default-scheduler
        terminationGracePeriodSeconds: 30

# The route which is used to access the IAG service.  The route will be based
# on the supplied DNS name.
- apiVersion: v1
  kind: Route

  metadata:
    name: ${APP_NAME}
    labels:
      app: ${APP_NAME}

  spec:
    host: ${DNS_NAME}
    port:
      targetPort: ${APP_NAME}
    tls:
      insecureEdgeTerminationPolicy: Redirect
      termination: passthrough
    to:
      kind: Service
      name: ${APP_NAME}
      weight: 100
    wildcardPolicy: None

# The service which is used to access the runtime interface of the IAG pod.
- apiVersion: v1
  kind: Service

  metadata:
    name: ${APP_NAME}
    labels:
      app: ${APP_NAME}

  spec:
    externalTrafficPolicy: Cluster
    ports:
    - name: ${APP_NAME}
      port: 443
      protocol: TCP
      targetPort: 8443
    selector:
      app: ${APP_NAME}
    sessionAffinity: ClientIP
    sessionAffinityConfig:
      clientIP:
        timeoutSeconds: 10800
    type: NodePort
  status:
    loadBalancer: {}

# Configuration parameters associated with this template.
parameters:
  - description: The name which will be given to the IBM Application Gateway application.
    name: APP_NAME
    value: iag
  - description: The IAG version/tag which is to be deployed.
    name: IAG_VERSION
    value: "20.09"
  - description: The fully qualified DNS name which will be used for routing.
    name: DNS_NAME
    value: ibm-app-gw.ibm.com
  - description: The service account which will be used when running the pod.
    name: SERVICE_ACCOUNT
    value: iag
  - description: The language in which the console error messages will be displayed.
    name: LANG
    value: C
  - description: The number of replicas of the application to create.
    name: REPLICAS
    value: "1"
  #### Start of ConfigMap section.
  - description: The ConfigMap which holds the configuration of the container.
    name: CONFIG_MAP
    value: iag-config
  #### End of ConfigMap section.
  #### Start of Custom Object section.
  #  - description: The name of the Custom Object which holds the configuration of the container.
  #  name: CUSTOM_OBJECT
  #  value: iag-config
  #### End of Custom Object section.

Please note:

  • The template currently assumes that a ConfigMap will be used to hold the configuration information.
  • If a Custom Object will be used to hold the configuration information:

    • Uncomment the 'Custom Object' sections;
    • Remove the 'ConfigMap' sections.
  • If the configuration is built into a new Docker image:

    • Remove the 'ConfigMap' and 'Custom Object' sections;
    • Replace the IAG image name with the image name of the custom build.

The following command can be used to create the template from this file:

oc create -f iag-template.yaml

Deployment

An instance of the IAG can be deployed using:

  1. The IAG template which has previously been created. Instructions on how to deploy using the template can be found in the official OpenShift documentation: https://docs.openshift.com/container-platform/3.11/dev_guide/templates.html#creating-from-templates-using-the-web-console;
  2. The 'oc create' command, referencing a standard Kubernetes deployment and service descriptor. An example deployment and service descriptor is available in the Kubernetes deployment page of the IAG documentation.

Supported Tags

Tag Purpose
YY.MM A particular release, of the format: {year}.{month}. For example 19.12.