从零构建GitLab CI/CD流水线:Shell Executor实战指南
当代码提交频率从每周一次提升到每天数次时,手动测试和部署就会成为团队效率的瓶颈。去年我们的前端团队就遇到了这样的困境——每次合并代码前需要手动运行30分钟测试套件,导致功能交付延迟。直到我们为GitLab配置了基于Shell Executor的Runner,才真正实现了"提交即测试"的自动化流程。本文将分享如何从零开始搭建这套系统,让每次代码推送都能自动触发质量检查。
1. 环境准备与Runner安装
在开始配置Runner之前,需要确保你的GitLab服务器已经正常运行。我们推荐使用至少8GB内存的服务器,特别是当需要同时运行多个Runner任务时。通过以下命令可以快速检查服务器资源使用情况:
free -h df -h安装GitLab Runner的步骤因操作系统而异。对于CentOS/RHEL系统,建议使用官方仓库安装最新稳定版:
# 添加GitLab Runner官方仓库 curl -L https://packages.gitlab.com/install/repositories/runner/gitlab-runner/script.rpm.sh | sudo bash # 执行安装 sudo yum install gitlab-runner对于Ubuntu/Debian系统,安装过程类似:
# 添加仓库 curl -L https://packages.gitlab.com/install/repositories/runner/gitlab-runner/script.deb.sh | sudo bash # 安装 sudo apt-get install gitlab-runner安装完成后,Runner会作为系统服务自动启动。可以通过以下命令验证服务状态:
sudo gitlab-runner status提示:生产环境中建议为Runner创建专用用户,避免使用root权限执行构建任务。可以通过修改/etc/gitlab-runner/config.toml文件中的"user"配置项实现。
2. Runner注册与项目配置
注册Runner是连接GitLab实例的关键步骤。首先需要在GitLab项目中获取注册所需的URL和token:
- 进入项目 → 设置 → CI/CD
- 展开"Runners"区域
- 复制"Set up a specific Runner manually"部分的URL和注册token
有了这些信息后,在服务器上执行注册命令:
sudo gitlab-runner register注册过程中需要提供以下信息:
| 配置项 | 示例值 | 说明 |
|---|---|---|
| GitLab实例URL | https://gitlab.example.com | 你的GitLab服务器地址 |
| 注册token | glrt-xxxxxx | 从项目设置获取的唯一token |
| 描述 | frontend-runner | 帮助识别Runner的说明文字 |
| Tag列表 | frontend,test | 用逗号分隔的标签,用于定向触发 |
| 执行器类型 | shell | 选择shell表示直接在主机执行 |
注册完成后,Runner会自动出现在项目设置页面。建议进行以下优化配置:
- 锁定到当前项目:避免Runner被其他项目占用
- 运行未标记的作业:允许不指定tag的任务使用此Runner
- 最大作业超时:根据项目需要设置合理值(默认3600秒)
可以通过编辑/etc/gitlab-runner/config.toml文件修改Runner的高级配置。例如设置并发数和检查间隔:
concurrent = 4 check_interval = 33. 编写高效的.gitlab-ci.yml文件
.gitlab-ci.yml是定义CI/CD流程的核心配置文件,采用YAML格式。下面是一个典型的前端项目配置示例:
stages: - install - test - build - deploy cache: key: ${CI_COMMIT_REF_SLUG} paths: - node_modules/ install_dependencies: stage: install script: - npm install tags: - frontend only: - merge_requests - master run_tests: stage: test script: - npm run test tags: - frontend artifacts: when: always paths: - coverage/ build_production: stage: build script: - npm run build tags: - frontend only: - master deploy_staging: stage: deploy script: - scp -r dist/ user@staging-server:/var/www/html tags: - frontend only: - master关键配置项解析:
- stages:定义流水线的阶段顺序
- cache:在不同任务间共享node_modules目录
- artifacts:保存测试报告等构建产物
- only/except:控制任务触发条件
注意:使用Shell Executor时,所有脚本命令都在Runner主机上直接执行,确保主机已安装所需工具(如npm、scp等)。
4. 高级配置与优化技巧
随着项目规模扩大,基础配置可能无法满足需求。以下是几个提升Runner效率的实用技巧:
4.1 资源隔离与并发控制
在config.toml中调整并发参数可以优化资源使用:
[[runners]] name = "high-memory-runner" limit = 2 [runners.machine] IdleCount = 0 MachineDriver = "docker" MachineName = "runner-%s" MachineOptions = [ "docker-options=--cpus=2 --memory=4g" ]4.2 自定义构建环境
为不同项目创建专用环境变量:
- 在项目设置 → CI/CD → Variables中添加
- 通过
$VARIABLE_NAME在.gitlab-ci.yml中引用
安全建议:
- 敏感变量(如密码、密钥)标记为"Protected"和"Masked"
- 不同环境使用不同变量组
4.3 分布式Runner架构
当单个Runner性能不足时,可以部署多个Runner并设置标签:
# 注册专用构建Runner sudo gitlab-runner register -n \ --url https://gitlab.example.com \ --registration-token glrt-xxxxxx \ --executor shell \ --description "build-runner" \ --tag-list build \ --run-untagged=false然后在.gitlab-ci.yml中定向使用:
build_android: stage: build script: - ./gradlew assembleRelease tags: - build4.4 监控与日志管理
GitLab提供内置的流水线监控界面,同时可以通过以下命令查看Runner日志:
# 查看实时日志 journalctl -u gitlab-runner -f # 查看历史错误 sudo grep -i error /var/log/gitlab-runner/runner.log对于长期运行的Runner,建议配置日志轮转:
# /etc/logrotate.d/gitlab-runner /var/log/gitlab-runner/*.log { weekly missingok rotate 12 compress delaycompress notifempty copytruncate }5. 典型问题排查指南
即使配置正确,实践中仍可能遇到各种问题。以下是常见问题的解决方法:
问题1:Runner显示活跃但无法接收任务
- 检查Runner的systemd状态:
sudo systemctl status gitlab-runner - 验证网络连接:
curl -v <GitLab实例URL> - 确认Runner没有被标记为"stuck"(在Admin区域重置)
问题2:Shell命令找不到
- 检查$PATH环境变量:
echo $PATH - 使用绝对路径执行命令
- 或者在.gitlab-ci.yml中预先设置PATH:
variables: PATH: "/usr/local/bin:$PATH"问题3:权限不足
- 避免在脚本中直接使用sudo,改为:
- 将Runner用户加入sudoers(有安全风险)
- 或预先配置必要的权限
问题4:缓存不生效
- 检查cache key配置是否唯一
- 手动清除缓存:在CI/CD设置中点击"Clear runner caches"
- 验证缓存路径是否正确
可以通过在脚本中添加调试命令来定位问题:
debug_info: script: - echo "当前用户: $(whoami)" - echo "工作目录: $(pwd)" - echo "环境变量:" - printenv