2. GitLab Runner 部署与注册
在 GitLab CI/CD 中,流水线的定义写在 .gitlab-ci.yml 里,但真正把 script 跑起来的,是 GitLab Runner。Runner 是一个独立于 GitLab 服务端的进程,它主动向 GitLab 拉取待执行的作业(Job),在本地或容器中执行,再把日志和结果回传。理解 Runner 的类型、安装注册方式、标签与并发控制,以及不同执行器的差异,是搭建自动化测试与发布流水线的基础。
一、Runner 类型:共享、专用与群组
从归属范围看,Runner 主要分为三类。共享 Runner(Shared Runner)由 GitLab 管理员注册,所有项目都可以使用,适合小团队快速起步,但资源竞争激烈、环境不可控。专用 Runner(Specific Runner)注册到某个具体项目,只服务该项目,适合需要特定依赖、特定网络或特定硬件的场景。群组 Runner(Group Runner)注册到某个群组,群组下所有项目共享,是介于两者之间的折中方案,常用于一个团队维护多个微服务仓库的情况。
选择原则很直接:如果作业需要访问内网数据库、需要 GPU、需要 macOS 或 Windows 环境,或者需要缓存大量依赖,就应该使用专用或群组 Runner;如果只是跑轻量的单元测试和构建,共享 Runner 足够。实际生产中常见的是“共享 Runner 跑通用任务 + 专用 Runner 跑部署和集成测试”的混合模式。
二、安装与注册
以 Linux 上安装 GitLab Runner 为例,官方仓库方式最稳妥:
# 添加官方仓库并安装
curl -L "https://packages.gitlab.com/install/repositories/runner/gitlab-runner/script.deb.sh" | sudo bash
sudo apt-get install gitlab-runner
# 查看版本,确认安装成功
gitlab-runner --version
安装完成后需要注册。注册的本质是把 Runner 与 GitLab 实例建立信任关系,并给它分配标签和执行器。注册前先在 GitLab 项目或群组的 Settings → CI/CD → Runners 中获取注册令牌(Registration Token)。注册命令如下:
sudo gitlab-runner register \
--url "https://gitlab.example.com/" \
--registration-token "GR1348941xxxxxxxxxxxx" \
--executor "docker" \
--docker-image "alpine:latest" \
--description "docker-runner-for-test" \
--tag-list "docker,test,linux" \
--run-untagged="false" \
--locked="false"
其中 --tag-list 决定这个 Runner 能接哪些作业,--run-untagged 决定是否接受没有标签的作业。注册成功后,配置文件通常位于 /etc/gitlab-runner/config.toml,可以在这里调整并发数、缓存目录等参数。
三、标签与并发控制
标签(Tag)是作业与 Runner 之间的匹配规则。在 .gitlab-ci.yml 中给作业写 tags: [docker, test],GitLab 只会把该作业派发给同时带有这两个标签的 Runner。标签设计要避免过细或过粗:过细会导致某个 Runner 空闲而其他作业排队,过粗则会让不合适的作业落到错误环境上。常见做法是按“执行器类型 + 操作系统 + 用途”三层命名,例如 docker、linux、deploy。
并发控制有两个层面。第一层是 Runner 级别的 concurrent,写在 config.toml 的 [runners] 段或全局段,表示该 Runner 进程最多同时执行多少个作业。第二层是单个 Runner 的 limit,限制某个具体 Runner 配置能同时跑几个作业。如果一台机器 CPU 是 8 核,跑 Docker 执行器时通常把 concurrent 设为 4 到 8,具体取决于每个作业的资源消耗。设置过大反而会因为资源争抢导致作业超时。
concurrent 是否已被占满。四、执行器差异
执行器(Executor)决定作业在什么环境中运行,是 Runner 配置中最关键的选择。常见执行器对比如下:
| 执行器 | 隔离性 | 典型用途 | 注意事项 |
|---|---|---|---|
| shell | 无 | 简单脚本、固定机器 | 依赖直接装在宿主机,易污染 |
| docker | 容器级 | 构建、单元测试 | 需处理镜像拉取与缓存 |
| docker-machine | 虚拟机级 | 需要独立主机的场景 | 已逐步被替代 |
| kubernetes | Pod 级 | 弹性伸缩的集群环境 | 配置复杂,依赖 K8s |
| parallels / virtualbox | 虚拟机级 | 需要完整 OS 的测试 | 资源开销大 |
对大多数自动化测试与发布流水线来说,docker 执行器是首选:环境可复现、启动快、清理方便。它的工作方式是每个作业启动一个容器,把仓库代码挂载进去,在容器内执行 script。如果作业需要 Docker 命令本身(例如构建镜像),可以在 config.toml 中挂载 /var/run/docker.sock,或使用 docker:dind 服务,但要注意安全边界。
下面这张图把 Runner 的注册关系、标签匹配与执行器选择串在一起,帮助建立整体认识:
五、实践中的配置要点
在真实项目中,建议把 Runner 配置纳入版本管理。例如用 Ansible 或 Terraform 统一安装 Runner,用模板生成 config.toml,避免手工修改导致环境漂移。对于 Docker 执行器,可以在 config.toml 中配置 pull_policy = "if-not-present",减少重复拉取镜像的时间;同时设置 cache_dir 和 volumes,让依赖缓存和构建产物在作业之间复用。
另外要注意,注册到项目还是群组会影响令牌的可见范围。项目级 Runner 的令牌只对单个项目有效,群组级 Runner 的令牌对整个群组有效。如果团队有多个仓库需要共用同一套 Runner,优先注册到群组,再通过标签区分不同作业的用途,这样既减少重复部署,又保留调度灵活性。
最后,Runner 的版本应与 GitLab 服务端保持兼容。GitLab 官方建议 Runner 版本不低于服务端版本,且不要跨越大版本升级。升级前先在测试项目上验证,确认执行器、缓存和标签行为没有变化,再推广到生产 Runner。