CI/CD:提交即构建,构建即测试,测试过即上线¶
1. 这一章讲什么¶
前面各章把零件备齐:代码在 Git 里、应用在容器里、集群是 Kubernetes。这一章把它们串成一条自动流水线——CI(持续集成)、CD(持续交付)、CD(持续部署),三个词只差一两个字母,差别全在「自动化走到哪一步、上线前还留不留一道人工批准」。本章后半段用 GitLab CI 做了一次完整的落地演示:配置文件、runner、镜像仓库、一条真实的天气应用流水线。
2. 顶层全景¶
主线例子(本章落地演示):一个 Flask 天气应用,配一条「build 镜像 → push 到 registry → deploy 容器」的两阶段流水线。
3. 核心原理¶
3.1 三个词拆开:integration / delivery / deployment¶
书里先用一个电商应用拆词1:
- 集成(integration):多个小组各写各的组件(前端、支付网关、库存、推荐……),拼到一起验证能协同工作;
- 交付(delivery):软件打包完毕、测试通过、随时能交给客户——像礼物已包装好,但还没递出去;
- 部署(deployment):真正放进生产环境、用户能用到。
「持续」从哪来?答案朴素:提交够勤、每步都自动化,过程就连续了。开发者一天多次提交到共享仓库,每次提交自动触发测试,反馈立刻回来2。书里特意声明:下文 CI/CD/CD 一律简写 CI/CD。
3.2 演化链:CI 治集成难,CD 补发布缝,DevOps 拆掉整面墙¶
历史是治病的链条3:
- CI 的出现治「集成地狱」:大型项目里大家各写各的,合并时爆炸。药方:一天集成多次,每次集成都自动构建+测试,错误刚冒头就反馈给作者,不让错误堆积3。
- CD 补 CI 留下的缝:CI 验证完的代码离「能发布」还差打包、配置、更多测试(集成/性能/验收)。CD 让软件永远处于可部署状态,随时按需发布3。
- DevOps 再补一刀:CI/CD 只管到「交付到生产」,生产环境的监控没人管;而且运维仍是另一拨人,「把代码扔过墙」。DevOps 把监控和反馈环也纳入,并拆掉开发与运维的墙3。
3.3 CI 的工作流与度量¶
CI 标准四步4:本地写代码 → 本地先跑单元测试(别等提交才测)→ commit 到共享仓库 → CI 系统自动构建+全量测试,挂了立刻通知。
怎么知道 CI 做得好不好?书里给了一张 10 项 KPI 表5,四个最常用:
| KPI | 量什么 |
|---|---|
| 集成频率 | 每天/每周合进主分支多少次 |
| 构建成功率 | 成功构建占比 |
| 代码覆盖率 | 自动化测试盖住的代码百分比 |
| 错误检测修复时间 | 构建失败后多久修好 |
3.4 delivery vs deployment:就差一道人工批准¶
这是最常被混的一对。书里的礼物类比:delivery 是把礼物包好,deployment 是把礼物递到对方手里6。持续交付(continuous delivery):流水线走到「随时可发布」,上线由人(或业务排期)手动触发——例:安全功能好了,市场部定发布日,那天手动触发上线。持续部署(continuous deployment):测试一过自动上生产,用户立刻见到,没有任何人工批准环节7。判断你处在哪一档,就看一个问题:测试全绿之后,还需不需要人来触发上线?
CD 侧的 KPI 表里 17 项8,记住四个:部署频率、变更前置时间(lead time)、变更失败率、平均恢复时间(MTTR)——这四个正是 DORA 四大关键指标(书里没点名对应关系,这是业界通行框架;补充,不在书里)。
3.5 CI/CD 流水线:四个阶段、各归谁管¶
流水线 = 代码管理 → 构建 → 测试 → 部署9:
| 阶段 | 干什么 | 主要负责人 |
|---|---|---|
| Code | 写代码、commit、分支策略(GitFlow/feature branch) | 开发者 |
| Build | 编译、查语法、出构件 | DevOps 工程师配管道,开发者保代码能编过 |
| Test | 单测/集成/功能测试自动跑 | QA 设计,开发者写单测,CI 工具执行 |
| Deploy | 发布到生产/预发 | 运维,用 Ansible/Docker/Kubernetes |
实施挑战书里列了七条,最痛的三条:工具太多选错集成不畅;管道复杂难维护;文化阻力(有人爱 Jenkins 有人爱 GitLab,有人怕自动化抢饭碗)10。另有一条值得抄下来:过度自动化——管道复杂到没人能排错,反而成了负担10。
3.6 工具四选一(书里给了等价配置)¶
同一条「装依赖 + 跑 pytest」的流水线,四个工具各一段配置,风格立判11:
- Jenkins:老牌开源、插件生态最大、可自托管;但界面旧、插件维护累。声明式流水线用 Groovy 语法(
pipeline { agent { docker { image 'python:3.11' } } … })。 - Travis CI:云托管、对开源项目免费、配置极简(
.travis.yml五行)。 - CircleCI:速度快、缓存和并行强;大团队价格贵。
- GitLab CI:与 GitLab 仓库一体化、
.gitlab-ci.yml就是仓库里的一个文件、可自托管。本章的主角。
3.7 GitLab CI 落地(主线例子走全程)¶
三个角色12:① .gitlab-ci.yml(仓库里的流水线定义);② Runner(轻量代理,装在随便哪台机器上,轮询 GitLab 抢活干——不是 GitLab 派活,是 runner 自己要活);③ Container Registry(GitLab 内置镜像仓库,免费私有——与 Docker Hub 相反,Docker Hub 公共免费、私有收费)。
runner 两种:共享 runner(GitLab 提供,排队可能慢)vs 私有 runner(自建,专属、可定制,自己掏机器和维护)。执行环境(executor)多种:shell(直接在宿主机跑)、docker(容器里跑,最常用)、kubernetes(pod 里跑)等13。
一条真实流水线(天气 Flask 应用,照抄原书骨架14):
variables:
IMAGE_NAME: registry.gitlab.com/devops-textbook/devops-ch8-cicd/weather-flask/webWeather:latest
stages:
- build
- deploy
build_image:
stage: build
tags: [build]
script:
- docker login -u "$CI_REGISTRY_USER" -p $gitlabpassword $CI_REGISTRY
- docker build -t $IMAGE_NAME .
- docker push $IMAGE_NAME
deploy_image:
stage: deploy
tags: [deploy]
script:
- docker run -d --name weather-flask -p 5000:5000 $IMAGE_NAME
三段结构:variables(定义变量,镜像名全局一致)→ stages(阶段列表,按顺序执行,同阶段并行)→ jobs(每个 job:属于哪个 stage、在哪个 runner 上跑(tags 匹配)、跑什么命令(script))14。
常用关键字一张表15:default(全局默认,job 可覆盖)、include(从外部文件导入配置)、script(每个 job 必填)、before_script/after_script(前后置)、tags(选 runner)、only/except(条件触发,如只在 main 分支部署)、artifacts(产物传给下游 job)、allow_failure(失败不阻塞管道)、cache(跨次运行缓存依赖,如 node_modules/)。
runner 的通信协议(书里给了时序图16):注册时 POST /api/v4/runners 拿 runner_token;之后进入拉活循环——不停 POST /api/v4/jobs/request,有活就领 job_token、clone 代码、让 executor 跑、把结果报回去。注册信息存在 runner 所在机器的 config.toml(concurrent = 1 表示同时只跑一个 job)。
3.8 CI/CD 与 DevOps 的关系,和新三样¶
书里用三个自问自答厘清关系17:
- DevOps 没有 CI/CD 能活吗? 能,但严重受限。文化与协作可以先行;大规模下 CI/CD 几乎不可缺。
- CI/CD 怎么支撑 DevOps 文化? 自动化消灭重复劳动(减少 toil);管道的设计维护强迫开发/运维/QA 协作;小而频繁的提交契合持续改进。
- DevOps 就等于 CI/CD 吗? 不。CI/CD 只管集成/交付/部署;DevOps 覆盖全生命周期(计划→反馈),自动化还延伸到 IaC、监控、日志。
新三样(各一小节)18:
- AI in CI/CD:Copilot 级代码建议、AI 代码评审(Codacy、CodeRabbit)、AI 生成测试(Snyk DeepCode、Testim)、AI 运维异常检测(Dynatrace、New Relic)。
- GitOps:基础设施和部署配置全部存 Git,集群里的 operator(ArgoCD、Flux)盯着仓库,发现声明变了就把线上调成和 Git 一致——和 Kubernetes 的控制循环同款思路, pull 式部署。
- Serverless / cloud-native CI/CD:构建机不再 24/7 空转,按需起环境(AWS CodeBuild、GitHub Actions、Cloud Build);cloud-native 流水线(Tekton、Jenkins X)全程容器化,配合 GitOps 做部署。
4. 作者的判断与证据¶
有出处的:CI/CD 演化叙事基于《The DevOps Handbook》与《Continuous Delivery》19;GitLab 部分的命令和时序图与 GitLab 官方文档一致(书中引官方文档)。
作者的判断:「工具无绝对优劣,看团队规模和生态」(Jenkins 灵活但重、Travis 简单但弱)是经验之谈,无实证比较;AI 小节是方向性展望,所举产品为 2024 年快照。
我们的补充:四大 DORA 指标(deployment frequency、lead time、change failure rate、MTTR)与书中 CD KPI 表高度重合但书中未点名;GitOps 与 Kubernetes 声明式模型的同构关系书中暗示未点破(补充,不在书里)。
5. 边界与局限¶
- 部署策略(蓝绿/金丝雀)在复习题里问,正文只给了名字——详解在第 12 章。
- Jenkins 只展示了声明式管道一例,插件管理、agent 拓扑没展开。
- 安全(凭证管理、管道注入攻击)只在注册 token 处一句带过。
- AI 小节是产品列表式概览,无方法论。
6. 可带走的¶
- 三个词:集成=拼起来验证;交付=包好待发;部署=递到用户手里。「持续」= 频繁提交 + 全程自动化12。
- delivery 与 deployment 的分界:测试全绿之后,还需不需要人工触发7。
- CI 四步:本地写码 → 本地单测 → commit → 自动构建测试4。
- 度量 CI 看集成频率/构建成功率/覆盖率/修复时间;度量 CD 看部署频率/前置时间/变更失败率/MTTR58。
- 流水线四阶段 code → build → test → deploy,每阶段有明确负责人9。
- 实施七大坑:选错工具、管道过复杂、基建不伸缩、文化阻力、依赖管理、预算、过度自动化10。
- GitLab CI 三件套:yml 定义、runner 轮询抢活、registry 存镜像;
tags决定 job 在哪台 runner 跑1216。 - 关键字的用法:
only: [main]只在主分支部署;artifacts传产物;cache缓存依赖;allow_failure不阻塞15。 - GitOps = 用 Git 当唯一事实源,集群里的 operator 把线上调得和仓库一致18。
- CI/CD 是 DevOps 的使能器,不是 DevOps 本身17。
7. 原文地图¶
| 主题 | 原书章 | 原文位置 |
|---|---|---|
| 三个术语拆解(电商例) | 8 - Continuous integration, delivery, and deployment | text/13-ch08-8-continuous-integration-delivery-and-deployment.txt:19(搜「Integration is the process of combining」) |
| CI 到 DevOps 的演化 | 8 - Continuous integration, delivery, and deployment | text/13-ch08-8-continuous-integration-delivery-and-deployment.txt:54(搜「Evolution of CI/CD to DevOps」) |
| CI 四步工作流 | 8 - Continuous integration, delivery, and deployment | text/13-ch08-8-continuous-integration-delivery-and-deployment.txt:91(搜「Write code on local machine」) |
| CI 的 10 项 KPI | 8 - Continuous integration, delivery, and deployment | text/13-ch08-8-continuous-integration-delivery-and-deployment.txt:166(搜「Integration Frequency」) |
| 礼物类比:delivery vs deployment | 8 - Continuous integration, delivery, and deployment | text/13-ch08-8-continuous-integration-delivery-and-deployment.txt:142(搜「wrapping a gift」) |
| 安全功能例:手动 vs 自动发布 | 8 - Continuous integration, delivery, and deployment | text/13-ch08-8-continuous-integration-delivery-and-deployment.txt:160(搜「marketing team must schedule」) |
| CD 的 17 项 KPI | 8 - Continuous integration, delivery, and deployment | text/13-ch08-8-continuous-integration-delivery-and-deployment.txt:199(搜「Deployment Frequency」) |
| 流水线四阶段 | 8 - Continuous integration, delivery, and deployment | text/13-ch08-8-continuous-integration-delivery-and-deployment.txt:230(搜「structured workflow」) |
| 实施挑战七条 | 8 - Continuous integration, delivery, and deployment | text/13-ch08-8-continuous-integration-delivery-and-deployment.txt:274(搜「Implementation challenges」) |
| 四工具等价配置 | 8 - Continuous integration, delivery, and deployment | text/13-ch08-8-continuous-integration-delivery-and-deployment.txt:321(搜「Declarative Pipeline」) · text/13-ch08-8-continuous-integration-delivery-and-deployment.txt:358(搜「language: python」) |
| GitLab 三组件与 runner 类型 | 8 - Continuous integration, delivery, and deployment | text/13-ch08-8-continuous-integration-delivery-and-deployment.txt:434(搜「GitLab CI/CD Pipeline」) |
| 天气应用流水线 | 8 - Continuous integration, delivery, and deployment | text/13-ch08-8-continuous-integration-delivery-and-deployment.txt:522(搜「IMAGE_NAME」) |
| 关键字三组 | 8 - Continuous integration, delivery, and deployment | text/13-ch08-8-continuous-integration-delivery-and-deployment.txt:588(搜「three main types」) |
| runner 时序(拉活循环) | 8 - Continuous integration, delivery, and deployment | text/13-ch08-8-continuous-integration-delivery-and-deployment.txt:828(搜「jobs/request」) |
| 三问三答(CI/CD 与 DevOps) | 8 - Continuous integration, delivery, and deployment | text/13-ch08-8-continuous-integration-delivery-and-deployment.txt:931(搜「Can DevOps exist without CI/CD」) |
| AI / GitOps / serverless CI | 8 - Continuous integration, delivery, and deployment | text/13-ch08-8-continuous-integration-delivery-and-deployment.txt:979(搜「AI in CI/CD automation」) · text/13-ch08-8-continuous-integration-delivery-and-deployment.txt:1008(搜「Git and Operations」) · text/13-ch08-8-continuous-integration-delivery-and-deployment.txt:1022(搜「cloud-native CI/CD」) |
-
出处:「8 - Continuous integration, delivery, and deployment」第 19–32 段(
text/13-ch08-8-continuous-integration-delivery-and-deployment.txt:19,搜「Integration is the process of combining」)。 ↩↩ -
出处:「8 - Continuous integration, delivery, and deployment」第 36–49 段(
text/13-ch08-8-continuous-integration-delivery-and-deployment.txt:39,搜「multiple times a day」)。 ↩↩ -
出处:「8 - Continuous integration, delivery, and deployment」第 54–76 段(
text/13-ch08-8-continuous-integration-delivery-and-deployment.txt:60,搜「integrate the code more frequently」;:71搜「throwing code over the wall」)。 ↩↩↩↩ -
出处:「8 - Continuous integration, delivery, and deployment」第 86–103 段(
text/13-ch08-8-continuous-integration-delivery-and-deployment.txt:94,搜「Run local unit test」)。 ↩↩ -
出处:「8 - Continuous integration, delivery, and deployment」表 8.1(
text/13-ch08-8-continuous-integration-delivery-and-deployment.txt:166,搜「Integration Frequency」)。 ↩↩ -
出处:「8 - Continuous integration, delivery, and deployment」第 139–151 段(
text/13-ch08-8-continuous-integration-delivery-and-deployment.txt:142,搜「wrapping a gift」)。 ↩ -
出处:「8 - Continuous integration, delivery, and deployment」第 153–188 段(
text/13-ch08-8-continuous-integration-delivery-and-deployment.txt:160,搜「manually triggered」;:182搜「without manual approval」)。 ↩↩ -
出处:「8 - Continuous integration, delivery, and deployment」表 8.2(
text/13-ch08-8-continuous-integration-delivery-and-deployment.txt:199,搜「Deployment Frequency」)。 ↩↩ -
出处:「8 - Continuous integration, delivery, and deployment」第 227–248 段(
text/13-ch08-8-continuous-integration-delivery-and-deployment.txt:230,搜「structured workflow」)。 ↩↩ -
出处:「8 - Continuous integration, delivery, and deployment」第 274–300 段(
text/13-ch08-8-continuous-integration-delivery-and-deployment.txt:291,搜「Cultural resistance」;:298搜「over-automation」)。 ↩↩↩ -
出处:「8 - Continuous integration, delivery, and deployment」第 302–402 段(Jenkins
:325搜「pipeline {」;Travis:358搜「language: python」;CircleCI:381搜「version: 2.1」)。 ↩ -
出处:「8 - Continuous integration, delivery, and deployment」第 404–500 段(
text/13-ch08-8-continuous-integration-delivery-and-deployment.txt:435,搜「orchestrates the flow of jobs」;:443搜「Shared Runners」)。 ↩↩ -
出处:「8 - Continuous integration, delivery, and deployment」第 489–501 段(
text/13-ch08-8-continuous-integration-delivery-and-deployment.txt:491,搜「Shell Executor」)。 ↩ -
出处:「8 - Continuous integration, delivery, and deployment」第 502–579 段(
text/13-ch08-8-continuous-integration-delivery-and-deployment.txt:522,搜「IMAGE_NAME」;:558搜「executed sequentially」)。 ↩↩ -
出处:「8 - Continuous integration, delivery, and deployment」第 581–739 段(global
:594搜「default」;job-specific:646搜「Job-specific keywords」)。 ↩↩ -
出处:「8 - Continuous integration, delivery, and deployment」第 813–834 段(
text/13-ch08-8-continuous-integration-delivery-and-deployment.txt:827,搜「continuously requests jobs」)。 ↩↩ -
出处:「8 - Continuous integration, delivery, and deployment」第 925–978 段(
text/13-ch08-8-continuous-integration-delivery-and-deployment.txt:931,搜「Can DevOps exist without CI/CD」;:966搜「not all about CI/CD」)。 ↩↩ -
出处:「8 - Continuous integration, delivery, and deployment」第 979–1038 段(GitOps
:1017搜「declarative code」;serverless:1026搜「auto-scale」)。 ↩↩ -
出处:「8 - Continuous integration, delivery, and deployment」参考文献(
text/13-ch08-8-continuous-integration-delivery-and-deployment.txt:1092,搜「The DevOps Handbook」;:1094搜「Continuous Delivery」)。 ↩