2026-05-06 iOS 模擬器執行時期 磁碟預算、選擇性安裝 與 CI 清理(租用 Apple Silicon 雲端 Mac,香港/東京/首爾/新加坡/美國)
在香港、東京、首爾、新加坡或美國租用 Mac mini M4 跑 xcodebuild test 的團隊,很快會遇到第二張帳單:Simulator 執行時期並不免費——它們在 Library/Developer/CoreSimulator 下佔據數 GB 到十幾 GB,與 DerivedData 爭搶 NVMe 頻寬;一旦 watchOS 伴侶矩陣加入,體積還會倍增。本 2026-05-06 指南回答三個維運問題:如何盤點已裝內容、如何只選 destinations 真正需要的 OS 家族、如何裁剪而不刪掉夜間 UI 測試仍要啟動的執行時期。延續 無頭模擬器測試,與 磁碟清理與 janitor 配套,並在同主機多車道時引用 DerivedData 隔離 與 並行 xcodebuild 的佇列策略。
為何 2026 的 CI 仍把「裝了 Xcode」當成「模擬器就緒」
Xcode.app 帶的是工具鏈,而執行時期是可依需求下載的版本化載荷。三類高頻失誤:
- destination 漂移——YAML 仍寫
iPhone 15,主機 Xcode 升級後只預置了iPhone 16映像。 - 靜默 watch 配對——本機 Xcode 自動拉了 watch 執行時期,CI 從未拉取。
- 清掃越權——排程刪掉 QA 仍要拿來重現 App Store 崩潰的 iOS 17.6 執行時期。
體積:GB 藏在哪裡
Apple Silicon 主機會存放裝置資料、dyld 共享快取與依執行時期切分的映像。粗略預期:每對主要 iOS 執行時期(手機+年度 watch 映像)7–14 GB;若 UI 截圖車道裝了多語系包,再加 3–6 GB。關鍵不是精確位元組,而是導數——五名工程師在同一共用機構建機上各自「順手裝最新 beta 執行時期」時的斜率。
把執行時期增長與佇列延遲關聯:空閒低於 12% 時,首個症狀往往是 xctest fixture 變慢而非立刻失敗,因為 APFS 需要更努力找連續區塊。
採納新 Xcode 大版本時,把執行時期下載當成容量遷移而非單一勾選:Xcode 可能提示多平台包、CoreSimulator 快取重建,首個綠構建常伴隨 24–48 小時 的隱式「暖機」膨脹。為租用主機預留顯式維護視窗,避免 PR 流量與首次大量下載重疊——忽視這點的團隊常見「無程式碼原因」的間歇性紅構建,隔天又自行消失。該視窗內按小時記錄 df,與上季穩態曲線對比;若斜率高於歷史 2×,多半在同一車道疊了 beta 與 GA 兩套重疊切片。
最後把誰有權安裝執行時期寫進制度:工程師臨時 sudo 是共享金鑰上出現「神秘 6 GB」的主因。變更應走基礎建設工單並綁定 CI 映像標籤,使 ssh 工作階段可稽核——尤其在資料落地已約束你選擇新加坡還是美東保存簽章材料的監管情境。
車道矩陣:哪台主機保留哪些執行時期
顯式拆分職責,不要假裝每台 runner 可互換。
| 車道標籤 | 執行時期策略 | 誰負責清理? |
|---|---|---|
ios-current |
最新 GA iOS+一條 N-1 對齊 App Store | 每週裁剪+工單 |
watch-heavy |
watchOS 映像+僅配對手機 | 月度;無 QA 簽字不刪 N-1 |
archive-only |
最少模擬器;偏好真機 Archive | 對模擬器 aggressive、對金鑰 gentle |
維運應貼進 runbook 的盤點指令
先非破壞探測,再升級動作。
xcrun simctl list runtimes
df -h /
du -sh ~/Library/Developer/CoreSimulator/* 2>/dev/null | sort -h | tail -n 20
若數字與 Finder 不一致,以 CI 使用者執行的 du 為準——launchd 作業以建置帳號執行。若使用獨立卷,對 /Volumes/builds 重複上述步驟。
選擇性安裝(理想路徑)
- 凍結佇列或排空綁定到該主機的標籤。
- 下載下一 sprint destination 矩陣真正需要的執行時期包。
- 每類執行時期做一次
xcrun simctl boot冒煙,並確認sysctl hw.model仍回報 Apple Silicon。 - 提升 CI YAML 的映像版本標籤後重新開放佇列。
- 在 infra 倉庫記錄已裝集合,而不是孤立 wiki。
在步驟二與三之間,把 校驗和 或 Apple 版本字串記在工單裡,若映像損壞可明確回滾。
裁剪策略:什麼可以刪
好的 janitor 對衍生產物 aggressive,對執行時期視作半靜態基礎設施。兩階段策略:
| 產物 | 安全節奏 | 過度裁剪風險 |
|---|---|---|
| 未啟動的模擬器裝置 | 每日 | 低——可從範本重建 |
舊 .xcresult 包 |
上傳物件儲存後 | 中——合規可能要求離機保留 30–90 天 |
| 執行時期包本體 | 季度+ QA 清單 | 高——破壞崩潰重現的可重複性 |
並行車道與統一記憶體壓力
並行 xcodebuild 會放大模擬器啟動抖動。用佇列標籤限制每主機並行啟動數——見 並行作業指南。記憶體尖峰時優先減少並行 destination而不是依賴交換;統一記憶體下 XCTest 對 swap 極其敏感。
sysdiagnose 切片——磁碟壓力常以 SpringBoard watchdog 形式先出現。
Xcode 升級視窗:把執行時期拉取與 Archive 錯峰
除非有第二台熱備節點,否則不要把執行時期大下載與 TestFlight 提交凍結夜排在同一天。MacXCode 主機上最安全的模式是藍綠建置機:候選映像上 xcodebuild test 與輕量 xcodebuild archive -archivePath /tmp/Smoke.xcarchive 均綠後再提升映像標籤。若買不起雙節點,就縮小範圍:維護視窗每小時只增裝一個額外執行時期,而不是一次五個。記錄每次下載的牆鐘分鐘數,便於財務比較「再租一台 1 TB 建置機」與「燒掉一個發佈週末」。升級後重新校驗 YAML 裡的 destination 字串,Apple 偶爾會改模擬器硬體 profile 名稱。錯配表現為「destination not found」,而 simctl list 看起來仍有裝置——通常是因為作業指向了裁剪時刪掉的硬體字串。把 simctl list devices available 的機器可讀匯出納入 infra 倉庫做 diff。
可寫進 Grafana 的數值目標
- 持續磁碟利用率不超過 85%再談分頁維運。
- 16 GB 機型預設最多 4 個已啟動模擬器,除非 profiling 證明仍有裕量。
- 「安裝執行時期+啟動+單條 XCTest」冷路徑上限 22 分鐘;升級後逾時告警。
刪「那個大目錄」前的九步清單
- 確認沒有 Archive 任務在飛。
- 把目前
simctl list快照進 GitOps。 - 標出過去 30 天 零作業命中的執行時期。
- 向 QA 發出帶明確移除日期的通知。
- 一次只排空一條車道。
- 僅透過受支援的 UI/CLI 路徑刪除執行時期。
- 對剩餘 destination 重跑冒煙。
- 對比刪除前後
df,把差值附在工單。 - 僅在健康主機上前滾標籤。
常見問題:beta、Apple Silicon 與跨區主機
| 問題 | 實務答案(2026-05-06) |
|---|---|
| beta 執行時期應放在正式 CI 嗎? | 隔離到帶 canary 標籤的主機;永遠不要與 App Store 提交車道混跑。 |
| 新加坡與美國主機要完全一致嗎? | 對齊最小公共集合;區域特有附加包可以,但 YAML 必須編碼。 |
為何 1–2 TB 的 Mac mini M4 仍適合模擬器密集型 CI
模擬器負載偏隨機讀;MacXCode 節點上裸金屬 Mac mini M4 NVMe 讓四條車道為同一 PR 矩陣啟動不同 OS 代際時啟動時間仍可預期——可預期性才能把數字預算變成工程紀律,而不是買不知底細的「大雲碟」卻與吵鬧鄰居共享。向容量規劃解釋為何需要第二台 JP canary 時用 區域定價;安全團隊要稽核誰刪了執行時期時用 SSH/VNC 接入說明。