如何防止Jenkins Pipeline占用主节点槽位并仅在指定代理运行
Jenkins Pipeline 避免占用主节点槽位,同时保留archiveArtifacts和post步骤可用
问题场景
现有如下Jenkins Pipeline脚本:
pipeline{ agent any stages { stage('First Step'){ agent { label 'TheSecondAgent'} steps { ... Do stuff } } stage('Second Step'){ agent { label 'TheSecondAgent'} steps { ... Do even more stuff } } ... Bunch more steps here stage('Archive Artifacts'){ agent { node { label 'TheSecondAgent' customWorkspace 'another/path/where/artifacts/are' } } steps { archiveArtifacts artifacts: '**/logs/*.xml, **/logs/*.json, **/logs/*.log', followSymlinks: false } } } post { always{ node('TheSecondAgent'){ dir('path/to/logs'){ xunit(tools: [ xUnitDotNet(pattern: '**/logs/*-jenkinsLogs.xml') ]) } } } } }
每个stage都指定了代理TheSecondAgent,但运行时仍会同时占用主Jenkins节点和该代理的槽位。将顶层agent设为none可解决主节点槽位占用问题,但会导致archiveArtifacts和post构建步骤无法正常使用,因此需要找到替代方案,强制脚本仅在TheSecondAgent上运行,避免占用主节点槽位。
解决方案
方案1:顶层agent直接指定TheSecondAgent,复用节点避免重复占用
将顶层agent改为直接指向TheSecondAgent,这样整个Pipeline默认在该代理节点运行,无需每个stage重复声明agent。对于需要自定义工作区的阶段,使用dir步骤切换目录即可,无需重新创建agent节点,避免额外占用槽位。
修改后的脚本:
pipeline{ // 顶层直接指定目标代理,默认所有阶段都在此节点运行 agent { label 'TheSecondAgent' } stages { stage('First Step'){ steps { ... Do stuff } } stage('Second Step'){ steps { ... Do even more stuff } } ... Bunch more steps here stage('Archive Artifacts'){ steps { // 用dir切换到自定义路径,无需重新指定agent dir('another/path/where/artifacts/are'){ archiveArtifacts artifacts: '**/logs/*.xml, **/logs/*.json, **/logs/*.log', followSymlinks: false } } } } post { always{ dir('path/to/logs'){ xunit(tools: [ xUnitDotNet(pattern: '**/logs/*-jenkinsLogs.xml') ]) } } } }
这种方式下,整个Pipeline只会占用TheSecondAgent的一个槽位,不会占用主节点资源,同时archiveArtifacts和post步骤都能正常运行。
方案2:顶层agent设为none,显式在必要步骤绑定代理
如果需要保留顶层agent为none的灵活性,可以将archiveArtifacts放在node块内执行,post步骤已经在node块中,这样就能解决步骤无法运行的问题,同时不会占用主节点槽位。
修改后的脚本:
pipeline{ agent none stages { stage('First Step'){ agent { label 'TheSecondAgent'} steps { ... Do stuff } } stage('Second Step'){ agent { label 'TheSecondAgent'} steps { ... Do even more stuff } } ... Bunch more steps here stage('Archive Artifacts'){ agent { label 'TheSecondAgent'} steps { dir('another/path/where/artifacts/are'){ archiveArtifacts artifacts: '**/logs/*.xml, **/logs/*.json, **/logs/*.log', followSymlinks: false } } } } post { always{ node('TheSecondAgent'){ dir('path/to/logs'){ xunit(tools: [ xUnitDotNet(pattern: '**/logs/*-jenkinsLogs.xml') ]) } } } } }
此方案中,每个stage和必要的步骤都显式绑定TheSecondAgent,顶层agent none不会占用任何节点槽位,所有执行逻辑都在目标代理上完成。
内容的提问来源于stack exchange,提问作者DeadlyHigh
相关产品推荐
相关产品推荐

