CircleCI Machine Runner 3 迁移:2026 macOS 验收清单

这篇文章面向维护 CircleCI macOS 自托管构建节点的企业 IT 和研发效能负责人,重点解决旧版 launch agent 迁移后无法接单、凭证残留、任务路由错误和重启失效等问题。文章提供 3 张对比表、分问题域的验收清单,以及适合试点、放量或回滚的决策条件。

Runner 在 CircleCI 控制台里显示在线,但生产任务仍然没有安全切换,甚至旧节点已经停止接单、新服务却没有成功启动。

最快解法:仍使用旧版 launch agent 的 macOS 构建节点应迁移到 Machine Runner 3,但必须先隔离试点、并行验证,再分批切换生产节点,并提前保留可执行的回滚路径。

00谁应该看这份验收清单

这篇文章适合维护 CircleCI macOS 自托管节点、准备淘汰旧版 launch agent 的平台工程负责人,也适合担心代码签名、私有网络访问和发布稳定性的企业 IT 负责人。

如果技术总监正在决定继续使用现有 Mac、增加隔离节点,还是采用可按需扩容的远程 Mac,这份清单可以作为迁移评审和生产准入的基础材料。

更新提醒: 本文最后更新于 2026 年 8 月 21 日,资料核实自 CircleCI 官方迁移指南、macOS 安装文档、配置参考、配置策略文档与 Runner changelog。正式执行前仍应重新核对官方页面,因为安装包、服务启动方式和配置行为可能继续变化。

01先划清迁移边界:配置兼容不等于生产行为兼容

CircleCI 官方迁移说明明确表示,Machine Runner 3 可以替代旧版 launch agent,macOS 迁移的基本路径是先卸载旧服务,再安装新 Runner;官方还说明原有配置文件具备 1:1 兼容性。具体步骤应以官方 macOS 迁移指南当前版本为准。

但“配置文件能被读取”只回答了语法和字段层面的问题,不能证明以下行为完全一致:

  • 服务是否在正确的 LaunchAgent 域中启动;
  • 执行用户是否仍然拥有 Xcode、钥匙串和私有网络访问权限;
  • 任务是否被路由到预期的 resource class;
  • 任务结束后代码、缓存和签名材料是否真正清理;
  • Mac 重启、网络短暂中断或 Runner 进程退出后能否恢复接单;
  • 回滚时是恢复旧服务,还是切换到备用节点。

因此,迁移对象不能只记录“Runner 名称”和“在线状态”。至少要建立以下最小盘点表:

盘点对象 必须记录的内容 不记录的后果
迁移节点 Mac 型号、芯片架构、macOS、执行账号、节点用途 无法判断签名与工具链是否一致
依赖流水线 iOS CI/CD、发布、测试、私有网络任务 切换后才发现关键流水线无法运行
任务路由 namespace、resource class、允许项目 普通项目可能进入生产签名节点
凭证范围 SSH key、临时 Keychain、Provisioning Profile 无法证明跨任务隔离
回滚责任 负责人、备用节点、恢复命令、验证任务 故障时在生产机上临时拼接方案

企业应把迁移拆成“隔离试点节点”和“生产节点”两类,而不是在唯一的 Mac 打包服务器上直接覆盖安装。

02按服务残留排查启动冲突

旧版 launch agent 的服务文件、安装目录和运行进程如果没有完整清理,新旧 Runner 可能分别读取不同配置,或者同时尝试向同一个 resource class 领取任务。官方 macOS 迁移步骤包含停止服务、删除 plist 和移除旧安装目录的动作;实际命令应根据节点当前的安装路径和服务域调整。

迁移前应在维护窗口内完成以下核验:

  • ✅ 检查 /Library/LaunchDaemons/Library/LaunchAgents 与用户目录下是否存在旧 Runner plist;
  • ✅ 检查是否仍有旧的 circleci-launch-agent 或同类进程;
  • ✅ 记录旧安装目录、配置文件路径和日志路径;
  • ✅ 停止旧服务后再次确认进程已经退出;
  • ✅ 不在同一节点上临时保留两套自动启动方式;
  • ✅ 失败时明确是恢复旧服务,还是把流水线切到备用 Mac。

安装新 Runner 时,官方 macOS 安装文档采用 Homebrew 方式,并要求配置 Runner 名称与认证令牌。安装包来源、安装日志和二进制校验结果应纳入变更记录,而不是只保留一条“brew install 成功”的终端输出。安装完成后,可按官方 macOS 安装指南核对二进制签名、notarization 和 launchctl 服务状态。

