17、GitLab与CI/CD:GitLab介绍、GitLab CI配置、Runner配置、自动化测试与部署
聊到Git,就不能不提GitLab。很多团队用GitHub做开源,但企业内部开发,GitLab才是真正的利器。为什么?因为它把代码托管、代码审查、CI/CD全打包在一起了。说白了,你不需要东拼西凑各种工具,一个GitLab就能搞定从提交到上线的整条链路。
我个人习惯把GitLab比作「开发者的瑞士军刀」。它不只是一个Git仓库,更是一个完整的DevOps平台。今天我们就来拆解它的核心能力——CI/CD。
GitLab CI/CD 是什么?
先别急着敲命令。我们得先搞清楚,CI/CD到底在解决什么问题。
你想想看,以前开发流程是什么样的?开发写完代码,手动打包,丢给测试,测试测完,再手动部署上线。中间任何一个环节出错,都得从头再来。我见过一个团队,上线一次要折腾大半天,光等编译就半小时。
CI/CD就是把这些重复劳动自动化。CI(持续集成)让你每次提交代码都自动跑测试、自动构建。CD(持续部署)让通过测试的代码自动部署到服务器。嗯,这里要注意:CD也可以是持续交付(手动触发部署),看团队策略。
核心价值:把「人肉操作」变成「机器自动执行」,减少人为失误,加快交付速度。
GitLab CI 的核心概念
要配置GitLab CI,你得先理解三个东西:Pipeline、Job、Stage。
- Pipeline(流水线):一次CI/CD的完整执行过程。比如你push代码,触发一次Pipeline。
- Job(任务):Pipeline里的最小执行单元。比如「运行测试」是一个Job,「构建镜像」是另一个Job。
- Stage(阶段):一组Job的集合。比如「测试阶段」包含多个测试Job,「部署阶段」包含部署Job。
我曾经犯过一个错误:把所有Job都放在同一个Stage里。结果一个Job失败,整个Pipeline都停了。后来才明白,合理的Stage划分能让问题定位更清晰。
下面这张图展示了典型的Pipeline结构:
配置 .gitlab-ci.yml
GitLab CI的配置文件叫 .gitlab-ci.yml,放在项目根目录。GitLab检测到这个文件后,就会自动触发CI/CD流程。
来看一个最基础的配置:
# .gitlab-ci.yml
stages:
- build
- test
- deploy
build-job:
stage: build
script:
- echo "正在编译项目..."
- mkdir -p build
- cp -r src/* build/
test-job:
stage: test
script:
- echo "运行单元测试..."
- npm test
deploy-job:
stage: deploy
script:
- echo "部署到生产环境..."
- scp -r build/ user@server:/var/www/
only:
- main
这个配置干了三件事:先构建,再测试,最后部署。注意 only: - main,意思是只有main分支的提交才会触发部署。我建议你养成这个习惯——部署操作一定要加分支限制,不然随便一个分支push都可能触发上线,那可就乱套了。
小技巧:可以用 rules 替代 only/except,更灵活。比如根据提交信息决定是否执行某个Job。
Runner 配置
配置文件写好了,谁来执行?答案是Runner。Runner是真正跑Job的「工人」。GitLab官方提供共享Runner,但很多时候你需要自己搭。
为什么?我遇到过这种情况:共享Runner排队太久,一个Job等半小时。而且共享Runner的环境不一定满足你的需求,比如需要特定版本的Node.js或Docker。
安装Runner很简单:
# 在服务器上安装GitLab Runner
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 register
注册时需要输入GitLab实例地址和注册令牌。这些信息在项目的 Settings → CI/CD → Runners 页面可以找到。
Runner有三种类型:
| 类型 | 说明 | 适用场景 |
|---|---|---|
| Shared Runner | 所有项目共享 | 小团队、测试环境 |
| Group Runner | 组内项目共享 | 部门级项目 |
| Specific Runner | 指定项目专用 | 生产环境、特殊需求 |
我个人习惯给生产环境部署用Specific Runner,确保资源不被其他项目抢占。测试环境用Shared Runner就够了。
自动化测试
CI/CD的核心价值之一就是自动化测试。没有测试的流水线,说白了就是「自动部署bug」。我曾经接手过一个项目,CI流水线跑得挺欢,但里面全是 echo "test passed" 这种假测试。结果上线后问题不断。
真正的自动化测试应该包含:
- 单元测试:测试每个函数、模块的正确性
- 集成测试:测试模块之间的交互
- 代码质量检查:用ESLint、SonarQube等工具
看一个带测试的完整示例:
stages:
- lint
- test
- build
- deploy
lint-job:
stage: lint
script:
- npm install
- npm run lint
unit-test:
stage: test
script:
- npm install
- npm run test:unit
artifacts:
reports:
junit: junit.xml
integration-test:
stage: test
script:
- docker-compose up -d
- npm run test:integration
- docker-compose down
build-job:
stage: build
script:
- docker build -t myapp:$CI_COMMIT_SHORT_SHA .
- docker push myapp:$CI_COMMIT_SHORT_SHA
deploy-prod:
stage: deploy
script:
- kubectl set image deployment/myapp myapp=myapp:$CI_COMMIT_SHORT_SHA
only:
- main
when: manual
注意 when: manual,这是手动触发部署。生产环境我强烈建议用手动部署,而不是自动。自动部署到测试环境没问题,但生产环境还是让人看一眼比较放心。
避坑指南:我曾经因为测试环境数据库和生产环境不一致,导致测试全过但上线就崩。后来我强制要求测试环境镜像和生产环境保持一致。记住:环境差异是CI/CD最大的敌人。
自动化部署策略
部署不是简单的把文件丢到服务器。现代部署讲究「零停机」和「快速回滚」。常用的策略有:
- 蓝绿部署:维护两套环境,切换流量
- 滚动更新:逐步替换旧实例
- 金丝雀发布:先让少量用户用新版本
在GitLab CI中,你可以通过不同的Job来实现这些策略。比如:
deploy-canary:
stage: deploy
script:
- kubectl set image deployment/myapp-canary myapp=myapp:$CI_COMMIT_SHORT_SHA
only:
- main
environment:
name: production/canary
deploy-production:
stage: deploy
script:
- kubectl set image deployment/myapp myapp=myapp:$CI_COMMIT_SHORT_SHA
only:
- main
when: manual
environment:
name: production
先部署金丝雀版本,观察一段时间没问题,再手动部署全量版本。这个流程我用了很久,效果很好。
环境变量与缓存
CI/CD中两个容易被忽略的点:环境变量和缓存。
环境变量用来存储敏感信息,比如数据库密码、API密钥。千万别写在代码里!在GitLab的 Settings → CI/CD → Variables 里配置,然后在yml中引用:
deploy-job:
script:
- echo "数据库密码是 $DB_PASSWORD"
variables:
DB_PASSWORD: $DB_PASSWORD
缓存用来加速构建。比如Node.js的 node_modules,每次重新安装太慢了:
cache:
key: ${CI_COMMIT_REF_SLUG}
paths:
- node_modules/
install-deps:
script:
- npm install
这样只有分支切换或 package.json 变化时才会重新安装依赖。我算过,加了缓存后Pipeline时间缩短了60%。
总结
GitLab CI/CD其实不复杂。核心就三件事:写对 .gitlab-ci.yml、配好Runner、加好测试。但细节决定成败——环境一致性、分支策略、缓存配置,这些才是真正影响体验的地方。
如果你刚开始接触,建议从最简单的流水线开始,逐步加测试、加部署策略。别想着一步到位,CI/CD是持续改进的过程。
一句话记住:GitLab CI/CD不是银弹,但它能把重复劳动变成自动化流程,让你专注于真正有价值的事情——写代码。