1. 流水线基础回顾:CI/CD 核心概念、Jenkins/GitLab CI 基础架构、Pipeline as Code 理念
说实话,很多团队把 CI/CD 流水线当成「一键部署」的工具。但在我眼里,流水线其实是整个研发团队的数字化高速公路。路修得好,代码从提交到上线就像跑高速一样顺畅;路修得烂,天天堵车、翻车,运维同学就得半夜爬起来救火。
这一章,咱们先把地基打牢。我会带着你回顾 CI/CD 的核心概念,聊聊 Jenkins 和 GitLab CI 的架构差异,再深入讲讲 Pipeline as Code 这个理念——嗯,这也是我这些年踩坑最多的地方。
1.1 CI/CD 核心概念:别把概念搞混了
先问一个问题:CI 和 CD 到底有什么区别?
我面试过不少候选人,能把这两个概念说清楚的不超过三成。很多人觉得「CI/CD 就是自动部署」,其实差远了。
| 概念 | 全称 | 核心目标 | 典型产出 |
|---|---|---|---|
| CI | Continuous Integration | 频繁合并代码,自动构建+测试 | 编译产物、测试报告 |
| CD | Continuous Delivery | 随时可部署到生产环境 | 可发布的制品、部署审批 |
| CD | Continuous Deployment | 每次通过测试自动部署到生产 | 自动上线、回滚机制 |
你看,同样是 CD,Continuous Delivery 和 Continuous Deployment 就差了一个字母,但含义完全不同。Delivery 是「准备好部署,但需要按个按钮」,Deployment 是「直接推上线」。我个人习惯在团队初期先用 Delivery,等测试覆盖率上来了再切到 Deployment——步子迈太大容易扯着蛋。
核心公式:
CI + CD + 自动化测试 + 基础设施即代码 = 可靠的交付流水线
少了任何一环,流水线都会变成「流水线事故线」。
1.2 Jenkins 基础架构:老牌劲旅的底牌
Jenkins 是我最早接触的 CI 工具,那时候还是 Hudson 时代。说实话,Jenkins 的架构设计在当年是非常超前的——Master/Agent 架构,说白了就是「一个大脑管一群手脚」。
它的核心组件其实就这几个:
- Jenkins Master:调度中心,负责任务分发、UI 展示、配置存储
- Jenkins Agent:执行节点,跑具体的构建、测试、部署任务
- 共享文件系统 / 制品仓库:Master 和 Agent 之间的数据交换通道
我在项目中遇到过一个问题:Master 挂了,整个流水线就瘫痪了。为什么?因为 Jenkins 的 Master 是单点,所有 Agent 都依赖 Master 来分配任务。后来我们做了 Master 的高可用,但说实话,配置起来挺折腾的。
避坑指南:
我曾经把 Jenkins Master 和 Agent 部署在同一台机器上,结果构建任务一多,Master 的 UI 直接卡死。记住:Master 只做调度,别让它干活。Agent 资源要独立规划,尤其是磁盘和内存。
1.3 GitLab CI 基础架构:原生集成的优雅
GitLab CI 和 Jenkins 最大的区别是什么?原生集成。你想想看,代码仓库、CI/CD、制品管理、容器镜像仓库,全在一个平台里。不用像 Jenkins 那样装一堆插件来对接 GitLab。
GitLab CI 的架构更轻量:
- GitLab Server:提供代码仓库和 CI/CD 配置解析
- GitLab Runner:执行 CI 任务的代理,支持 Docker、Kubernetes、Shell 等多种执行器
- .gitlab-ci.yml:流水线定义文件,放在项目根目录
我个人特别喜欢 GitLab CI 的一点是它的 Pipeline 可视化。每个 Stage、每个 Job 的依赖关系一目了然。不像 Jenkins 的 Pipeline 视图,有时候得靠脑补。
小技巧:
GitLab Runner 建议用 Docker 执行器,配合 services 关键字可以轻松拉起数据库、缓存等依赖服务。我曾经用这个特性在一条流水线里同时跑了 MySQL、Redis 和 RabbitMQ 的集成测试,爽得很。
1.4 Pipeline as Code 理念:把流水线当代码管
Pipeline as Code,说白了就是用代码定义你的流水线。不是点鼠标配界面,而是写 Jenkinsfile 或 .gitlab-ci.yml。
为什么这件事这么重要?我给你讲个真实经历。
有一次,我们团队的生产环境出了个 Bug,需要紧急修复。但负责 Jenkins 配置的同事请假了,其他人都不敢动那个「点出来的流水线」——因为没人知道哪个按钮对应哪个步骤。最后等了三个小时才修复上线。
从那以后,我强制团队所有流水线都必须用代码定义。好处很明显:
- 版本控制:流水线变更和代码变更一起走 PR 评审
- 可复现:任何环境都能重建一模一样的流水线
- 可审计:谁改了流水线、改了啥,Git 历史一清二楚
下面是一个简单的 Jenkins Declarative Pipeline 示例:
pipeline {
agent any
stages {
stage('Checkout') {
steps {
checkout scm
}
}
stage('Build') {
steps {
sh 'mvn clean package'
}
}
stage('Test') {
steps {
sh 'mvn test'
}
}
stage('Deploy') {
steps {
sh 'scp target/*.jar user@server:/app/'
}
}
}
}
再看 GitLab CI 的等价写法:
stages:
- build
- test
- deploy
build-job:
stage: build
script:
- mvn clean package
test-job:
stage: test
script:
- mvn test
deploy-job:
stage: deploy
script:
- scp target/*.jar user@server:/app/
你看,两种工具的表达方式不同,但核心理念是一样的:流水线是代码,代码就要被管理。
1.5 本章知识体系总览
为了让你更直观地理解本章的知识结构,我画了一张图。它把 CI/CD 核心概念、Jenkins 和 GitLab CI 的架构、以及 Pipeline as Code 的关系串在了一起。
这张图把本章的核心脉络都串起来了。你可以看到,CI/CD 是理念,Jenkins 和 GitLab CI 是工具,Pipeline as Code 是实践方法。三者缺一不可。
一句话总结:
CI/CD 是「做什么」,Pipeline as Code 是「怎么做」,Jenkins/GitLab CI 是「用什么做」。搞清楚这三层关系,后面的迁移和部署实战才能游刃有余。