在日常的 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 緩存效率不如歸檔);
- 文件 導入 / 導出 使用的 Jenkins 默認的 當前工作目錄(workspace),若要使用其他路徑:
-
復制文件到 workspace 下再導入 / 導出文件到 workspace 下再復制到指定目錄;
-
使用
dir()
塊切換路徑:# 導入 dir('/home/swt_jenkins/jenkins/backup') {stash includes: 'file.txt', name: 'file' } # 導出 dir('/home/swt_jenkins/jenkins/backup') {unstash 'file' }
-
? 最終推薦選擇
場景 | 推薦方法 | 適用建議 |
---|---|---|
Job A 生成 → Job B 處理 | archiveArtifacts + copyArtifacts | 多 Job 聯動、構建產物管理 |
同一 Job,分節點執行 | stash / unstash | 簡潔輕量、無插件依賴 |
🧩 結語
通過這兩種方式,即使 a 和 b 兩個 Jenkins agent 節點互相無法訪問,只要它們能連接 Jenkins master,我們仍然可以實現跨節點的文件傳輸與任務協作。這不僅保證了系統的安全隔離,也增強了構建流程的靈活性。