4. Runner注册与配置管理

在 GitLab Runner 的日常运维中,注册与配置管理是决定集群能否稳定扩展、能否安全隔离、能否快速排障的核心环节。很多团队在 Runner 数量少时靠手工注册还能应付,一旦扩展到几十甚至上百个 Runner,令牌管理混乱、配置漂移、优先级理解错误就会集中爆发。本节围绕注册令牌(registration token)、认证令牌(authentication token)、配置模板、全局配置与单 Runner 配置的优先级,梳理一套可落地的治理策略。

一、两种令牌的本质区别

GitLab Runner 注册过程中涉及两类令牌,理解它们的生命周期是治理的起点。

注册令牌(registration token)是项目、群组或实例级别的“入场券”。它用于向 GitLab 申请创建一个新的 Runner,注册成功后 GitLab 会返回一个独立的认证令牌。注册令牌的特点是:同一令牌可被多次使用来注册多个 Runner,因此一旦泄露,攻击者可以注册任意数量的 Runner 接入你的 GitLab,风险极高。GitLab 15.10 之后引入了新的 Runner 认证流程,注册令牌逐步被“Runner 认证令牌”取代,但存量环境仍大量存在。

认证令牌(authentication token)是每个 Runner 独有的身份凭证,通常以 glrt- 开头(新流程)或形如 xxxxx 的字符串(旧流程)。它写入 Runner 的 config.toml,用于 Runner 与 GitLab 之间的每次通信鉴权。认证令牌与单个 Runner 一一对应,泄露后影响范围限于该 Runner 本身,但仍可能被用于窃取作业产物或注入恶意作业。

注册令牌应视为“一次性或短期凭证”,注册完成后立即轮换或禁用;认证令牌应视为“长期密钥”,纳入密钥管理系统并定期轮换。两者都不应硬编码在公开仓库或镜像中。

二、配置模板与配置层级

Runner 的配置最终落在 config.toml 中,但它的来源可能有多层:全局配置、模板配置、单 Runner 配置。理解优先级是避免“改了不生效”的关键。

典型的优先级从低到高为:全局默认配置 < 配置模板 < 单 Runner 配置。也就是说,当同一参数在多处出现时,越靠近具体 Runner 的定义越优先。例如全局设置了 concurrent = 10,模板中某 Runner 设置了 limit = 3,则该 Runner 最多同时跑 3 个作业,而全局并发上限仍为 10。

配置模板通常通过 config.toml 的 [[runners]] 段复制生成,或在自动化脚本中用变量替换。治理策略上,建议把“所有 Runner 共有的参数”(如 url、executor、shell、builds_dir)放在模板层,把“单 Runner 特有参数”(如 tags、run_untagged、limit、environment)放在单 Runner 层。

Runner 注册与配置优先级治理视图 注册阶段 注册令牌 registration token gitlab-runner register 认证令牌 authentication token 配置层级(优先级由低到高) 全局默认配置 concurrent / check_interval 配置模板 url / executor / builds_dir 单 Runner 配置 tags / limit / environment 治理动作 注册后禁用注册令牌 认证令牌入密钥库并轮换 模板版本化 + 单 Runner 覆盖审计 优先级冲突示例:同一参数在多层出现时的生效结果 参数 全局配置 模板配置 单 Runner 配置(生效) concurrent 10 — 10(全局生效) limit — 5 3(单 Runner 覆盖) tags — docker docker, gpu(追加)

三、注册令牌的治理策略

注册令牌的风险在于“可重复使用”。治理上建议遵循以下原则:

  • 最小权限:优先使用项目级或群组级注册令牌,避免使用实例级令牌。实例级令牌一旦泄露,影响整个 GitLab 实例。
  • 短期有效:注册窗口期结束后立即在 GitLab 界面禁用或轮换注册令牌。GitLab 15.10+ 推荐使用 Runner 认证令牌(glrt-)替代注册令牌,它天然与单个 Runner 绑定。
  • 自动化注册:通过 CI/CD 或配置管理工具(如 Ansible、Terraform)调用 gitlab-runner register,令牌从密钥管理系统注入,不落盘、不打印。
  • 审计:记录每次注册的时间、操作者、Runner 名称、标签、执行器类型,便于事后追溯。

