如何使用Jenkins Pipeline在多节点同时运行相同任务集
解决Jenkins Pipeline多节点并行执行的问题
我懂你现在的困扰——原来的Pipeline是挨个串行处理每个VM节点,现在想改成所有节点同时跑,但直接把parallel和for循环混着用行不通。这是因为Jenkins的parallel语法要求传入一个键值对的映射集合,每个键对应一个要并行执行的任务闭包,咱们来改造你的脚本实现并行:
核心思路
先为每个节点创建一个包含其完整执行流程的闭包,把这些闭包整理成一个映射(键用节点名称保证唯一),最后把这个映射传给parallel块,这样所有节点就会同时启动各自的任务流了。
改造后的完整脚本
pipeline { agent any parameters { string(name: '_RNX_OS', description: '用「陇」分隔的节点名称列表') string(name: '_RNX_STAGES', description: '用「陇」分隔的测试/操作列表') } stages { stage('Parallel Node Execution') { steps { script { // 分割参数得到节点列表和操作列表 def nodes = params._RNX_OS.split('陇') def configs = params._RNX_STAGES.split('陇') // 构建并行任务映射 def parallelTasks = [:] for (String VMnode : nodes) { // 创建局部变量捕获当前节点,避免闭包作用域引用问题 def currentNode = VMnode parallelTasks["Node_${currentNode}"] = { stage("Prepare environment for ${currentNode}"){ build job: "TA_StartVM", parameters: [ string(name: "_RNX_OS", value: currentNode), string(name:"_RNX_SNAPSHOT", value:"Configured") ] } for (String config : configs) { switch (config) { case "Restart": stage("Restart VM ${currentNode}"){ build job: 'TA_RestartVM', parameters: [string(name: "_RNX_OS", value: currentNode)] } break case ~/.*Start.*/: def param = config.split(':') def snapshot = param[1] stage("Start VM ${currentNode}"){ build job: 'TA_StartVM', parameters: [ string(name: "_RNX_OS", value: currentNode), string(name:"_RNX_SNAPSHOT", value: snapshot) ] } break case "Shutdown": stage("Shut down VM ${currentNode}"){ build job: 'TA_ShutdownVM', parameters: [string(name: "_RNX_OS", value: currentNode)] } break case ~/.*Save.*/: def param = config.split(':') def snapshot = param[1] stage("Save VM Snapshot ${currentNode}"){ build job: 'TA_SaveVMSnapshot', parameters: [ string(name: "_RNX_OS", value: currentNode), string(name:"_RNX_SNAPSHOT", value: snapshot) ] } break default: stage("Run ${config} Test on ${currentNode}"){ build job: 'TA_RunTest', parameters: [ [$class: 'LabelParameterValue', name: 'node', label: currentNode], string(name: "_RNX_TESTCONF", value: config), string(name: "_RNX_OS", value: currentNode) ], propagate: false } break } } stage("Test Results Table for ${currentNode}"){ build job: 'TA_TestResultsTable', parameters: [[$class: 'LabelParameterValue', name: 'node', label: currentNode]], propagate: false } stage("Publish Test Results for ${currentNode}"){ build job: 'TA_CopyTestResults', propagate: false } stage("Stop Slave ${currentNode}"){ build job: "TA_ShutdownVM", parameters: [string(name: "_RNX_OS", value: currentNode)] } } } // 执行所有并行任务 parallel parallelTasks } } } } }
关键说明
- 闭包作用域处理:循环里创建了
currentNode局部变量来捕获当前的VMnode,否则所有并行任务都会引用循环最后一个节点的值,这是Groovy闭包常见的坑。 - 并行任务映射:
parallelTasks是一个Map,键用Node_${currentNode}保证每个并行任务的唯一性,值是包含该节点所有操作的闭包。 - 保留原有逻辑:所有原来的stage逻辑(启动VM、执行操作/测试、结果处理、停止VM)都完整保留,只是封装到了每个节点的闭包里。
- stage名称优化:给每个stage加上了节点名称后缀,这样在Jenkins界面上能清晰区分不同节点的执行进度。
这样改造后,所有节点会同时启动各自的完整流程,不用再等前一个节点执行完才开始下一个,完美解决你的并行需求。
内容的提问来源于stack exchange,提问作者ruva
相关产品推荐
相关产品推荐

