從連線層開始定位

雲端 Mac 發生問題,分層排查,不靠猜

從 SSH、圖形介面與檔案傳輸,到 Xcode、Runner、fastlane 及節點網路,先用可重現的指令縮小範圍,再決定修正設定或提交工單。

獨享實體機 macOS 圖形介面與命令列 四個節點的網路疑難排解
由多台 Mac mini 實體節點與網路連線組成的工程叢集
diagnose@mac-node — zsh

$ ssh -v "$MAC_USER@$MAC_HOST"

debug1: Authentication succeeded

$ xcodebuild -version

Xcode 工具鏈就緒

$ scutil --dns | grep nameserver

解析路徑已驗證

首次連線

先完成一次可驗證的 SSH 連線

在控制台開啟對應執行個體,確認主機位址、登入使用者名稱與初始認證資料。首次連線只處理三件事:驗證目標主機、登入系統,並將後續登入切換為金鑰驗證。

  1. 01

    核對執行個體與本機環境

    先確認執行個體處於正常執行狀態,並將控制台顯示的主機位址與使用者名稱分別寫入本機環境變數。不要將密碼、私鑰或完整認證資料寫入儲存庫、聊天記錄或自動化日誌。

    export MAC_HOST="控制台顯示的主機位址"
    export MAC_USER="控制台顯示的使用者名稱"
    test -n "$MAC_HOST" && test -n "$MAC_USER" && echo "connection variables ready"
  2. 02

    首次連線並核對主機指紋

    執行連線後,核對終端顯示的指紋與控制台資訊。若主機位址變更、重新安裝後指紋變更,或本機保存了舊記錄,不要直接忽略警告,應先確認執行個體是否仍為同一台裝置。

    ssh -v "$MAC_USER@$MAC_HOST"
    ssh-keygen -F "$MAC_HOST"
  3. 03

    產生並安裝獨立金鑰

    建議為雲端 Mac 個別產生 Ed25519 金鑰,方便輪替與撤銷。安裝公開金鑰後保留目前工作階段,再開啟第二個終端驗證金鑰登入成功,確認無誤後再結束原工作階段。

    ssh-keygen -t ed25519 -a 64 -f "$HOME/.ssh/macrents_build"
    cat "$HOME/.ssh/macrents_build.pub" | ssh "$MAC_USER@$MAC_HOST" 'umask 077; mkdir -p ~/.ssh; cat >> ~/.ssh/authorized_keys'
    ssh -i "$HOME/.ssh/macrents_build" "$MAC_USER@$MAC_HOST"
  4. 04

    固定用戶端設定並執行基準檢查

    為該執行個體設定獨立別名、金鑰路徑與保活參數。登入系統後記錄 macOS 版本、可用磁碟空間、目前使用者與系統時間,之後建置失敗時即可快速判斷環境是否發生變化。

    sw_vers
    whoami
    date
    df -h /
    uptime

連線逾時與驗證失敗是兩類不同問題

逾時通常應先檢查本地網路、連接埠、節點路由與來源位址限制;出現 Permission denied 則先檢查使用者名稱、金鑰檔案、檔案權限與伺服器端授權記錄。驗證錯誤時不要反覆修改 DNS,網路不通時也不要持續重設認證資料。

遠端存取

依任務選擇終端、圖形介面或檔案通道

建置與自動化優先使用 SSH;需要除錯介面、模擬器或桌面工具時使用圖形化遠端桌面;批次同步專案與產物時使用可恢復的檔案傳輸。

終端連線

適合拉取儲存庫、安裝相依套件、執行建置與管理常駐任務。連線不穩定時啟用用戶端保活,並透過詳細日誌判斷中斷發生於交握、驗證還是工作階段。

ssh -vvv -o ServerAliveInterval=30 -o ServerAliveCountMax=4 "$MAC_USER@$MAC_HOST"

圖形化遠端桌面

從控制台進入圖形存取入口,適合 Xcode 介面除錯、觀察模擬器及使用需要桌面互動的工具。畫面卡頓時先降低解析度與更新頻率,再比較終端延遲,以區分畫面編碼問題與整條網路連線問題。