一个典型的自动化注册命令示例如下(令牌通过环境变量注入,示例值仅为占位):

export REGISTRATION_TOKEN="GR1348941xxxxxx"
export RUNNER_TAG_LIST="docker,linux"
gitlab-runner register \
  --non-interactive \
  --url "https://gitlab.example.com/" \
  --registration-token "$REGISTRATION_TOKEN" \
  --executor "docker" \
  --docker-image "alpine:3.19" \
  --description "runner-docker-01" \
  --tag-list "$RUNNER_TAG_LIST" \
  --run-untagged="false" \
  --locked="false" \
  --access-level="not_protected"

注册完成后,config.toml 中会生成对应的 [[runners]] 段,其中 token 字段即为认证令牌。此时应立即从环境中清除注册令牌变量。

四、配置模板与单 Runner 覆盖的治理

配置模板的价值在于“一次定义、多处复用”,但滥用模板会导致单 Runner 的特殊需求被淹没。建议采用“模板 + 覆盖”的分层结构:

  1. 全局层:只放与所有 Runner 无关的调度参数,如 concurrent、check_interval、log_level。
  2. 模板层:按执行器类型或环境划分模板,如 docker-template.toml、shell-template.toml,包含 url、executor、builds_dir、cache_dir 等共性参数。
  3. 单 Runner 层:只写差异项,如 tags、limit、environment、docker.privileged。差异项越少,配置漂移越容易发现。

为了验证优先级是否符合预期,可以用 gitlab-runner list 或 gitlab-runner verify 查看实际加载的配置。更严格的做法是在 CI 中加入配置校验步骤,例如用 tomlq 或自定义脚本检查每个 Runner 的 limit 是否超过全局 concurrent,以及 tags 是否与预期一致。

一个实用的检查规则:单 Runner 的 limit 之和不应超过全局 concurrent,否则部分 Runner 会长期排队。例如全局 concurrent = 10,三个 Runner 的 limit 分别为 5、5、5,总和 15 大于 10,说明资源被超卖,需要调整。

五、配置漂移与轮换

配置漂移是指实际运行的 config.toml 与版本库中的模板不一致。常见原因包括:手工修改未回写、模板更新未重新下发、单 Runner 覆盖被误删。治理手段包括:

  • 将 config.toml 的生成过程纳入版本控制,模板和变量文件都提交到 Git。
  • 用配置管理工具定期下发并比对,发现差异时告警而非静默覆盖。
  • 认证令牌轮换时,先更新密钥库,再滚动重启 Runner,最后验证作业可正常领取。

轮换认证令牌的典型流程是:在 GitLab 中为 Runner 生成新令牌 → 更新 config.toml 中的 token → 重启 Runner 服务 → 触发一个测试作业确认 Runner 在线且能执行。旧令牌在确认新令牌生效后再禁用,避免服务中断。

六、治理策略小结

把上述内容归纳为可执行的治理策略:注册令牌“用完即禁”,认证令牌“入库存管、定期轮换”;配置模板“分层复用”,单 Runner 配置“只写差异”;优先级“越具体越优先”,并用自动化校验防止超卖和漂移。这样既能支撑 Runner 集群的横向扩展,又能在出现异常时快速定位是令牌问题、模板问题还是单 Runner 覆盖问题。

治理对象 风险 推荐动作 验证方式
注册令牌 可重复注册,泄露后大量恶意 Runner 接入 注册后立即禁用或轮换,优先使用项目/群组级 GitLab Runner 列表无未知 Runner
认证令牌 长期有效,泄露后可窃取作业产物 存入密钥库,定期轮换,不硬编码 轮换后测试作业可正常执行
配置模板 模板更新未下发导致配置漂移 版本化模板,定期比对下发 config.toml 与模板差异告警
单 Runner 覆盖 limit 之和超过 concurrent 导致排队 只写差异项,CI 中校验 limit 总和 gitlab-runner list 显示实际 limit

掌握这些优先级与治理动作后,Runner 集群的注册与配置就不再是“黑盒”,而是可以审计、可以回滚、可以自动化的工程对象。