Connecting inbound agents

When an administrator wants to connect an inbound (formerly known as “JNLP”) external agent to a Jenkins Master, such as a Windows virtual machine running outside the cluster and using the agent service wrapper, two connection types are available in CloudBees CI on modern cloud platforms.

Table 1. Connection types
Connection type Description

WebSocket for Agent Remoting Connections (available in CloudBees CI on modern cloud platforms version 2.222.2.1 and later)

This is the recommended method for all new inbound agent connections. It is a substitute for the older method and is simpler, more straightforward, and easier to establish. This feature allows for the agent to call back on the regular HTTP port, using WebSocket to set up a bidirectional channel. Using WebSocket, inbound agents can now be connected much more simply when a reverse proxy is present: if the HTTP(S) port is already serving traffic, most proxies will allow WebSocket connections with no additional configuration.

WebSocket for Agent Remoting Connections provides the following benefits:

  • Uses best practices to set up secure connections, enhancing overall security.

  • Increases productivity by simplifying a previously complex administrative task.

  • Provides easier and more comprehensive support for any agent type on any cloud platform.

Inbound TCP (formerly known as JNLP)

With this connection, the master must expose a non-HTTP port (conventionally 50000) and then wait for an agent pod to call back to it. This can complicate network architectures. You can use a values.yaml file for this or configure it manually.

Connecting inbound agents using WebSocket for Agent Remoting Connections

CloudBees CI on modern cloud platforms supports using WebSocket transport to connect inbound agents to Managed Masters. This works for shared agents and clouds, as well.

Note: This feature is available in CloudBees CI on modern cloud platforms version 2.222.2.1 and later.

This functionality lets you make a connection via HTTP(S), then holds the connection open to create a bidirectional channel to send data back and forth between Managed Masters and inbound agents.

No special network configuration is needed since the regular HTTP(S) port proxied by the CloudBees CI ingress is used for all communications.

For additional details about WebSocket support in Jenkins, see JEP-222: WebSocket Support for Jenkins Remoting and CLI.

To connect inbound agents:

  1. On the Agent Configuration screen, in Launch method, select Launch agent by connecting it to the master.

  2. Select Use WebSocket.

    Enabling the Use WebSocket option allows the agent to make a connection to the WebSocket. When starting the agent computer, provide the -webSocket option to the launcher.

Connecting inbound agents using the values.yaml file

Use this procedure only if Helm was used to install NGINX Ingress Controller. If Helm was not used to install NGINX Ingress Controller, you should configure ports manually.

The procedure is similar to the one allowing connection of external masters to Operations Center using Helm.

To use the values.yaml file to configure ports for inbound agents:

  1. Type the following command:

    curl -Is https://$DOMAIN_NAME/$MASTER_NAME/tcpSlaveAgentListener/ | fgrep -i X-Jenkins-JNLP-Port
    On AWS, if you followed these instructions, proxy protocol will be enabled. It requires adding :PROXY at the end of each entry.

    This returns the advertised port for inbound agent traffic of a specific master.

  2. Add the service mapping to the tcp section of the values.yaml file (replace occurrences of cloudbees-core with the namespace where CloudBees CI was installed, $JNLP_MASTER_PORT by the port determined above, and $MASTER_NAME by the master name):

    tcp:
      $JNLP_MASTER_PORT: "cloudbees-core/$MASTER_NAME:$JNLP_MASTER_PORT"

    or (proxy protocol variant)

    tcp:
      $JNLP_MASTER_PORT: "cloudbees-core/$MASTER_NAME:$JNLP_MASTER_PORT:PROXY"
    Add a line for every master that you want to allow external inbound agent connections to.
  3. Apply the configuration:

    helm upgrade nginx-ingress stable/nginx-ingress \
                --namespace ingress-nginx \
                --values values.yaml \
                --version 1.31.0
  4. These changes require a redeployment of nginx-ingress-controller, but due to nginx issue #4804 this will happen only when creating the tcp section, not when updating it.

    To force a rolling update of nginx-ingress-controller, use the following command:

    kubectl patch deployment nginx-ingress-controller -p \
      "{\"spec\":{\"template\":{\"metadata\":{\"annotations\":{\"date\":\"`date +'%s'`\"}}}}}"

After you have configured ports, you should test the connection.

Configuring ports manually for inbound agents

Use this procedure if Helm was not used to install NGINX Ingress Controller. If Helm was used to install NGINX Ingress Controller, you should use the values.yaml file.

The procedure is similar to the one allowing connection of external masters to Operations Center.

To use the values.yaml file to configure ports for inbound agents:

  1. Type the following command:

    curl -I https://$DOMAIN_NAME/$MASTER_NAME/tcpSlaveAgentListener/ | fgrep -i X-Jenkins-JNLP-Port

    This returns the advertised port for inbound agent traffic.

    If you already configured tcp-services before, you will need to retrieve the current configmap using kubectl get configmap tcp-services -n ingress-nginx -o yaml > tcp-services.yaml and edit it accordingly.

    Example of a new file: replace occurrences of $NAMESPACE with the namespace where CloudBees CI was installed, $JNLP_MASTER_PORT by the port determined just before, and $MASTER_NAME by the master name, then save it to tcp-services.yaml.

    apiVersion: v1
    kind: ConfigMap
    metadata:
      name: tcp-services
      namespace: ingress-nginx
    data:
      $JNLP_MASTER_PORT: "$NAMESPACE/$MASTER_NAME:$JNLP_MASTER_PORT"

    or (proxy protocol variant)

    apiVersion: v1
    kind: ConfigMap
    metadata:
      name: tcp-services
      namespace: ingress-nginx
    data:
      $JNLP_MASTER_PORT: "$NAMESPACE/$MASTER_NAME:$JNLP_MASTER_PORT:PROXY"
  2. Copy and paste the following to a new file and save it as deployment-patch.yaml.

    spec:
      template:
        spec:
          containers:
            - name: nginx-ingress-controller
              ports:
              - containerPort: $JNLP_MASTER_PORT
                name: $JNLP_MASTER_PORT-tcp
                protocol: TCP
  3. Copy and paste the following to a new file and save it as service-patch.yaml.

    spec:
      ports:
      - name: $JNLP_MASTER_PORT-tcp
        port: $JNLP_MASTER_PORT
        protocol: TCP
        targetPort: $JNLP_MASTER_PORT-tcp
  4. Apply these fragments using the following commands:

    kubectl apply -f tcp-services.yaml
    kubectl patch deployment nginx-ingress-controller -n ingress-nginx -p "$(cat deployment-patch.yaml)"
    kubectl patch service ingress-nginx -n ingress-nginx -p "$(cat service-patch.yaml)"

After you have configured the connection, you should test the connection.

Testing the connection for inbound agents

After you have configured the connection for inbound agents, you should confirm that Master is ready to receive external inbound agent requests.

To test the connection for inbound agents:

$ curl $DOMAIN_NAME:$JNLP_MASTER_PORT
Jenkins-Agent-Protocols: Diagnostic-Ping, JNLP4-connect, OperationsCenter2, Ping
Jenkins-Version: 2.176.1.4
Jenkins-Session: f4e6410a
Client: 0:0:0:0:0:0:0:1
Server: 0:0:0:0:0:0:0:1
Remoting-Minimum-Version: 3.4

Once the connection is correctly configured in your cloud, you can then create a new 'node' in your master under Manage Jenkins > Manage Nodes.

The node should be configured with: - Launch method: 'Launch agent by connecting it to the master'