檔案傳輸

少量檔案可使用 scp;大型目錄與建置快取建議使用 rsync。傳輸前排除衍生資料、暫存封存檔與相依套件快取,避免反覆跨境傳輸可重新產生的內容。

rsync -azP --partial --exclude DerivedData/ ./project/ "$MAC_USER@$MAC_HOST:~/workspace/project/"

工作階段安全性與斷線復原

長時間建置不要只依賴單一前景終端。使用工作階段管理器或 macOS 服務機制維持任務執行,並定期將日誌寫入受控目錄。離開專案時撤銷不再使用的公開金鑰與存取權杖。

tmux new -s build
tmux attach -t build
tail -n 200 "$HOME/logs/build.log"
建置工具鏈

Xcode 報錯前,先確認目前實際使用的工具鏈

圖形介面中看到的 Xcode,與命令列選取的開發者目錄可能不是同一個版本。先記錄路徑、版本、SDK、模擬器與簽署環境,再重新執行最小建置指令。

基本檢查指令

xcode-select -p
xcodebuild -version
xcodebuild -showsdks
xcrun simctl list devices available
xcrun --find swift
swift --version
security list-keychains -d user
security find-identity -v -p codesigning
A

開發者目錄

xcode-select -p 應指向本次建置所需的 Xcode。路徑不符時先停止 Runner,切換目錄後再重新啟動,避免執行中的任務繼承舊環境。

B

SDK 與模擬器

若目標 SDK 不在 -showsdks 的輸出中,修改專案參數並不會補齊工具鏈。模擬器任務還應確認裝置狀態、執行階段版本與磁碟空間。

C

簽署身分與鑰匙圈

簽署身分存在,不代表自動化程序就能讀取私鑰。比較互動式終端與 Runner 服務的使用者、鑰匙圈搜尋清單及解鎖狀態。

D

最小建置重現

先固定工作區、scheme、configuration 與 destination,再停用無關腳本。保留完整結束碼與末段日誌,不要只擷取最後一行錯誤。

set -o pipefail
xcodebuild -workspace Project.xcworkspace -scheme Project -configuration Release -destination 'generic/platform=macOS' clean build | tee "$HOME/logs/xcode-build.log"
printf 'exit_code=%s\n' "$?"
自動化整合

Runner 能註冊,不代表建置環境已可重現

自託管 Runner 與常駐代理程式都應固定執行使用者、工作目錄、工具鏈路徑、快取邊界與金鑰讀取方式。先讓一個最小任務穩定完成,再逐步恢復並行、快取與分發步驟。

GitHub Actions

自託管 Mac Runner

在專案或組織設定中產生一次性註冊資訊,在雲端 Mac 上以專用系統使用者完成註冊。標籤至少區分作業系統、晶片等級與用途,工作流程只將 macOS 任務路由至對應節點。

  • 註冊完成後安裝為常駐服務
  • 將建置目錄與認證資料目錄分開
  • 每個任務清理暫存簽署材料
  • 先限制單一並行,再評估佇列
whoami
xcode-select -p
printenv | sort
df -h "$HOME"
GitLab CI

macOS Runner

註冊時選擇適合 macOS 的執行方式,並使用受保護標籤限制任務來源。服務使用者必須能存取專案目錄與所需鑰匙圈,但不應取得與建置無關的系統權限。

  • 核對標籤與受保護分支規則
  • 將工具鏈與相依套件版本加入快取鍵
  • 重試僅用於短暫性網路步驟
  • 上傳產物前記錄校驗值與大小
git status --short
git rev-parse HEAD
shasum -a 256 "$HOME/artifacts/app.zip"
du -sh "$HOME/build-cache"
常駐建置代理程式

以服務執行