验收项目 通过条件 失败时的处理
旧 plist 已停止并删除,且没有重复副本 暂停安装,先清理旧服务
旧进程 迁移后不存在旧 Runner 进程 终止进程并重新检查启动项
新二进制 来源、版本、安装日志可追溯 禁止使用临时下载文件覆盖
签名状态 spctl 显示已接受并通过 notarization 按官方安装说明处理系统授权
服务启动 运行域、执行用户和配置路径明确 不要只依赖控制台在线状态

官方安装说明提供了 spctl -a -vvv -t install 用于检查签名与 notarization 状态。这个检查只能证明二进制获得系统认可,不能证明任务运行权限、钥匙串访问或项目路由正确。

03逐项验证配置语义,而不是只复制 config.yaml

旧配置文件可以作为 Machine Runner 3 的迁移输入,但迁移验收仍应逐项对照Machine Runner 3 配置参考。重点不是把字段重新抄一遍,而是确认每个字段在企业节点上的实际后果。

需要重点检查的字段和假设包括:

  1. working_directory 是否位于专用磁盘或专用用户目录,权限是否只授予 Runner 执行账号;
  2. cleanup_working_directory 是否启用,并在任务成功、失败、取消三种状态下都执行;
  3. command_prefix 是否改变了任务执行用户,尤其要确认它是否影响钥匙串、Xcode 工具链和私有网络客户端;
  4. 任务最长运行时间是否设置,超时后是否会留下子进程、临时文件或锁;
  5. task-agent 缓存是否可能保留旧平台或旧版本行为;
  6. 配置中的绝对路径、环境变量和日志路径是否仍适用于新安装方式;
  7. 认证令牌是否只存在于配置文件或受控密钥存储中。

Machine Runner 3 的任务配置至少要明确 machine: true 和目标 resource_class,否则任务可能不会进入预期的自托管 Mac 节点。

基准任务应避免直接使用生产凭证,建议只验证以下链路:

  • checkout 私有测试仓库;
  • 打印 macOS、芯片架构和 Xcode 版本;
  • 执行一个不会发布的构建或单元测试;
  • 检查日志是否完整回传;
  • 检查退出码是否准确;
  • 上传一个无敏感信息的测试产物;
  • 结束后检查工作目录是否清空。

这一步可以尽早发现“服务在线但任务无法运行”的问题,例如执行账号不同、路径不存在、Xcode 许可未接受、钥匙串不可访问,或任务实际被发送到了错误的 resource class。

04收紧任务路由与 Runner 权限

CircleCI 的 resource class 既用于识别自托管 Runner 池,也用于把任务路由到对应节点。迁移试点时,建议为新节点创建独立的 resource class,而不是直接复用生产节点的标签。这样可以把验证任务限制在试点 Mac 上,避免新旧节点同时处理同一类发布任务。

CircleCI 的配置参考说明,如果没有显式设置 resource_class,平台可能使用默认值,而默认值可能发生变化。因此,迁移验收应把资源类写入项目配置并纳入代码审查,而不是依赖隐含默认行为。

路由验收至少应包括三组结果:

测试类型 期望结果 证据
允许项目 可信 iOS CI/CD 项目能领取任务 项目 ID、resource class、任务日志
拒绝项目 未授权项目无法调用该 Mac resource class 配置策略结果或拒绝记录
错误标签 使用错误 resource class 的任务不进入试点节点 任务路由和 Runner 日志

如果组织使用配置策略,应限制哪些项目可以调用指定的自托管 resource class。可参考CircleCI 自托管 Runner 配置策略文档按项目 ID 区分生产发布流水线与普通测试任务,避免非可信项目进入承载签名凭证的 Mac。

认证令牌不能进入代码仓库、共享脚本、构建日志或可被普通项目读取的环境变量。令牌只用于 Runner 领取与执行任务,权限边界仍取决于节点执行用户本身;执行账号拥有过宽的本地权限时,单独保护令牌并不能完成隔离。

05用交叉测试证明工作区和签名材料能清理

对于 iOS CI/CD 节点,最容易被低估的风险不是构建失败,而是上一个任务留下的代码、环境变量或签名文件被下一个任务读取。

cleanup_working_directory: true 是必要条件,但不能单独作为隔离证明。企业还应检查:

  • Git checkout 目录与隐藏文件;
  • Swift Package、CocoaPods 或其他依赖缓存;
  • SSH checkout key;
  • 临时 Keychain 及其解锁状态;
  • Provisioning Profile、证书和导出的构建产物;
  • TMPDIR、用户目录和脚本自行创建的临时目录;
  • 任务失败或被取消后仍在运行的子进程。

建议准备两个互不信任的测试项目。项目 A 在任务中写入唯一标记、环境变量、临时签名材料和测试代码;任务完成后,项目 B 尝试扫描工作目录、缓存、钥匙串和常见临时路径。如果项目 B 能读取项目 A 的任何敏感内容,节点不能进入生产发布池。

