Frage

TLDR: I want to be able to run job simultaneously on multiple nodes in Jenkins pipeline. [ for example - build application x on nodes dev, test & staging nodes based on aws ]

I have a large group of nodes with the same label. I would like to be able to run a job in Jenkins that executes on all of the nodes with the same label as well as doing so simultaneously.

I saw a suggestion to use the matrix configuration option in Jenkins, but I can only think of one axis (the label group). When I try and run the job, it seems like it only executes once instead of 300 times (1 for each of the nodes in that label group).

What should my other axis be? Or...is there some plugin to do this? I had tried the NodeLabel Parameter Plugin, and choosing "run on all available online nodes", but it does not seem to run the jobs simultaneously.

War es hilfreich?

Lösung 6

Andere Tipps

  1. Install
  2. For the job you want to run, enable Execute concurrent builds if necessary
  3. Create another job besides the job you want to run on all slaves and configure it
    • Build > Add build step > Trigger/call builds on other projects
      • Add ParameterFactories > All Nodes for Label Factory > Label: the label of the nodes

The matrix build will work; use "Slaves" as the axis and expand the "Individual nodes" list to select all of your nodes.

Note that you will need to update the selection every time you add or remove a slave.

For a more maintainable solution, you could use the Job DSL plugin to set up a seed job that has the template for the build, then loops over each slave and creates a new job with the build label set to the name of the slave.

There is two plugins that you need: Paramitrized Trigger Plugin to be able to trigger other jobs as build step of your main job, and NodeLabel Plugin (read the BuildParameterFactory section for descrition of what you need) to specify the label.

The best and easiest way to accomplish this is using Elastic Axis plugin.
1. Install the pulgin.
2. Create a Multi Configuration job.(Install if not present)
3. In the job configuration you can find new axis added as Elastic axis. Add the label as shown below to get the job run on multiple slaves. enter image description here

Taking a few of the above answers and adjusting them for 2.0 series.

You can now launch all a job on all nodes.

// The script triggers PayloadJob on every node.
// It uses Node and Label Parameter plugin to pass the job name to the payload job.
// The code will require approval of several Jenkins classes in the Script Security mode
def branches = [:]
def names = nodeNames()
for (int i=0; i<names.size(); ++i) {
  def nodeName = names[i];
  // Into each branch we put the pipeline code we want to execute
  branches["node_" + nodeName] = {
    node(nodeName) {
      echo "Triggering on " + nodeName
      build job: 'PayloadJob', parameters: [
              new org.jvnet.jenkins.plugins.nodelabelparameter.NodeParameterValue
                  ("TARGET_NODE", "description", nodeName)
          ]
    }
  }
}

// Now we trigger all branches
parallel branches

// This method collects a list of Node names from the current Jenkins instance
@NonCPS
def nodeNames() {
  return jenkins.model.Jenkins.instance.nodes.collect { node -> node.name }
}

Taken from the code https://jenkins.io/doc/pipeline/examples/#trigger-job-on-all-nodes

Got it - No need for any special plugin!

I've created a parent job that triggers/call another build , And when I'm calling him I pass him the Label that I wan't the child job to run on.

So basically the parent job Only triggers the job I need , and the child job will run as many times as the number of slaves in that Label (In my case 4 times).

enter image description here

I was looking for a way to run docker system prune on all nodes (with label docker). I ended with a pretty simple scripted pipeline, which AFAIK will only need the pipeline plugin to work:

#!/usr/bin/env groovy

def nodes = [:]

nodesByLabel('docker').each {
  nodes[it] = { ->
    node(it) {
      stage("docker-prune@${it}") {
        sh('docker system prune -af --filter "until=1440h"')
      }
    }
  }
}

parallel nodes

What this does, it is looking for all nodes with label docker, then iterates over it and creates an associative array nodes with one step per found node (to be precise, what this is doing is cleaning all old docker stuff older then 60 days). parallel nodes starts to execute in parallel (on all found nodes simultaneously).

Hope that this will help someone.

Enable This project is parameterized, add a parameter of type Label, enter an arbitrary name for the label and select a default value such as a label covering a number of nodes or a conjuction (&&) of such labels. Enable Run on all nodes matching the label, keep Run regardless of result, keep Node eligibility at All nodes.

enter image description here

Solution: You can succinctly parallel the same build across multiple Jenkins nodes

This can be useful for building the same project on different environments ( for example: build node applications on test ,dev and staging environments )

Example:

pipeline {
agent { docker {  image 'node:14-alpine' } }
stages {
    stage('build') {
        steps {
            parallelTasks
        }
      }
   }
}


def parallelTasks() {
  def labels = ['test', 'dev', 'staging'] // labels for Jenkins node types we will build on
  def builders = [:]
  for (x in labels) {
      def label = x
      
      builders[label] = {
          node(label) {
              sh """#!/bin/bash -le
                    echo "build app on ${label} node"
                    cd /home/app
                    npm run build
              """
          }
      }
  }
  parallel builders


}
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top