配了三年 self-hosted runner,今天才发现「在线」和「能跑任务」从来就是两件事——GitHub 今天把这件事从根上钉死了

配了三年 self-hosted runner,今天才发现「在线」和「能跑任务」从来就是两件事——GitHub 今天把这件事从根上钉死了

你有一个 runner,控制台显示 Idle,绿色在线,一切正常。但任务进来的时候,它不接单。没有任何报错,就是不接单。

这不是网络问题,也不是权限问题。这是 GitHub Actions 刚刚补上的一张三年老漏洞:runner 显示在线,不代表它还能跑任务。

GitHub 在 2026 年 9 月 25 日对 GitHub Enterprise Cloud 正式执行自托管 runner 版本强制要求。这不是一次常规更新,这是一个平台行为的根本性改变——而且很多团队到现在还没意识到。

注册版本和执行版本,是两个门槛

GitHub 这次说的版本要求有两层:

第一层是注册门槛:runner 必须升级到 2.329.0 或更高版本,才能在新的 Actions 架构上完成注册或重新注册。这在 2026 年 8 月已经开始分阶段执行 brownout,9 月 25 日彻底强制。

第二层是执行门槛(这是大多数团队不知道的):runner 注册成功不代表它能一直执行任务。GitHub 要求 runner 必须在新版本发布后的 30 天内完成升级,否则 Actions 会停止向该 runner 排队任务。

换句话说:一个 runner 装好了 2.329.0,然后关闭自动更新,永久停留在那个版本——它可以成功注册,显示在线,但 30 天后它就会静默停止接单。没有报错,没有告警,任务就是静静地排队。

这意味着:你不能把 runner 当作”装一次用三年”的虚拟机。它现在是需要持续维护的运行时环境。

为什么是 30 天?

GitHub 在 2024 年初对 Actions 后端服务进行了架构重建,新架构现在每天处理超过 1.2 亿次任务,支持企业每分钟启动比之前多 7 倍的任务。这套新架构在 2026 年逐步完成迁移,版本强制执行是最后一步——旧版 runner 与新架构不兼容,不能再被支持。

30 天是一个平衡点:既给了维护团队足够的响应时间,又确保没有 runner 能长期游离在安全更新之外。

这些场景会直接踩坑

场景一:容器镜像里的 runner 版本是固定的。CI 用 Dockerfile 构建 runner 镜像,版本写死在 FROM 里,镜像发布后再也没动过。这种 runner 注册没问题,30 天后任务就停了。

场景二:自动更新被禁用了。有些团队因为网络限制或合规要求,用 –disableupdate 参数禁用了 runner 的自动更新。这类 runner 必须手动定期升级,否则一定会踩线。

场景三:Golden Image 一直没重建。企业用 Packer 或镜像流水线生成 runner 镜像,每次发布新版本都要重建镜像、打标签、灰度发布。很多团队的流水线里根本没有这个步骤。

怎么查你现在有多少 runner 在危险状态?

GitHub 在 2026 年 3 月把 runner 版本信息加入了 REST API,可以用这个命令批量导出:

gh api --paginate 
  /orgs/YOUR_ORG/actions/runners 
  --jq '.runners[] | [.name, .os, .status, .version] | @tsv'

输出会列出每个 runner 的名称、操作系统、状态和当前版本。然后对照 actions/runner 的 releases 页面,看当前最新版本是哪个,算一下差距是否超过 30 天。

三步修复策略

第一步,确认哪些 runner 需要升级。用上面的 API 导出清单,按版本分组。版本低于当前最新版本 30 天以上的,都需要处理。

第二步,对于自动更新正常的 runner,验证网络路径。runner 的自动更新需要访问 releases.githubusercontent.com 和 objects.githubusercontent.com,如果 runner 在受限网络段,要确认出站流量没有被防火墙拦截。很多 runner “自动更新失败” 的真实原因是网络不通。

第三步,对于禁用自动更新的 runner,把 runner 版本纳入镜像更新流程。重建 Golden Image 时,先查一下最新 runner 版本,把版本号写入 Dockerfile,然后用新镜像灰度替换旧 runner。

如果你是 Actions Runner Controller(ARC)管理的集群,需要升级 ARC 本身到 0.14.0 或更高版本,新版 ARC 已经适配了 30 天更新要求的语义。

这件事的本质变化

自托管 runner 正在从”一次配置永久使用”的静态资产,变成”需要持续验证可用性”的动态状态。一个 runner 今天能注册,不等于 30 天后还能执行任务。这和 GitHub 托管 runner 的行为完全不同——托管 runner 是 GitHub 维护的,自托管 runner 的版本新鲜度现在是你的责任。

这不是一个可以推迟到下个季度的优化项。9 月 25 日 full enforcement 之后,不符合要求的 runner 会直接从队列里消失,而且没有任何宽限期。

现在去跑一遍那个 API 命令,比任何文档都有说服力。

评论区

0 条评论

登录后可评论。