生产签名节点应优先采用专用运行账号和专用 resource class,不要把普通测试项目与生产签名任务放在同一个信任域。若必须共享 Mac,应至少在组织策略、项目白名单、执行用户和任务结束清理四个层面同时设限。

06通过重启、故障和回滚测试后再放量

macOS 节点在控制台显示在线,只能说明某个时间点的 Runner 注册状态正常。真正的生产验收要证明节点经历重启、进程异常退出、网络短时中断和任务超时后,仍然能够恢复接单,并且不会触发重复发布。

macOS 安装文档区分了 GUI 和非 GUI 会话的服务启动方式,并使用 launchctl bootstrapenablekickstartprint 检查服务状态。远程或无图形界面的构建机应特别验证 user 域服务,不能只在人工登录的 GUI 会话里测试。

建议按以下顺序执行最小故障测试:

  1. 远程重启 Mac,确认系统恢复后 Runner 自动启动;
  2. 检查服务是否进入正确的 user 或 GUI 域;
  3. 运行一条无发布动作的基准流水线;
  4. 手动终止 Runner 进程,确认服务能否拉起;
  5. 短暂阻断网络,再恢复网络并观察接单状态;
  6. 让测试任务超时,检查子进程、工作目录和签名材料;
  7. 在任务执行期间重启或切换备用节点,确认不会产生重复发布;
  8. 执行回滚,验证旧服务或备用节点确实能够接管任务。

截至 2026 年 8 月 21 日,CircleCI 官方 changelog 显示 Runner 3.1.11 于 2026 年 7 月 29 日发布,3.1.10 曾修复缓存 task-agent 可能导致任务出现“不支持平台”错误、需要重启进程才能恢复的问题。版本信息和已知修复应在迁移变更单中留档,不能只写“安装最新版”。相关版本变更应以CircleCI Runner 官方 changelog为最终核对依据。

故障场景 需要观察的指标 放量判断
Mac 重启 服务自动启动、Runner 重新注册、任务可领取 任一环节失败则限制放量
Runner 进程退出 自动恢复、无重复任务、日志连续 无恢复机制则保留备用节点
网络短断 恢复接单、任务状态明确 状态不确定时禁止承载发布
任务超时 子进程退出、工作区清理、凭证失效 有残留则退回整改
回滚 旧服务或备用节点可独立接管 回滚依赖人工临时操作则不准入

迁移验收决策条件

  • 服务残留已清理、试点 resource class 路由正确、两个测试项目无法交叉读取代码和签名材料,且重启后能自动接单,进入小批量生产切换。
  • 任务能够成功构建,但凭证清理、执行用户或重启恢复仍没有证据,只保留在隔离试点,不得承载生产发布。
  • 新 Runner 无法稳定启动,或回滚必须在唯一生产 Mac 上临时修改多套启动方式,立即停止迁移,切回备用节点或恢复旧服务。
  • 生产节点队列持续积压,但单节点构建结果稳定,优先增加隔离的 Mac Runner 容量,而不是提高同一节点的权限范围或并发风险。
  • 团队无法提供专用签名账号、项目白名单和任务清理证据,不应把通用共享 Mac 作为生产签名节点。

对于需要先建立隔离试点的团队,可先了解 NUKCLOUD 的远程 Mac 使用方式,再根据团队所在区域查看远程 Mac 节点选项。这里的重点不是替代现有生产架构,而是为迁移提供一台不影响主流水线的验证节点。

07用一张验收卡决定“通过、限量或回退”

最终验收记录不应只有“Runner Online”截图,而应保存以下证据:

  • [ ] 旧 launch agent 服务、plist、进程和安装目录已核查;
  • [ ] 新二进制来源、版本、安装日志和签名状态可追溯;
  • [ ] config.yaml 的路径、执行用户、清理策略和任务超时已逐项复核;
  • [ ] 试点 resource class 只允许指定项目调用;
  • [ ] 认证令牌没有出现在仓库、脚本和构建日志;
  • [ ] 两个隔离项目交叉读取测试未发现代码或凭证残留;
  • [ ] checkout、构建、日志、退出码和产物回传全部通过;
  • [ ] Mac 重启后 Runner 自动恢复;
  • [ ] Runner 进程退出、网络短断和任务超时均有处理结果;
  • [ ] 回滚责任人、备用节点和恢复命令已经演练;
  • [ ] 真实基准流水线的排队、成功率、失败原因和人工恢复动作已记录。

结论可以分为三档:

验收结论 适用条件 后续动作
通过 核心功能、隔离、恢复和回滚证据齐全 分批切换生产节点
限制放量 构建可用,但容量或恢复证据不足 仅承载非关键任务并补测
退回整改 服务冲突、凭证残留、错误路由或回滚失败 停止迁移,恢复备用路径