自研代理程式或其他建置代理程式應交由 macOS 服務機制管理,明確設定啟動使用者、環境變數檔案、標準輸出與結束後的重新啟動策略。不要依賴某個遠端桌面工作階段持續連線。

  • 設定穩定且唯一的工作目錄
  • 限制日誌大小並保留失敗背景資訊
  • 重新啟動後自動復原,但避免失敗循環
  • 定期驗證工具鏈與磁碟基準
launchctl list | grep build
ps aux | grep '[b]uild-agent'
lsof -nP -iTCP -sTCP:ESTABLISHED
tail -n 200 "$HOME/logs/agent.log"

建議的最小整合順序

  1. 環境探針:輸出使用者、Xcode 路徑、版本、磁碟與工作目錄。
  2. 儲存庫任務:只執行簽出與相依套件解析,確認網路與檔案權限。
  3. 無簽署建置:驗證編譯與測試,排除憑證變數。
  4. 簽署封存:接入受控鑰匙圈與必要的環境變數。
  5. 產物上傳:記錄結束碼、檔案大小、校驗值與上傳日誌。
  6. 擴充並行:觀察 CPU、統一記憶體、磁碟讀寫與佇列時間後,再增加任務。
發布自動化

fastlane 失敗時,依憑證、權限、變數與日誌分層排查

不要一開始就重新安裝所有相依套件。先確認失敗發生於簽署準備、封存、匯出還是上傳階段,再針對該階段收集輸入、結束碼與已去除敏感資訊的日誌。

fastlane 常見問題、檢查指令與判斷方式
排查層級 常見症狀 先檢查什麼 處理原則
憑證 找不到簽署身分、身分數量為零 security find-identity -v -p codesigning 確認匯入目標鑰匙圈、憑證有效性與私鑰是否配對
描述檔 識別碼不符、功能項目不一致 目標識別碼、團隊資訊、所需功能與檔案內容 不要混用不同專案或不同環境的描述檔
鑰匙圈權限 終端可建置,Runner 無法簽署 執行使用者、搜尋清單、解鎖狀態與私鑰存取控制 讓自動化程序只存取本次任務所需的簽署材料
環境變數 互動式執行成功,服務執行時缺少參數 printenv 的去識別化差異與服務啟動設定 明確注入變數,不依賴互動式 Shell 設定檔
上傳日誌 封存成功但上傳中斷或回傳非零狀態 完整結束碼、重試次數、檔案大小與網路時間線 先確認產物有效,再將上傳問題與建置問題分開處理
為什麼終端執行成功,Runner 卻顯示找不到簽署身分?

最常見原因是執行使用者不同,或服務程序沒有繼承互動式工作階段中的鑰匙圈搜尋清單。分別記錄 whoamisecurity list-keychains -d user 與簽署身分輸出,再比較兩種執行環境。不要透過放寬所有私鑰權限來掩蓋使用者邊界問題。

如何確認 fastlane 缺少的是環境變數,而不是專案設定?

在相同提交、相同 Xcode 路徑與相同工作目錄下,分別從互動式終端與 Runner 輸出去除敏感資訊後的變數名稱清單。只比較變數是否存在,不要列印權杖值。若變數完整,再檢查工作目錄、Shell 類型、相依套件版本與執行使用者。

提交 fastlane 問題時應保留哪些日誌?

保留 lane 名稱、失敗階段、完整結束碼、Xcode 與 fastlane 版本、任務開始與結束時間、末段背景資訊及可重現指令。提交前刪除存取權杖、憑證密碼、私鑰、工作階段資訊與個人資料。只有最後一行錯誤的截圖通常不足以定位問題。

四個網路節點

新加坡、日本(東京)、韓國(首爾)與香港統一使用同一組指標比較

節點選擇應根據團隊所在地、程式碼與相依套件來源、產物去向及實際線路。不要只看單次延遲結果;至少比較往返延遲、封包遺失、DNS 解析與路由變化,並記錄測試時間範圍。

SG

新加坡

適合面向東南亞的團隊與相依鏈路。若延遲突然增加,請比較辦公室網路、行動網路與另一條出口線路,判斷是否為本地電信商路徑變化。

JP

日本(東京)

