User Tools

Site Tools


services:downstream_ci

RDU3 Jenkins

Overview

The RDU3 Jenkins deployment is the new Jenkins environment running in the RDU3 OpenShift cluster.

Jenkins URL:

https://jenkins.apps.prod-scale-spoke1-dc-rdu3.itup.redhat.com

OpenShift cluster:

prod-scale-spoke1-dc-rdu3.itup.redhat.com

OpenShift Console:

https://console-openshift-console.apps.prod-scale-spoke1-dc-rdu3.itup.redhat.com

Production OpenShift project:

ceph-downstream-tenant–pipeline

Architecture

The Jenkins environment consists of:

  • Jenkins controller running in OpenShift
  • OpenShift Virtualization (KubeVirt/CNV) VMs used as Jenkins build agents
  • RHEL 9 builder VMs
  • On-demand Jenkins agent provisioning
  • Jenkins agents connect back to the controller using WebSocket

Unlike a traditional Kubernetes Jenkins deployment, builds are not executed inside Kubernetes pods. Dedicated KubeVirt VMs are created on demand and used as Jenkins agents.

This provides Jenkins jobs with a full RHEL virtual machine while still allowing the builders to be dynamically created and removed as required.

Jenkins Configuration Repository

The Jenkins configuration is maintained in the following Git repository:

git@gitlab.cee.redhat.com:ccit/jenkins-csb-customers/storage-casc-ceph-downstream.git

During the RDU3 migration, the new Jenkins instance is using the following branch:

rdu3-migration

This is a temporary migration branch used for the RDU3 Jenkins configuration while the existing Jenkins environment is still in use.

Changes specific to the new RDU3 Jenkins deployment should currently be made against the rdu3-migration branch.

Once the migration to the RDU3 Jenkins instance is complete, the temporary migration branch can be retired and the normal production configuration workflow can be used.

Jenkins Agents

The Jenkins build agents are RHEL 9 virtual machines running through OpenShift Virtualization.

Example agent types include:

  • rhel9medium
  • rhel9large

These builders are not expected to be permanently running Jenkins nodes. They are provisioned on demand when Jenkins needs capacity to execute a job.

Each VM is configured as a Jenkins agent and connects back to:

https://jenkins.apps.prod-scale-spoke1-dc-rdu3.itup.redhat.com

The Jenkins agent uses WebSocket connectivity rather than the traditional JNLP TCP agent port.

On-Demand Builder Lifecycle

The RDU3 Jenkins builders are dynamically created using OpenShift Virtualization.

Instead of maintaining a large pool of permanently running builder VMs, Jenkins creates builders when jobs require them and removes the builders when they are no longer needed.

The lifecycle of a builder is:

  1. A Jenkins job is submitted and requests a particular builder type/label.
  2. Jenkins checks whether an appropriate agent is already available.
  3. If no suitable agent is available, Jenkins requests a new builder.
  4. A new KubeVirt VirtualMachine is created in the OpenShift tenant.
  5. OpenShift Virtualization starts the VM and creates the corresponding VirtualMachineInstance (VMI).
  6. The RHEL 9 VM boots.
  7. The VM is provisioned with the required Jenkins agent configuration.
  8. The Jenkins agent connects back to the Jenkins controller using WebSocket.
  9. Jenkins detects the new agent and marks it online.
  10. The queued Jenkins job is assigned to the new builder.
  11. The job runs inside the VM.
  12. After the builder is no longer required, Jenkins removes the agent.
  13. The associated KubeVirt VM is destroyed, releasing the CPU and memory resources back to the OpenShift tenant.

This makes the builders effectively disposable.

A builder exists only for the period in which Jenkins requires the capacity. A later job can cause a new clean VM to be created instead of depending on the state left behind by an older build.

Builder Creation

When Jenkins determines that additional capacity is required, it requests a new builder based on the configuration for the requested node type.

For example, a job requiring a rhel9large builder causes Jenkins to request a VM matching the rhel9large configuration.

OpenShift Virtualization then creates the VM and allocates the configured resources, including:

  • CPU
  • Memory
  • Storage
  • Network interfaces

The VM boots from the configured RHEL 9 image.

As part of provisioning, the VM is configured with the Jenkins agent information required to connect back to the controller.

Jenkins Agent Registration

Inside the VM, the Jenkins agent is started using agent.jar.

An example of the agent command is:

java -jar /home/jenkins-build/agent.jar \
  -url https://jenkins.apps.prod-scale-spoke1-dc-rdu3.itup.redhat.com \
  -secret @/etc/jenkins-agent/secret \
  -name <node-name> \
  -webSocket \
  -workDir /home/jenkins-build

The important part of the RDU3 configuration is:

-webSocket

The agent establishes an outbound WebSocket connection to the Jenkins controller over HTTPS.

Once the connection is established, Jenkins marks the node online and can schedule the waiting job onto it.

Running the Build

Once the builder is online, Jenkins assigns the queued job to the VM.

From the Jenkins job's perspective, the VM behaves like a regular Jenkins node.

The build has access to the RHEL environment and any tools installed as part of the builder provisioning process.

Builder Destruction

The builders are disposable and are not intended to remain running indefinitely after their work has completed.

After Jenkins determines that the dynamically created agent is no longer required, the agent is removed and the associated KubeVirt VM is deleted.

Deleting the VM also releases the compute resources that were allocated to it.

This is particularly important in RDU3 because the OpenShift tenants have resource limits. Dynamically removing unused builders prevents idle Jenkins nodes from continuously consuming the tenant's CPU and memory allocation.

Jenkins / KubeVirt Integration

