Jenkins Agents

Overview

OKD provides three images suitable for use as Jenkins agents: the Base, Maven, and Node.js images.

The first is a base image for Jenkins agents:

  • It pulls in both the required tools (headless Java, the Jenkins JNLP client) and the useful ones (including git, tar, zip, and nss among others).

  • It establishes the JNLP agent as the entrypoint.

  • It includes the oc client tooling for invoking command line operations from within Jenkins jobs.

  • It provides Dockerfiles for both CentOS and RHEL images.

Two more images that extend the base image are also provided:

The Maven and Node.js Jenkins agent images provide Dockerfiles for both CentOS and RHEL that you can reference when building new agent images. Also note the contrib and contrib/bin subdirectories. They allow for the insertion of configuration files and executable scripts for your image.

Use and extend an appropriate agent image version for the version of OKD that you are using. If the oc client version embedded in the agent image is not compatible with the OKD version, unexpected behavior may result.

Images

The OKD Jenkins agent images come in two flavors:

RHEL 7 Based Images

RHEL 7 images are available through the Red Hat Registry:

  1. $ docker pull registry.redhat.io/openshift3/jenkins-slave-base-rhel7
  2. $ docker pull registry.redhat.io/openshift3/jenkins-slave-maven-rhel7
  3. $ docker pull registry.redhat.io/openshift3/jenkins-slave-nodejs-rhel7
  4. $ docker pull registry.redhat.io/openshift3/jenkins-agent-maven-35-rhel7
  5. $ docker pull registry.redhat.io/openshift3/jenkins-agent-nodejs-10-rhel7
  6. $ docker pull registry.redhat.io/openshift3/jenkins-agent-nodejs-12-rhel7

CentOS 7 Based Images

These images are available on Docker Hub:

  1. $ docker pull openshift/jenkins-slave-base-centos7
  2. $ docker pull openshift/jenkins-slave-maven-centos7
  3. $ docker pull openshift/jenkins-slave-nodejs-centos7
  4. $ docker pull openshift/jenkins-agent-maven-35-centos7
  5. $ docker pull openshift/jenkins-agent-nodejs-10-centos7
  6. $ docker pull openshift/jenkins-agent-nodejs-12-centos7

To use these images, you can either access them directly from these registries or push them into your OKD container image registry.

Configuration and Customization

Environment Variables

Each Jenkins agent container can be configured with the following environment variables:

  • OPENSHIFT_JENKINS_JVM_ARCH

    Set to x86_64 or i386 to override the JVM used to host the Jenkins agent. For memory efficiency, by default the Jenkins agent images dynamically use a 32-bit JVM if running in a container with a memory limit under 2GiB.

  • JAVA_MAX_HEAP_PARAM
    CONTAINER_HEAP_PERCENT (default: 0.5, i.e. 50%)
    JNLP_MAX_HEAP_UPPER_BOUND_MB

    These values control the maximum heap size of the Jenkins agent JVM. If JAVA_MAX_HEAP_PARAM is set (example setting: -Xmx512m), its value takes precedence. Otherwise, the maximum heap size is dynamically calculated as CONTAINER_HEAP_PERCENT% (example setting: 0.5, i.e. 50%) of the container memory limit, optionally capped at JNLP_MAX_HEAP_UPPER_BOUND_MB MiB (example setting: 512).

    By default, the maximum heap size of the Jenkins agent JVM is set to 50% of the container memory limit with no cap.

  • JAVA_INITIAL_HEAP_PARAM
    CONTAINER_INITIAL_PERCENT

    These values control the initial heap size of the Jenkins agent JVM. If JAVA_INITIAL_HEAP_PARAM is set (example setting: -Xms32m), its value takes precedence. Otherwise, the initial heap size may be dynamically calculated as CONTAINER_INITIAL_PERCENT% (example setting: 0.1, i.e. 10%) of the dynamically calculated maximum heap size.

    By default, the initial heap sizing is left to the JVM.

  • CONTAINER_CORE_LIMIT

    If set, specifies an integer number of cores used for sizing numbers of internal JVM threads. Example setting: 2.

  • JAVA_TOOL_OPTIONS (default: -XX:+UnlockExperimentalVMOptions -XX:+UseCGroupMemoryLimitForHeap -Dsun.zip.disableMemoryMapping=true)

    Specifies options to be heeded by all JVMs running in this container. It is not recommended to override this.

  • JAVA_GC_OPTS (default: -XX:+UseParallelGC -XX:MinHeapFreeRatio=5 -XX:MaxHeapFreeRatio=10 -XX:GCTimeRatio=4 -XX:AdaptiveSizePolicyWeight=90)

    Specifies Jenkins agent JVM garbage collection parameters. It is not recommended to override this.

  • JNLP_JAVA_OVERRIDES

    Specifies additional options for the Jenkins agent JVM. These options are appended to all other options, including the Java options above, and may be used to override any of them if necessary. Separate each additional option with a space; if any option contains space characters, escape them with a backslash. Example settings: -Dfoo -Dbar; -Dfoo=first\ value -Dbar=second\ value.

