Jib containers in the API Mediation Layer

Jakub Balhar
Geek Culture
Published in
4 min readJun 28, 2021

--

In the last month we introduced GitHub Actions as a infrastructure of the choice for Zowe API Mediation Layer. The main reasons were stability and ease of use of the GitHub Actions. With the last improvements around the High Availability (HA) within Zowe we needed to have a setup that is similar to the HA setup within Zowe.

https://www.shadowandy.net/2015/05/docker-a-highly-portable-and-lightweight-software-container.htm

The GitHub actions provide a neat option to start services upfront of the actual run of the pipeline via services block. Below is the excerpt from the HA setup of services. The full setup is available here: https://github.com/zowe/api-layer/blob/master/.github/workflows/containers.yml

services:
nginx:
image: nginx:latest
ports:
- 443:443
volumes:
- /$(pwd)/docker/nginx/load-balancer.conf:/etc/nginx
- /$(pwd)/keystore/docker:/etc/ssl/private
gateway-service:
image: ghcr.io/balhar-jakub/gateway-service:${{ github.event.pull_request.number || 'latest' }}
env:
APIML_SERVICE_DISCOVERYSERVICEURLS: https://discovery-service:10011/eureka/,https://discovery-service-2:10011/eureka/
gateway-service-2:
image: ghcr.io/balhar-jakub/gateway-service:${{ github.event.pull_request.number || 'latest' }}
env:
APIML_SERVICE_HOSTNAME: gateway-service-2
SERVER_INTERNAL_PORT: 10027
APIML_SERVICE_DISCOVERYSERVICEURLS: https://discovery-service:10011/eureka/,https://discovery-service-2:10011/eureka/

To be able to leverage this mechanism we needed to be able to build the Docker containers from our services. We selected jib as the method of choice. The tooling and integration with Gradle and Java applications is quite good and the layered build approach is very effective. It also helps that Docker itself isn’t required to build the artifacts.

There were a few problems that we needed to resolve during the way:

  • Get the right container for the specific Pull Request (PR) run
    In the last version we depend on the number of the pull request to be used as tag for the specific container to be used in the PR.
  • Allow local debugging of the containerized applications?
    jib.container.jvmFlags = project.hasProperty(“zowe.docker.debug”) ? [‘-agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=’ + debugPort]: []
    Based on the zowe.docker.debug parameter we can provide the JVM arguments necessary for the remote debugging. Once provided it’s possible to debug remotely via debug port.
  • Configure applications within containers
    This is combination of externalized configuration in docker specific .yml file and the environment variables and depending on Spring to properly understand them.

Updated app arguments: jib.container.args = [‘ — spring.config.additional-location=file:/docker/’ + componentName + ‘.yml’, ‘ — spring.profiles.include=dev,debug’]

Example of environment variable: APIML_SERVICE_DISCOVERYSERVICEURLS: https://discovery-service:10011/eureka/,https://discovery-service-2:10011/eureka/

How do you use the current version locally?

You need Docker installed on the machine, where you want to run the full setup of the API Mediation Layer stored in the docker container.

Build the containers for local usage. This command builds the current version of the services and packages them to the containers stored in local docker registry.

./gradlew jibDockerBuild -Pzowe.docker.debug=true

If you want to be able to properly interact with the containers from local machine, you will need to update hosts file. In Windows machine it is stored in C:\Windows\System32\drivers\etc\hosts. In Linux and MacOS based usually in /etc/hosts. Add following lines:

127.0.0.1 caching-service
127.0.0.1 gateway-service
127.0.0.1 discovery-service
127.0.0.1 api-catalog-services
127.0.0.1 metrics-service
127.0.0.1 mock-zosmf
127.0.0.1 discoverable-client

Note: The containerized API Mediation Layer runs in its own network under hostnames representing the names of the containers. Within the network the containers communicate with each other via URLs such as: https://gateway-service:10010/ The changes to the hosts files allows correct run of the Integration tests. If you want just to run the containers, the changes to the hosts aren’t necessary the containers will be available on https://localhost:{relevantPort}

Create the network that will be used by the containers via:

docker network create api-layer-full

Create the actual containers based on the created images:

docker create --name caching-service --network api-layer-full -p 10016:10016 -p 5126:5126 ghcr.io/zowe/caching-service
docker create --name gateway-service --network api-layer-full -p 10010:10010 -p 10017:10017 -p 5120:5120 ghcr.io/zowe/gateway-service
docker create --name mock-zosmf --network api-layer-full -p 10013:10013 -p 5123:5123 ghcr.io/zowe/mock-zosmf
docker create --name discovery-service --network api-layer-full -p 10011:10011 -p 5121:5121 ghcr.io/zowe/discovery-service
docker create --name discoverable-client --network api-layer-full -p 10012:10012 -p 5122:5122 ghcr.io/zowe/discoverable-client
docker create --name api-catalog-services --network api-layer-full -p 10014:10014 -p 5124:5124 ghcr.io/zowe/caching-service

Run the containers:

docker start mock-zosmf
docker start discovery-service
docker start gateway-service
docker start api-catalog-service
docker start caching-service
docker start discoverable-client

At this moment you should be able to connect to the containers from the host machine via https://localhost:10010, https://localhost:10011, … or if you updated your hosts file via https://gateway-service:10010, https://discovery-service:10011/

Intellij Idea Setup

In both version of Idea (Community and Ultimate) it’s possible to debug the containers remotely. The Run Configuration is labeled as Remote JVM Debug. Valid setup for mock-zosmf container is shown below. The important part is the port used to connect.

mock-zosmf debug setup

Ultimate simplification

Within Ultimate edition of Idea it’s possible to integrate well with Docker. This allows for run configurations to start the docker containers as well as depend on the run of the jibDocker task before starting container.

Visual example of docker configuration for mock-zosmf service
Xml example of configuration for run of specific service

--

--

Jakub Balhar
Geek Culture

I always try to find answers to the complex questions. Now exploring the world of Mainframes in the Broadcom inc.