企业不应为了追求一次性完成而牺牲回滚能力。固定生产节点适合稳定、低变化的发布流水线;当团队需要同时验证多个 Xcode 工具链、临时增加 iOS CI/CD 容量,或不希望改造唯一的 Mac 打包机时,隔离的远程 Mac 可以作为迁移试点和弹性补充,而不是直接替代所有长期基础设施。

08常见问题

CircleCI launch agent 迁移到 Machine Runner 3,最小操作路径是什么?

最小路径是:盘点旧节点与依赖流水线,停止并删除旧 launch agent 服务,安装 Machine Runner 3,迁移配置文件,核验签名与 notarization,使用独立 resource class 运行无生产凭证的基准任务,最后执行重启、清理和回滚测试。官方迁移页给出了 macOS 的服务卸载路径,但企业仍需补充权限和安全验收。

为什么 Machine Runner 3 重启后没有自动接单?

常见原因包括 plist 放置位置与运行域不匹配、服务只在人工登录的 GUI 会话中启动、执行用户无法读取配置文件,或启动后无法访问工作目录和网络。应使用 launchctl print 检查实际服务域,再验证配置路径、执行账号和网络访问,而不是只刷新控制台页面。

原有 config.yaml 直接复制后,为什么任务仍可能失败?

配置文件 1:1 兼容主要表示字段可以作为迁移输入,并不保证路径、用户、权限、日志行为和钥匙串环境一致。旧配置中的工作目录可能指向已删除路径,旧的 logging 配置也可能不适用于新 Runner;因此必须用基准任务验证 checkout、构建、日志、退出码和产物回传。

怎样验证自托管 Mac Runner 没有残留代码和签名凭证?

不能只检查任务结束时的工作目录。应使用两个隔离测试项目交叉验证代码目录、缓存、SSH checkout key、临时 Keychain、Provisioning Profile、环境变量和构建产物,并覆盖成功、失败、取消和超时场景。对生产签名节点,还应限制项目白名单并采用专用运行账号。

09验收通过后,如何选择长期节点方案

如果现有方案是把唯一的物理 Mac 直接改造成 Machine Runner 3,它的真实缺点通常是:迁移期间没有隔离试点,重启和回滚依赖人工操作;固定设备容量无法快速应对发布高峰;硬件故障、系统升级和签名环境维护会直接影响团队流水线;普通测试项目与生产签名任务也容易被放进同一信任域。

因此,更稳妥的做法是先租赁一台与生产节点隔离的远程 Mac,完成真实流水线、重启恢复、凭证清理和任务路由验证;通过验收后,再依据队列长度、发布 SLA 和签名隔离要求决定长期节点数量。对于需要临时算力、迁移试点或弹性补充的团队,NUKCLOUD 的远程 Mac 可以作为不改动唯一生产构建机的验证入口;如果团队需要长期满负载运行、物理接口或完全自主管理硬件,自购 Mac 仍可能更合适。

FAQ常见问题

旧版 CircleCI launch agent 迁移到 Machine Runner 3 时,应该先改配置还是先停服务?
应先隔离节点并停止、卸载旧服务,再安装 Machine Runner 3。官方文档说明旧配置文件具备 1:1 兼容性,但这不代表新旧服务可以同时运行。迁移时还要核对工作目录、执行用户、日志路径和启动域,避免两个服务争抢任务或读取不同凭证。
Machine Runner 3 在 macOS 重启后没有自动接单,通常应该检查什么?
先检查 plist 是否放在与运行方式匹配的 LaunchAgents 目录,再检查 bootstrap、enable 和 kickstart 状态。无图形界面的远程节点尤其要验证 user 域服务,而不是只在 GUI 域中启动。最后确认执行用户登录后仍能读取配置文件、工作目录和钥匙串。
旧的 config.yaml 能否直接用于 Machine Runner 3?
可以作为迁移起点,但不能把兼容性声明当作生产验收结论。应逐项检查 working_directory、cleanup_working_directory、command_prefix、任务最长运行时间、task-agent 缓存、环境变量和文件权限。至少运行一条不含生产凭证的基准任务,验证 checkout、构建、日志和产物回传。
如何证明自托管 Mac Runner 没有残留代码和签名凭证?
准备两个隔离测试项目,让第一个项目写入代码、环境变量、临时 Keychain 和签名材料,任务结束后再由第二个项目尝试读取。检查工作目录、缓存、SSH checkout key、Provisioning Profile、构建产物和钥匙串,而不是只观察任务是否成功。生产签名节点应使用专用账号与专用 resource class。