Запуск задания Jenkins одновременно на всех узлах

TL; DR: я хочу иметь возможность запускать задание одновременно на нескольких узлах конвейера Jenkins. [например - сборка приложения x на узлах dev, тестовых и промежуточных узлах на основе aws]

У меня есть большая группа узлов с одинаковой меткой. Я хотел бы иметь возможность запускать задание в Jenkins, которое выполняется на всех узлах с одной и той же меткой, а также выполняет это одновременно.

Я видел предложение использовать параметр конфигурации матрицы в Jenkins, но я могу думать только об одной оси (группе меток). Когда я пытаюсь запустить задание, мне кажется, что оно выполняется только один раз, а не 300 раз (по 1 для каждого узла в этой группе меток).

Какой должна быть другая ось? Или ... есть какой-нибудь плагин для этого? Я попробовал подключаемый модуль параметров NodeLabel и выбрал запускать на всех доступных онлайн-узлах, но, похоже, он не запускает задания одновременно.


person user2406467    schedule 24.06.2013    source источник
comment
Есть ли другой способ добавить узлы в задание без редактирования файла resources.xml? В конечном итоге мы будем масштабироваться до тысяч узлов, и необходимость добавлять их вручную в файл XML немного утомительна, особенно с учетом того, что узлы могут меняться. Помимо этого, Rundeck выглядит так, как будто у него есть много функций, которые мне нужны.   -  person user2406467    schedule 26.06.2013
comment
@ MarkO'Connor - Тогда я думаю, что Rundeck сможет добиться того, что мы делаем :) В конечном итоге мы будем использовать EC2. Если вы хотите добавить свои ответы в качестве ответа, я смогу их принять. Спасибо!   -  person user2406467    schedule 28.06.2013


Ответы (10)


  • Rundeck может быть инструментом, более подходящим для ваших нужд. Может быть настроен для параллельного выполнения нескольких заданий и имеет плагин для Jenkins: http://rundeck.org/
  • Rundeck разработан для интеграции с более крупными системами. Мы генерируем файл ресурсов из нашей базы данных управления конфигурацией. Очень просто просмотреть документацию: http://rundeck.org/docs/administration/node-resource-sources.html.
  • Дополнительные плагины доступны для Amazon и / или таких систем, как puppet и chef: http://rundeck.org/plugins
person Mark O'Connor    schedule 28.06.2013

  1. Install
  2. Для задания, которое вы хотите запустить, включите Выполнять параллельные сборки, если необходимо
  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
person thSoft    schedule 27.01.2016

Построение матрицы будет работать; используйте «Подчиненные» в качестве оси и разверните список «Отдельные узлы», чтобы выбрать все свои узлы.

Обратите внимание, что вам нужно будет обновлять выбор каждый раз, когда вы добавляете или удаляете подчиненное устройство.

Для более удобного в обслуживании решения вы можете использовать плагин Job DSL чтобы настроить начальное задание, которое имеет шаблон для сборки, затем перебирает каждое ведомое устройство и создает новое задание с меткой сборки, установленной на имя ведомого.

person gareth_bowles    schedule 24.06.2013
comment
Было бы очень неудобно выбирать отдельные узлы, поскольку мы хотели бы в какой-то момент масштабироваться до нескольких тысяч. Я посмотрел на плагин Job DSL и смог сгенерировать одно задание, но я не совсем понимаю, как перебирать каждое ведомое устройство. Кроме того ... похоже, что после того, как рабочие места созданы, мне все равно придется их выполнять вручную. - person user2406467; 25.06.2013
comment
@ ^^^ вот хорошее введение в Job DSL, которое немного проясняет его: youtube.com/ смотреть? v = Gyccyj6lA8k - person dyodji; 28.01.2014
comment
Вы можете заставить одну работу запускать другие. Используйте нижестоящий команда. - person Captain Man; 18.01.2019

Вам нужны два плагина: параметризованный плагин триггера, чтобы быть возможность запускать другие задания в качестве этапа сборки вашего основного задания и подключаемый модуль NodeLabel (прочтите раздел BuildParameterFactory, чтобы узнать, что вам нужно), чтобы указать метку.

person Sergey Irisov    schedule 13.09.2013

