团队往往会过早地把目光投向 Actions Runner Controller。最常见的触发点,是对 GitHub Actions 启动速度、包安装时间,或者偶发资源上限的不满。可在把 Kubernetes 引入问题之前,GitHub 实际上已经给了两层摩擦更低的选项:标准 GitHub-hosted runners,以及 larger GitHub-hosted runners。[1][2]

这一层区分很重要,因为 larger runners 已经覆盖了许多平台团队口中“需要自托管”的理由。GitHub 自己的文档列出的能力,包括静态 IP、Azure 私有网络、runner groups、autoscaling、GPU 机型,以及 custom images。[1][2] 如果你的抱怨主要是“作业需要更大的机器”或者“我们想把 VM 镜像预先做热”,ARC 很容易变成一道解错题的答案。

更准确的迁移问题其实更窄:runner 的落位本身,什么时候开始成为平台架构的一部分。ARC 的价值线,是从这里才真正出现。GitHub 将 ARC 描述为面向 self-hosted runners 的参考级 Kubernetes autoscaling 方案,并明确建议把它留给已经拥有 Kubernetes 基础设施、同时团队也具备 Kubernetes 经验的组织。[3][4] 从另一层看,ARC 并非 hosted runners 的通用升级版,它是一项 control plane 选择。

配图说明:题图采用 Wikimedia Commons 上的真实服务器机架照片,而并非示意图,因为这场迁移最后讨论的始终是现实容量。走向 ARC 以后,队列、镜像、网络路径与故障处理都会变成基础设施治理的一部分,而不再是托管服务默认值。[7]

在 ARC 之前,你已经拥有什么

先看基线。标准 GitHub-hosted runners 提供的是较为干净的执行环境,runner 应用与常见工具已经预装,镜像维护与升级也由 GitHub 处理。[1] 文档还写明,GitHub 自有镜像的软件集每周更新一次,而每次工作流实际命中的工具清单,也能在日志里直接看到。[1] 对大多数仓库来说,这是一套很强的默认值,因为它让构建表面保持可丢弃状态。

再往上一层,是 larger runners。它们依然由 GitHub 托管,却把那些经常被拿来当作“必须自托管”理由的能力提前补上:更多 CPU、RAM 与磁盘,静态 IP,Azure 私有网络,autoscaling,runner groups,GPU 机型,以及 custom VM images。[1][2] 这意味着相当多“我们需要更多控制”的诉求,其实还没有走到必须承接 cluster operations 的地步。

最简单的判断规则可以写成这样:

只要这两层已经覆盖需求,ARC 就只是额外负担。

ARC 真正开始成立的地方

GitHub 在 self-hosted runner 文档里把价值讲得很直白:你可以控制硬件、操作系统、软件工具,也可以直接使用公司已经维护并持续付费的机器与服务。[3] ARC 做的事,是把这种 self-hosted 的自由度,进一步组织成一套 Kubernetes 原生的 autoscaling 系统。[4]

这通常只会在三种场景里变得重要。

第一种,是数据或服务的重力。如果作业必须靠近 cluster 内部服务、私有制品镜像、内部 registry,或者一些不适合向 hosted VM 暴露的东西向流量,ARC 能让执行面继续留在同一片运维语境里。[3][4]

第二种,是既有基础设施的经济性。从 GitHub 的计费语境看,self-hosted runners 本身免费,可机器与运维都要团队自己承担。[3] 只有在你本来就有 cluster 容量、采购路径,或者现成硬件布局,使“复用已有系统”比继续购买托管 runner 分钟更合算时,这条路才会站稳。

第三种,是把队列策略写成平台策略。ARC 不只是“把 runners 放进 Kubernetes”。它提供 runner scale sets,可以用 scale-set 名称或 labels 作为 runs-on 目标,也能通过 minimum 与 maximum runner 设置来决定常驻热容量与并发边界。[5][6] 当 runner 池需要和 namespace、secrets、硬件层级或内部团队边界对齐时,ARC 给出的控制面,会比一堆长寿命 runner 更清楚。

这些理由都成立。仅仅因为“npm install 太慢”,并不成立。

ARC 会把什么真正改成运维问题

GitHub 的架构说明把 ARC 的形状写得很具体。controller 负责管理 scale set,listener 通过长轮询等待 GitHub Actions 的 Job Available 消息,ephemeral runner pods 则在需求到来时,使用 just-in-time 注册token被创建出来。[4] 如果 runner pod 创建失败,会重试最多 5 次;如果始终没有 runner 接下作业,Actions 服务会把分配维持到 24 小时 的边界。[4]