The Jenkins integration uses customized logic for managing the KubeVirt builder nodes.

The Sorter Jenkins plugin contains Java customizations used as part of the KubeVirt Jenkins agent implementation.

The integration allows Jenkins to dynamically request KubeVirt builder VMs when jobs require additional capacity and remove those VMs when they are no longer needed.

KubeVirt Builder Flow

The following diagram shows the lifecycle of an on-demand Jenkins builder:

                  +-----------------------+
                  |      Jenkins Job      |
                  |   enters the queue    |
                  +-----------+-----------+
                              |
                              v
                  +-----------------------+
                  |  Jenkins Controller   |
                  |                       |
                  | Builder capacity      |
                  | required              |
                  +-----------+-----------+
                              |
                              v
                  +-----------------------+
                  |   Sorter / KubeVirt   |
                  |      Integration      |
                  +-----------+-----------+
                              |
                              | Create VM
                              v
        +------------------------------------------------+
        |              OpenShift RDU3                    |
        |                                                |
        |  ceph-downstream-tenant--pipeline              |
        |                                                |
        |       +-----------------------------+          |
        |       | OpenShift Virtualization    |          |
        |       |        / KubeVirt           |          |
        |       +-------------+---------------+          |
        |                     |                          |
        |                     | Start VM                 |
        |                     v                          |
        |       +-----------------------------+          |
        |       |     RHEL 9 Builder VM       |          |
        |       |                             |          |
        |       | rhel9medium / rhel9large    |          |
        |       +-------------+---------------+          |
        |                     |                          |
        +---------------------|--------------------------+
                              |
                              | WebSocket / HTTPS
                              v
                  +-----------------------+
                  |  Jenkins Controller   |
                  |                       |
                  | Agent becomes online  |
                  +-----------+-----------+
                              |
                              v
                  +-----------------------+
                  |       Job Runs        |
                  |   on the Builder VM   |
                  +-----------+-----------+
                              |
                              v
                  +-----------------------+
                  |     Job Completes     |
                  +-----------+-----------+
                              |
                              v
                  +-----------------------+
                  | Jenkins removes the   |
                  | dynamic agent         |
                  +-----------+-----------+
                              |
                              | Delete VM
                              v
                  +-----------------------+
                  | KubeVirt VM Destroyed |
                  |                       |
                  | CPU / Memory released |
                  +-----------------------+

The important point is that the builder VM is temporary:

Job queued
    |
    v
VM created
    |
    v
VM boots
    |
    v
Agent connects to Jenkins
    |
    v
Job runs
    |
    v
Job finishes
    |
    v
Agent removed
    |
    v
VM destroyed

Networking

Outbound traffic from the RDU3 tenant is restricted.

When Jenkins or its builder VMs require access to a new external destination, that destination must be allowed by the tenant egress configuration.

The tenant uses egress rules to control which external networks and services workloads are allowed to reach.

Adding a New Outbound Destination

For example, if Jenkins builders need to reach a service at:

192.0.2.50

on TCP port 22, an EgressFirewall rule can be added:

apiVersion: network.openshift.io/v1
kind: EgressFirewall
metadata:
  name: default
  namespace: ceph-downstream-tenant--pipeline
spec:
  egress:
    - type: Allow
      to:
        cidrSelector: 192.0.2.50/32
      ports:
        - protocol: TCP
          port: 22

For an HTTPS service:

    - type: Allow
      to:
        cidrSelector: 192.0.2.50/32
      ports:
        - protocol: TCP
          port: 443

The destination should be restricted as much as possible. Prefer allowing the specific destination IP/network and required port instead of opening broad outbound access.

Before adding a new external dependency, identify:

  • Destination hostname/IP
  • Destination network/CIDR
  • Protocol
  • Required port

The appropriate egress rule can then be added to the tenant configuration.

After the rule is applied, connectivity can be verified from a Jenkins builder VM.

OpenShift Access

The RDU3 environment provides four tenants for our use.

Each tenant has limited CPU, memory, and other resources, so workloads should be placed in the appropriate tenant.

The two primary tenants used by Jenkins are:

  • ceph-downstream-tenant–pipeline - Production Jenkins workloads.
  • ceph-downstream-tenant–runtime-int - Staging and testing environment.

The ceph-downstream-tenant–pipeline tenant hosts the production Jenkins environment and production builder workloads.

The ceph-downstream-tenant–runtime-int tenant should be used for testing changes before they are introduced into production.

Examples include:

  • Testing new Jenkins plugins
  • Testing plugin upgrades
  • Testing Jenkins configuration changes
  • Testing builder changes
  • Testing Jenkins controller changes
  • Validating other infrastructure changes

Changes should first be validated in ceph-downstream-tenant–runtime-int before being applied to ceph-downstream-tenant–pipeline.

Migration

The RDU3 Jenkins environment is intended to become the new home for the downstream Jenkins controller and builder workloads.

During the migration period, the RDU3-specific Jenkins configuration is maintained in the:

rdu3-migration

branch of:

git@gitlab.cee.redhat.com:ccit/jenkins-csb-customers/storage-casc-ceph-downstream.git

This allows the RDU3 environment to be configured and validated without affecting the existing production Jenkins deployment.

Once the migration is complete and the RDU3 Jenkins instance becomes the primary production environment, the temporary migration configuration can be consolidated into the normal production configuration.

  • OpenShift
  • OpenShift Virtualization / KubeVirt
  • RHEL 9 builder VMs
  • Jenkins Sorter plugin
  • RDU3 TenantEgress / EgressFirewall
services/downstream_ci.txt · Last modified: by akraitman