節點顯示離線,但 SSH 仍然可以連線:不要先重裝節點。先確認 Jenkins 調度,再檢查 Agent 傳輸、Java 程式、macOS 常駐工作階段與 Xcode 工具鏈;偶發進程故障可原地恢復,反覆掉線或環境持續漂移則應隔離後重建。
這篇文章適合三類讀者:
負責 Jenkins 與遠端 Mac 建置節點日常維運、需要縮短 Agent 離線恢復時間的 DevOps 工程師。
維護 Xcode 自動建置、測試或簽名任務,不能只看節點「在線」狀態的 Apple 平台開發者。
準備增加長期在線 macOS CI 節點,希望建立上線驗收與故障取證標準的平台負責人。
先把「離線」拆成三種不同故障
Jenkins macOS Agent 掉線不一定代表遠端主機無法使用。你應先在控制器保存故障發生時間、節點名稱、最近一次成功建置、目前佇列原因,以及節點日誌中的完整錯誤行。接著再登入遠端 Mac,記錄 Agent 程式是否存在、目前使用者與工作目錄狀態。
Jenkins 官方的節點與 Agent 管理文件將節點、執行器與連線狀態分開管理。實務上可先用下表縮小範圍:
| 控制器看到的現象 | 遠端 Mac 的觀察結果 | 優先判斷 |
|---|---|---|
| 節點離線,佇列等待該標籤 | SSH 可登入,但沒有 Agent 程式 | Agent 未啟動或啟動後立即退出 |
| 節點在線,任務仍排隊 | 執行器忙碌、標籤不符或工作目錄不可寫 | 調度設定或節點環境問題 |
| 節點在線,Shell 可執行但 Xcode 失敗 | Xcode 路徑、元件、簽名資源不在同一使用者上下文 | 建置工具鏈失效 |
| 控制器重啟後節點沒有回來 | 手動啟動可成功,註銷或重啟後失效 | macOS 常駐機制與啟動上下文問題 |
不要把任務排隊直接當成 Jenkins Agent 斷線。先查看任務要求的 label、節點執行器數量、是否被手動標記離線,以及 Remote Root Directory 是否仍然存在。這一步能避免在真正的調度問題上反覆重啟主機。
02連線通道要分開驗證,SSH 能用不代表 Jenkins 能用
為什麼 Jenkins 顯示 macOS Agent 離線但 SSH 可以連線
SSH 登入測試的是 macOS 的 Remote Login 服務;Jenkins Agent 則可能透過控制器 SSH 啟動、TCP Agent Listener 或 WebSocket 傳輸。兩者的目的地、驗證資料與持續連線方式不同,因此「SSH 可登入」只能證明主機與系統登入服務仍有回應。
Apple 對macOS Remote Login 的官方說明涵蓋的是系統層 SSH 存取,不等於 Jenkins Agent 通道已建立。排查時不要把控制器的 SSH 服務、遠端 Mac 的系統 SSH,以及 Jenkins Agent 傳輸通道混為一談。
按你目前設定的 Launch Method 取證:
- SSH 啟動:確認控制器能解析主機名稱、使用正確帳戶登入,並能在該帳戶上下文啟動 Java 與 Agent。不要只測試互動式 Shell。
- TCP Agent Listener:檢查控制器暴露的 Agent 服務是否可達,以及中間防火牆或代理是否在閒置後切斷連線。Jenkins 的服務與連接埠文件是核對服務用途與安全設定的依據。
- WebSocket:檢查反向代理是否允許 WebSocket 升級,並確認控制器網址、TLS 憑證與代理轉送設定沒有變更。
- 所有方式:先核對 DNS 解析、路由、出口限制、憑證、控制器位址,再閱讀控制器端與節點端日誌的同一時間點。
修復不能只以「重新整理頁面後顯示在線」作為證據。你至少要觀察握手成功、心跳持續、執行一個最小化工作,並在控制器重啟後確認節點能按預期重新連線。Jenkins 的Agent 使用文件可用來核對不同連線方式的行為與設定邊界。
03Java Agent 啟動失敗時,先保存退出證據
在遠端 Mac 執行查詢時,先確認 Agent 程式是否存在、由哪個使用者啟動、父進程是誰,以及標準輸出和標準錯誤是否被導向檔案。把 PID、退出碼、最後一行錯誤、Agent 檔案修改時間與控制器日誌時間對齊,通常比直接重新下載檔案更快找到原因。
常見分支包括:
- Agent 檔案與控制器版本或傳輸參數不相容。
- Java 啟動參數在非互動式工作階段中無效。
- Secret、憑據或主機金鑰曾被輪換,舊啟動設定仍在使用。
- Java 進程被系統終止,或執行 Agent 的帳戶無法讀取工作目錄。
- 磁碟空間、檔案權限或路徑中的特殊字元導致啟動階段失敗。
Jenkins 的Java 支援政策會隨 Jenkins 發行線與支援範圍更新。不要在維運文件中永久寫死某個 Java 版本或下載網址;每次升級控制器前,應依官方頁面核對目前受支援的執行環境,再於隔離節點執行啟動驗證。
若只在互動式 SSH 中手動啟動成功,卻無法由 Jenkins 啟動,優先比較兩個上下文的環境變數、PATH、目前使用者、工作目錄與檔案權限。Secret、主機名稱、使用者名稱與金鑰在紀錄中一律使用佔位符,不要把真實憑據貼進工單或日誌。
04macOS 重啟後的常駐問題,重點在啟動上下文
Jenkins macOS Agent 重啟後不會自動上線怎麼辦
手動 SSH 啟動成功,只代表當下登入工作階段具備所需條件。註銷、關閉 VNC、重啟 Mac 或長時間無人操作後,Agent 可能因為啟動上下文、執行帳戶、檔案權限或自動啟動機制改變而消失。
先確認 Agent 是以哪個使用者啟動,再檢查該使用者是否能讀寫 Agent 檔案、Remote Root Directory 與工作區。接著依實際部署方式檢查 launchd 的設定狀態與系統日誌。不要直接套用網路上的通用 plist:不同 macOS 版本、登入型態、工作目錄與權限模型,可能需要不同的啟動條件。
修復後依序做這些復測:
- 登出目前圖形介面工作階段,確認 Agent 不依賴人工開啟終端機。
- 重啟遠端 Mac,確認啟動後能自動連回控制器。
- 暫時中斷網路,再觀察連線恢復後是否能重新握手。
- 關閉 VNC 或遠端桌面工作階段,確認 Agent 不隨顯示工作階段終止。
- 在無人值守狀態執行最小 CI 工作,確認執行器能接單。
若某一項只能靠人工 SSH 介入,就不能把節點標記為已恢復。你需要把失敗條件寫入節點運維紀錄,否則下一次控制器重啟時,故障會再次變成發布阻塞。
05遠端 Mac 在線後,還要驗證工作目錄與 Xcode CI
Jenkins Agent 在線但 Xcode 任務一直排隊怎麼排查
節點在線而任務排隊,先看 label、執行器、節點是否被暫停,以及任務要求的工作目錄。若任務已開始但在 Xcode 階段失敗,再檢查 Xcode 選用路徑、Command Line Tools、首次初始化元件、Shell 環境與簽名資源。
| 驗收層級 | 需要觀察的資料 | 不合格時的處置 |
|---|---|---|
| 調度 | 任務 label、節點 label、執行器狀態 | 修正標籤或釋放執行器 |
| 檔案系統 | Remote Root Directory、工作區權限、可用空間 | 修正權限或隔離磁碟問題 |
| Xcode 工具 | Xcode 選用版本、Command Line Tools 與初始化狀態 | 依 Apple 文件重新設定並記錄版本 |
| 測試 | 編譯、單元測試與測試結果 | 分開定位編譯和測試失敗 |
| 簽名 | 憑證、Provisioning Profile、Keychain 使用者上下文 | 隔離簽名節點,禁止共用不明狀態 |
Apple 的Xcode Command Line Tools 設定文件與安裝文件可用來核對工具選擇和安裝狀態。不要用「可以執行一行 Shell 指令」代替正式驗收,因為簡單命令可能沒有觸發編譯、測試或簽名所需的完整環境。
建議把驗收工作拆成三類:
- 普通編譯:確認專案能取得依賴、選用正確 SDK,並產生預期建置輸出。
- 測試:確認測試程序能啟動、結果能回傳控制器;參考 Apple 的Xcode 測試結果說明保存失敗分類。
- 簽名與封裝:確認 Jenkins Agent 使用的帳戶能讀取必要 Keychain 與簽名資源,再驗證歸檔輸出。Apple 的簽名程式碼與建立歸檔文件可作為流程核對依據。
遠端 Mac 上的 Jenkins Agent 應該用 SSH 還是入站連線
沒有單一答案。若控制器可以穩定連入遠端 Mac,SSH 啟動較容易集中管理;若節點位於受限網路,入站連線或 WebSocket 通常更符合出站連線模型。但真正的選擇取決於防火牆、代理、憑據輪換、斷線重連與長時間常駐需求,而不是只看初次安裝是否方便。
| 條件 | 較適合的方向 | 必須補上的驗證 |
|---|---|---|
| 控制器能穩定連入 Mac | SSH 啟動 | 非互動式 Shell、Java 與工作目錄權限 |
| Mac 只能向外連線 | 入站連線或 WebSocket | 代理升級、TLS、Secret 輪換與斷線重連 |
| 節點需要長期無人值守 | 任一可維持的方式 | 重啟、註銷、網路中斷後自動恢復 |
| 需要嚴格隔離簽名環境 | 專用節點與專用帳戶 | Keychain、憑證與任務並發策略 |
用可勾選清單判斷修復、重建或隔離
先不要因為一次掉線就重建。完成取證後,使用下面的清單判斷:
- [ ] 已保存控制器日誌、節點日誌,以及最近一次成功建置的時間點。
- [ ] 已確認是節點離線、任務排隊,還是 Xcode 工具鏈失效。
- [ ] 已分開測試系統 SSH 與 Jenkins Agent 傳輸通道。
- [ ] 已記錄 Agent PID、退出碼、標準錯誤與啟動使用者。
- [ ] 已依目前 Jenkins 文件核對 Java 支援範圍與 Agent 連線設定。
- [ ] 已在註銷、重啟、網路短暫中斷和無人值守條件下復測。
- [ ] 已分別通過編譯、測試,以及簽名或封裝驗收。
- [ ] 已確認 label、執行器、Remote Root Directory 和工作區權限一致。
- [ ] 已判斷故障是一次性進程問題,還是持續性的環境漂移。
若只是 Agent 進程退出、檔案權限錯誤或一次性的連線中斷,而且復測後能自動恢復,可以原地修復。若節點反覆掉線、重啟後必須人工介入、Xcode 或簽名狀態經常改變,應先標記為不可接收正式工作,再重建節點。需要更高可用性時,增加一台獨立遠端 Mac,比在同一台主機上不斷追加臨時腳本更容易維持可預測的 CI 行為。
對於沒有獨立重啟權限、需要長期在線 macOS 環境的團隊,可先閱讀VpsMesh 的遠端 Mac 方案,再依地區與連線需求比較Mac mini M4 遠端部署選項。如果你正在評估固定週期成本,也可以查看Mac mini M4 租用價格說明,但仍應以實際 Xcode CI 驗收結果作最後判斷。
如果你目前使用的是自有 Mac mini,常見缺點是硬體需要自行採購與維護、重啟或故障時沒有獨立替代節點,而且辦公室網路、電力與遠端存取權限會直接影響 Jenkins 可用性。若改用一般 Linux 雲端主機,則無法直接提供 Xcode 與 macOS 簽名工具鏈。當你的需求是臨時擴充建置量、測試隔離環境,或需要一台可由你完整管理的長期在線 Mac,租用 VpsMesh 的遠端 Mac 通常比繼續修補不穩定的既有節點更容易驗收與維運;若是長期固定的高負載工作,或必須接觸本地實體裝置,仍應如實評估自購 Mac 是否更合適。