Лучший и самый простой способ добиться этого - использовать плагин Elastic Axis.
1. Установите пульгин.
2. Создайте задание с несколькими конфигурациями. (Установите, если нет)
3. В конфигурации задания вы можете найти новую ось, добавленную как Эластичная ось. Добавьте метку, как показано ниже, чтобы запустить задание на нескольких ведомых устройствах. введите описание изображения здесь

person Amol Manthalkar    schedule 26.04.2015
comment
Это не работает. Размещение одной метки на оси приведет к созданию задания на одном узле с этой меткой. - person jwg; 05.11.2015
comment
Да, он построит работу на этом единственном узле. Обычно у нас есть общие метки, то есть несколько узлов используют одно и то же имя метки в соответствии с их использованием. (мы не используем уникальные имена меток для всех узлов, так как имя узла уже уникально и служит этой цели). Также вы можете указать несколько названий меток в предоставленной текстовой области. Это единственное решение, которое я нашел. Пожалуйста, помогите мне, если у вас есть лучшее решение для этого. - person Amol Manthalkar; 16.11.2015
comment
суть ярлыков состоит в том, чтобы иметь возможность сгруппировать их вместе, при масштабировании просто убедитесь, что есть ярлык, то есть 'script-1', и он будет добавлен к оси - person jonypony3; 09.02.2017

Взяв несколько из вышеперечисленных ответов и скорректировав их для серии 2.0.

Теперь вы можете запускать все задания на всех узлах.

// 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 }
}

Взято из кода https://jenkins.io/doc/pipeline/examples/#trigger-job-on-all-nodes

person drubin    schedule 06.01.2017

Понятно - никаких специальных плагинов не требуется!

Я создал родительское задание, которое запускает / вызывает другую сборку, и когда я звоню ему, я передаю ему метку, которую я не хочу запускать в дочернем задании.

Таким образом, в основном родительское задание запускает только нужное мне задание, а дочернее задание будет выполняться столько раз, сколько ведомых устройств в этой метке (в моем случае 4 раза).

введите описание изображения здесь

person Shahar Hamuzim Rajuan    schedule 06.07.2015
comment
Что произойдет, если узлу выбранной метки потребуется слишком много времени для запуска одной из запущенных сборок? Не будет ли он работать на другом узле с той же меткой, на котором уже запущена триггерная сборка? - person ldnunes; 08.09.2015
comment
@ldnunes Нет, сборка не завершится, пока она не запустится на всех узлах с этой меткой (конечно, только подключенные ведомые устройства) - person Shahar Hamuzim Rajuan; 12.01.2016
comment
Для этого требуется плагин параметризованного триггера + метки узла для тех, кто не может найти эти параметры в своем Jenkins (например, я). - person medwards; 12.02.2016

Я искал способ запустить docker system prune на всех узлах (с меткой docker). Я закончил с довольно простым скриптовым конвейером, для работы которого AFAIK понадобится только плагин конвейера:

#!/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

Что это делает, он ищет все узлы с меткой docker, затем выполняет итерацию по нему и создает ассоциативный массив nodes с одним шагом на каждый найденный узел (если быть точным, то, что это делает, очищает все старые докеры старше 60 дней) . parallel nodes начинает выполняться параллельно (на всех найденных узлах одновременно).

Надеюсь, что это кому-то поможет.

person marverix    schedule 09.05.2020
comment
Работает хорошо, но для nodesByLabel требуется подключаемый модуль Pipeline Utility Steps. - person jds210; 24.04.2021

Включите This project is parameterized, добавьте параметр типа Label, введите произвольное имя для метки и выберите значение по умолчанию значение, такое как метка, покрывающая несколько узлов, или соединение (&&) таких меток. Включите Run on all nodes matching the label, оставьте Run regardless of result, оставьте Node eligibility на All nodes.

введите описание изображения здесь

person eel ghEEz    schedule 23.08.2018
comment
Это сработало бы, если бы не тот факт, что он: (ожидает - нет узлов с меткой «dev03 && Windows-7-x64») - person Vikramaditya Gaonkar; 09.08.2019
comment
Я не вижу никаких «параметров типа Label» в параметризованных параметрах jenkins. @угорь - person Akhil; 05.10.2020

Решение: вы можете кратко распараллелить одну и ту же сборку на нескольких узлах Jenkins.

Это может быть полезно для создания одного и того же проекта в разных средах (например, для сборки узловых приложений в тестовой, разработочной и промежуточной средах).

Пример:

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


}
person avivamg    schedule 27.12.2020