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 核心概念 CI · 持续集成 CD · 持续交付/部署 Pipeline as Code Jenkins · Master/Agent GitLab CI · Runner 架构 核心原则:流水线即代码 · 版本控制 · 可复现 · 可审计 Jenkins 适合复杂定制场景 · GitLab CI 适合原生集成场景

这张图把本章的核心脉络都串起来了。你可以看到,CI/CD 是理念,Jenkins 和 GitLab CI 是工具,Pipeline as Code 是实践方法。三者缺一不可。

一句话总结:

CI/CD 是「做什么」,Pipeline as Code 是「怎么做」,Jenkins/GitLab CI 是「用什么做」。搞清楚这三层关系,后面的迁移和部署实战才能游刃有余。