Usage

Memory Requirements

A JVM is used in all Jenkins agents to host the Jenkins JNLP agent, as well as to run any Java applications (e.g. javac, Maven or Gradle). See Sizing OpenJDK on OKD for background information on tuning the JVM used by Jenkins agents.

For memory efficiency, by default the Jenkins image dynamically uses a 32-bit JVM if running in a container with a memory limit under 2GiB. This behavior can be overridden by the OPENSHIFT_JENKINS_JVM_ARCH environment variable. The JVM choice applies by default both for the Jenkins JNLP agent as well as for any other Java processes within the agent container.

By default the Jenkins JNLP agent JVM uses 50% of the container memory limit for its heap. This value can be modified by the CONTAINER_HEAP_PERCENT environment variable. It can also be capped at an upper limit or overridden entirely. See Environment Variables for more details.

Consider that by default any/all other processes executed in the Jenkins agent container, e.g. shell scripts or oc commands run from pipelines, may not be able to use more than the remaining 50% memory limit without provoking an OOM kill.

By default, each further JVM process run in a Jenkins agent container will use up to 25% of the container memory limit for their heap. It may be necessary to tune this for many build workloads. See Sizing OpenJDK on OKD for more information.

See the Jenkins documentation for information on specifying the memory request and limit of a Jenkins agent container.

Gradle builds

Hosting Gradle builds in the a Jenkins agent on OpenShift presents additional complications, not least because in addition to the Jenkins JNLP agent and Gradle JVMs, Gradle spawns a third JVM to run tests, if these are specified.

See Sizing OpenJDK on OKD for background information on tuning JVMs on OpenShift.

The following settings are suggested as a starting point for running Gradle builds in a memory constrained Jenkins agent on OpenShift. Settings may be relaxed subsequently as required.

  • Ensure the long-lived gradle daemon is disabled by adding org.gradle.daemon=false to the gradle.properties file.

  • Disable parallel build execution by ensuring org.gradle.parallel=true is not set in the gradle.properties file and that --parallel is not set as a command line argument.

  • Set java { options.fork = false } in the build.gradle file to prevent Java compilations running out-of-process.

  • Disable multiple additional test processes by ensuring test { maxParallelForks = 1 } is set in the build.gradle file.

  • Override the gradle JVM memory parameters according to Sizing OpenJDK on OKD by the GRADLE_OPTS, JAVA_OPTS or JAVA_TOOL_OPTIONS environment variables.

  • Set the maximum heap size and JVM arguments for any Gradle test JVM by the maxHeapSize and jvmArgs settings in build.gradle, or though the -Dorg.gradle.jvmargs command line argument.

Agent Pod Retention

Jenkins agent pods (also known as slave pods) are deleted by default after the build completes or is aborted. This behavior can be changed by the Kubernetes plug-in Pod Retention setting. Pod retention can be set for all Jenkins builds, with overrides for each pod template. The following behaviors are supported:

  • Always keeps the build pod regardless of build result.

  • Default uses the plug-in value (pod template only).

  • Never always deletes the pod.

  • On Failure keeps the pod if it fails during the build.

You can override pod retention in the pipeline Jenkinsfile:

  1. podTemplate(label: "mypod",
  2. cloud: "openshift",
  3. inheritFrom: "maven",
  4. podRetention: onFailure(), (1)
  5. containers: [
  6. ...
  7. ]) {
  8. node("mypod") {
  9. ...
  10. }
  11. }
1Allowed values for podRetention are never(), onFailure(), always(), and default().

Pods that are kept may continue to run and count against resource quotas.

For more information, see the Kubernetes plug-in documentation.