節點顯示離線,但 SSH 仍然可以連線:不要先重裝節點。先確認 Jenkins 調度,再檢查 Agent 傳輸、Java 程式、macOS 常駐工作階段與 Xcode 工具鏈;偶發進程故障可原地恢復,反覆掉線或環境持續漂移則應隔離後重建。

這篇文章適合三類讀者:
負責 Jenkins 與遠端 Mac 建置節點日常維運、需要縮短 Agent 離線恢復時間的 DevOps 工程師。
維護 Xcode 自動建置、測試或簽名任務,不能只看節點「在線」狀態的 Apple 平台開發者。
準備增加長期在線 macOS CI 節點,希望建立上線驗收與故障取證標準的平台負責人。

01

先把「離線」拆成三種不同故障

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 使用文件可用來核對不同連線方式的行為與設定邊界。

03

Java Agent 啟動失敗時,先保存退出證據

在遠端 Mac 執行查詢時,先確認 Agent 程式是否存在、由哪個使用者啟動、父進程是誰,以及標準輸出和標準錯誤是否被導向檔案。把 PID、退出碼、最後一行錯誤、Agent 檔案修改時間與控制器日誌時間對齊,通常比直接重新下載檔案更快找到原因。

常見分支包括:

  • Agent 檔案與控制器版本或傳輸參數不相容。
  • Java 啟動參數在非互動式工作階段中無效。
  • Secret、憑據或主機金鑰曾被輪換,舊啟動設定仍在使用。
  • Java 進程被系統終止,或執行 Agent 的帳戶無法讀取工作目錄。
  • 磁碟空間、檔案權限或路徑中的特殊字元導致啟動階段失敗。

Jenkins 的Java 支援政策會隨 Jenkins 發行線與支援範圍更新。不要在維運文件中永久寫死某個 Java 版本或下載網址;每次升級控制器前,應依官方頁面核對目前受支援的執行環境,再於隔離節點執行啟動驗證。

若只在互動式 SSH 中手動啟動成功,卻無法由 Jenkins 啟動,優先比較兩個上下文的環境變數、PATH、目前使用者、工作目錄與檔案權限。Secret、主機名稱、使用者名稱與金鑰在紀錄中一律使用佔位符,不要把真實憑據貼進工單或日誌。

04

macOS 重啟後的常駐問題,重點在啟動上下文

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、憑證與任務並發策略
06

用可勾選清單判斷修復、重建或隔離

先不要因為一次掉線就重建。完成取證後,使用下面的清單判斷:

  • [ ] 已保存控制器日誌、節點日誌,以及最近一次成功建置的時間點。
  • [ ] 已確認是節點離線、任務排隊,還是 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 是否更合適。