適合日本及東北亞專案。排查跨境連線時,同時記錄直連延遲、路由跳數與檔案傳輸速度,避免只憑圖形桌面的流暢度判斷。

KR

韓國(首爾)

適合韓國與鄰近地區存取。若 SSH 可用但大型檔案速度不穩定,應檢查封包遺失、路徑 MTU、本地代理伺服器與並行傳輸數量。

HK

香港

適合亞洲跨境協作與多地團隊。遇到某個網路可連線、另一個網路逾時時,分別儲存兩條路由結果並註明來源網路類型。

延遲與封包遺失

短時間測試用於確認是否可達,持續測試用於發現抖動與間歇性封包遺失。將 $MAC_HOST 設定為目前執行個體位址後執行:

ping -c 20 "$MAC_HOST"
nc -vz -w 5 "$MAC_HOST" 22
traceroute "$MAC_HOST"

DNS 與本機解析

如果使用主機名稱連線,先確認解析結果是否穩定;如果直接使用位址仍然失敗,問題通常不在 DNS。記錄本機目前的解析器與查詢結果:

scutil --dns
dscacheutil -q host -a name "$MAC_HOST"
dig "$MAC_HOST"

路由與介面

確認流量從預期介面送出,並檢查本地 VPN、代理伺服器或多網卡是否改變預設路由。測試後還原原本的網路設定,不要同時修改多個變數:

route -n get "$MAC_HOST"
netstat -rn
ifconfig
networkQuality

傳輸層驗證

SSH 交握正常但傳輸速度緩慢時,使用固定檔案重複測試,記錄檔案大小、耗時與用戶端網路。不要直接比較不同專案目錄或不同壓縮方式的結果:

time scp "$HOME/test-transfer.bin" "$MAC_USER@$MAC_HOST:~/"
shasum -a 256 "$HOME/test-transfer.bin"
ssh "$MAC_USER@$MAC_HOST" 'shasum -a 256 ~/test-transfer.bin'

所有節點全年 365 天正常運作

如果連線出現異常,請依來源網路、目標節點、通訊協定與時間範圍收集證據。單次測速不能代表長期線路品質;同一項測試至少要在問題網路與一個對照網路各執行一次,才能判斷問題位於本地出口、跨境路徑還是目標連線層。

升級人工支援

帶著可重現的背景資訊提交工單

現有使用者優先登入控制台提交工單,方便關聯訂單與執行個體。無法進入控制台時,可傳送電子郵件至 support@macrents.com。兩種方式都會進入相同的支援流程。

工單中應包含

  • 訂單編號與受影響的執行個體
  • 節點:新加坡、日本(東京)、韓國(首爾)或香港
  • 問題發生的時間範圍與時區
  • 預期結果、實際結果與重現步驟
  • 用戶端系統、網路類型與使用的通訊協定
  • 指令結束碼與已去除敏感資訊的相關日誌
  • 已執行的疑難排解步驟及結果

訊息中不要傳送

  • 任何私鑰檔案或私鑰內容
  • 完整密碼、存取權杖或工作階段資訊
  • 憑證密碼與未加密的簽署材料
  • 包含使用者資料的完整資料庫或專案封存檔
  • 未處理的個人資料與業務機密

日誌中的主機位址可保留必要部分,但應移除權杖、密碼、請求標頭、簽署材料與個人資料。支援人員需要更多資訊時,會在工單中明確說明最小必要範圍。

提交後的處理流程

確認訂單與執行個體 複核重現條件 定位連線或環境層 提供操作步驟 驗證恢復結果

連線中斷、執行個體無法存取或建置任務持續失敗時,請註明業務影響範圍。售前設定判斷可直接透過電子郵件諮詢;涉及既有訂單、主機狀態與日誌的技術問題,請優先使用控制台工單。

下一步

先選對設定,再將疑難排解流程納入團隊作業

三種方案皆為獨享 Mac mini 實體節點,並非虛擬機器。請依建置並行數、統一記憶體需求與租用期間選擇方案;已有執行個體遇到問題,可直接登入控制台提交工單。