Jenkins 不同节点间文件传递:跨 Job 与 同 Job 的实现方法
在日常的 DevOps 运维实践中,Jenkins 通常被用于串联多个自动化流程,而这些流程往往需要在不同的构建节点(agent)上执行。例如,在以下场景中:
📌 场景需求描述(实际问题)
最近在一次部署任务中,我遇到这样一个需求:
- Jenkins 的 a 节点 执行某些命令或脚本,生成一个临时文件或构建产物;
- 然后需要 b 节点 获取这个文件,并继续执行后续处理(如压缩、上传、部署等);
- a 节点与 b 节点不直接通信,它们都只能与 Jenkins master 通信;
- 不希望直接打通 a 与 b 节点的网络 ACL,出于安全隔离考虑,希望通过 Jenkins 实现文件传递。
于是我研究并实现了两种可靠的解决方案,分享如下👇
方法一:跨 Job 文件传递(使用 archiveArtifacts
+ copyArtifacts
插件)
🎯 场景适用:
- Job A 运行在 a 节点;
- Job B 运行在 b 节点;
- 两者在不同的 Jenkins Job 中;
- 构建产物持久化后再被其他 Job 使用。
📦 所需插件:
Copy Artifact Plugin
- 安装方式:Jenkins 管理后台 → 插件管理 → 可用插件中搜索
copy artifact
并安装
🛠️ 原理说明:
阶段 | 节点 | 操作 | 文件流向 |
---|---|---|---|
Job A | node-a | 生成并归档文件(archiveArtifacts ) | 上传到 Jenkins master 构建归档目录 |
Job B | node-b | 复制 Job A 的构建产物(copyArtifacts ) | 下载回 node-b 的工作目录 |
Jenkins 会将文件临时保存在 master 节点:
$JENKINS_HOME/jobs/JobA/builds/<构建号>/archive/...
📁 Job A:生成并归档文件(运行在 node-a
)
pipeline {agent { label 'node-a' }stages {stage('生成文件') {steps {sh 'echo hello-from-A > shared.txt'archiveArtifacts artifacts: 'shared.txt'}}}
}
📁 Job B:复制并处理文件(运行在 node-b
)
pipeline {agent { label 'node-b' }stages {stage('获取并处理文件') {steps {copyArtifacts(projectName: 'JobA',selector: specific('lastSuccessfulBuild'))sh 'cat shared.txt'sh 'echo 在 b 节点处理完成'}}}
}
✅ 优点:
- 适用于不同 Job 间的构建产物传递;
- 构建产物有历史记录可追溯,便于复查和调试;
- 跨节点传输由 Jenkins master 中转,无需节点互通。
⚠️ 注意事项:
- 插件必须安装;
- 文件必须通过
archiveArtifacts
显式上传,copyArtifacts
才能访问; - 传递的是“构建产物”,适合大文件或需要留痕的使用场景。
方法二:同一个 Job 跨节点传文件(使用 stash
/ unstash
)
🎯 场景适用:
- 单个 Job 内存在多个 stage;
- 每个 stage 在不同节点(agent)执行;
- a 节点执行前置任务,b 节点执行后置处理,且只需传递中间文件。
🛠️ 原理说明:
阶段 | 节点 | 操作 | 文件流向 |
---|---|---|---|
Stage A | node-a | 使用 stash 暂存文件 | a 节点 → Jenkins master 内部缓存 |
Stage B | node-b | 使用 unstash 还原文件 | Jenkins master → b 节点工作目录 |
Jenkins 在执行 stash
时,会将指定文件上传到控制节点的临时缓存;
在 unstash
阶段再从缓存取出,恢复到当前节点的工作目录。
✅ 不需要任何插件,Jenkins Pipeline 原生命令支持。
📋 示例 Pipeline(a 和 b 节点在同一个 Job 的不同阶段):
pipeline {agent nonestages {stage('a 节点生成文件') {agent { label 'node-a' }steps {sh 'echo hello-from-a > file.txt'stash name: 'intermediate-file', includes: 'file.txt'}}stage('b 节点处理文件') {agent { label 'node-b' }steps {unstash 'intermediate-file'sh 'cat file.txt'sh 'echo b 节点处理完毕'}}}
}
✅ 优点:
- 无需插件,Jenkins 原生命令支持;
- 跨节点无感传输,适合流水线阶段串行任务;
- 不需要构建产物留痕,避免污染归档记录。
⚠️ 注意事项:
stash/unstash
只在 同一个 Job 中有效,不能跨 Job 使用;- Jenkins 会将文件临时保存在控制节点目录,注意空间限制;
- 大文件不建议使用此方式(stash 缓存效率不如归档);
✅ 最终推荐选择
场景 | 推荐方法 | 适用建议 |
---|---|---|
Job A 生成 → Job B 处理 | archiveArtifacts + copyArtifacts | 多 Job 联动、构建产物管理 |
同一 Job,分节点执行 | stash / unstash | 简洁轻量、无插件依赖 |
🧩 结语
通过这两种方式,即使 a 和 b 两个 Jenkins agent 节点互相无法访问,只要它们能连接 Jenkins master,我们仍然可以实现跨节点的文件传输与任务协作。这不仅保证了系统的安全隔离,也增强了构建流程的灵活性。