这套结构带来两类好处。

一类是清洁性。GitHub 在 autoscaling 参考文档里明确推荐用 ephemeral self-hosted runners 做 autoscaling,并指出 persistent autoscaling 并不推荐,因为 ephemeral runners 能保证一个 runner 只执行一个作业,也更容易把“干净环境”自动化地维持住。[3] ARC 和这一模型天然契合。

另一类,是队列控制。在部署文档里,minRunnersmaxRunners 让你决定 scale set 是常驻零容量、保留预热容量,还是主动设定并发上限。[5] GitHub 还给出了一个维护场景:把两者都设成 0,就可以停止创建新的 runner pods,从而把新任务队列排空。[5] 这类能力,才是平台团队真正关心的开关。

可运维税也会立刻到来。

GitHub 自己的指导已经写明,runner pods 最好与 operator pods 分属不同 namespace,Kubernetes secrets 应当通过引用传入而并非明文塞进命令行,生产工作负载也应当与这些 runner 隔离,因为 Actions workflows 的设计前提就是允许执行任意代码。[5] 同一页还强调,进入生产之前,你应当已经建立 controller、listener 与 ephemeral runners 的日志收集与保留机制。[5]

接着是生命周期维护。self-hosted runners 把操作系统补丁与软件维护重新放回你的团队手里。[3] 如果你关闭自动更新,GitHub 要求在 runner 新版本发布后的 30 天内完成更新,否则作业将不再被派发到这些 runner 上。[3] 这并非注脚,而是平台契约的一部分。

一条通常更扎实的迁移路径

更干净的顺序,应该是分阶段推进,而并非带着立场迁移。

  1. 先确认标准 hosted runners 是否已经能用更少的制度成本解决问题。[1]
  2. 如果痛点是机器规格、静态 IP、Azure 私网,或者镜像预热时间,先测试 larger runners。[1][2]
  3. 只有在 runner 的落位、既有 cluster 的经济性,或者 Kubernetes 内部的队列策略才是真正需求时,再进入 ARC。[3][4][5]

真正做 ARC 试点时,第一条跑道应当尽量收窄:

这样的顺序会让迁移保持诚实。它迫使团队先证明 ARC 带来的,是结构性收益,而并非用更复杂的方法去运行原来那批作业。

一个足以叫停迁移的反证

如果团队对迁移的解释,只能落在启动速度、预装工具,或者“更大算力”这些词上,那就先停下来,先测试带有 custom images 的 larger runners。[1][2] GitHub 已经把这条路做成了托管服务。ARC 只有在 runner fleet 必须像 cluster 的一部分那样被治理时,才真正值回代价。

收束

当 CI 执行面已经变成基础设施落位问题,ARC 才是对的选择:私网可达性、既有 cluster 的经济性、明确的队列策略,以及把 ephemeral runners 作为 Kubernetes 工作负载来治理。[3][4][5][6] 如果真实需求只是更强算力、更可复现的镜像,或者更短的准备时间,托管的 GitHub-hosted 选项已经覆盖了很大一块区域。[1][2]

真正有用的迁移边界就在这里。不要因为 ARC 看起来更像平台而采用它;要在 runner 本身已经成为平台的一部分时,再采用它。

来源

  1. GitHub Docs,《GitHub-hosted runners》——托管 VM 模型、每周镜像更新、larger runner 的 custom images,以及工作流连续性说明。
  2. GitHub Docs,《Larger runners》——静态 IP、Azure 私有网络、autoscaling、groups、GPU 与计费模型。
  3. GitHub Docs,《Self-hosted runners reference》——控制权取舍、面向 Kubernetes 团队的 ARC 建议、ephemeral runner 指导、队列时序与更新要求。
  4. GitHub Docs,《Actions Runner Controller》——ARC 架构、listener 长轮询流程、JIT 注册、重试行为与 scale-set 模型。
  5. GitHub Docs,《Deploying runner scale sets with Actions Runner Controller》——namespace 隔离、secret 处理、日志保留、runner groups,以及 minRunners / maxRunners 行为。
  6. GitHub Docs,《Using Actions Runner Controller runners in a workflow》——如何用 scale-set 名称或 labels 作为 runs-on 目标。
  7. Wikimedia Commons,《File:Server Rack (54126210834).jpg》——本文题图所用的纪实服务器机架照片。