CI/CD 基础概念与常见失败概述
说实话,我做了快十年的 DevOps,接触过上百个 CI/CD 流水线。每次跟新人聊,他们最容易犯的错就是——把 CI/CD 当成“一键部署神器”。可实际上,流水线跑不跑得通,往往取决于你最不在意的那行配置。
这一章我们先打好地基。搞清楚 CI/CD 到底是什么,流水线里藏着哪些坑,以及为什么失败是常态、不是意外。
CI/CD 到底是什么?
CI(持续集成)和 CD(持续交付/持续部署)是两回事,但经常被混着说。我个人习惯这样理解:
- 持续集成(CI):每次代码合并到主干,自动触发构建和测试。目标是尽早发现问题。说白了,就是不让“我本地能跑”的借口拖到上线后才暴露。
- 持续交付(CD):CI 通过后,自动把产物部署到类生产环境(比如预发布),再由人工决定是否上线。加了一层安全阀。
- 持续部署(CD):CI 通过后,直接自动部署到生产环境。这个“胆量”不是每个团队都有的。
我记得有一年帮一家电商公司搭流水线,他们原来的流程是:开发写完代码,手动打包,运维手工部署。每次上线都是凌晨三点,还经常回滚。后来拆成 CI + 持续交付,光是测试时间就缩短了 70%。
一句话总结:CI 是“代码合并后自动检查和打包”,CD 是“把打包好的东西自动送到它该去的地方”。
核心流水线长什么样?
不管工具是 Jenkins、GitLab CI、GitHub Actions 还是 CircleCI,流水线的骨架都差不多。你想想看,它分这么几个阶段:
- 代码拉取与静态检查 – 拉分支、跑 Linter、代码规范扫描。
- 构建 – 编译、打包(比如 Maven、npm build)。
- 单元测试 & 集成测试 – 跑用例、生成覆盖率报告。
- 安全扫描 & 镜像构建 –(可选)扫描依赖漏洞,打容器镜像。
- 部署到测试/预发布环境 – 自动 push 到对应环境。
- 验收测试 & 人工审批 –(可选)冒烟测试,等负责人点确认。
- 生产部署 – 灰度、蓝绿、或直接全量。
下面是这一章的知识体系图,我把它画成了一张流程 + 失败点对应图。
最常见的 CI 失败类型
根据我在团队里看到的统计(以及踩过的坑),失败可以归成下面几类。我自己整理了一个对照表:
| 失败类别 | 典型表现 | 高频原因 | 影响等级 |
|---|---|---|---|
| 构建失败 | 编译报错、找不到依赖、版本冲突 | 代码合并冲突,依赖锁文件未更新,环境差异 | 🔴 高(阻塞合并) |
| 测试失败 | 单元测试断言失败,集成测试超时 | 测试数据污染,Mock 不匹配,时间敏感 | 🟡 中(需要人工确认) |
| 基础设施问题 | Runner 离线、磁盘满、网络超时 | 资源不够用,证书过期,DNS 解析 | 🔴 高(全阻塞) |
| 部署失败 | 部署脚本报错、k8s apply 失败、健康检查不通过 | 配置错误、权限不足、镜像 tag 不存在 | 🔴 高(影响上线) |
| 人因 / 流程问题 | 漏提代码、忘记更新版本号、审批流程卡住 | 沟通不足、CI 配置过于复杂 | 🟡 中(可快速修复) |
我的经验:很多团队把 80% 的精力花在写测试上,却忽略了构建环境的稳定性。我曾遇到一个项目,每周构建失败超过 30 次,结果八成是因为 Runner 节点内存不足。后来加了资源监控,失败率直接降到 5% 以下。
避坑指南:别让流水线变成“烂尾楼”
当我刚开始做 CI/CD 时,最常犯的一个错就是:一次性设计一个特别“完美”的流水线,恨不得把所有的扫描、测试、部署步骤都揉进去。结果呢?
- 一个构建动不动跑 40 分钟。
- 失败点太多,开发看到红色就麻木了。
- 没人愿意修流水线,因为太复杂。
我建议:先让它能跑通最简单的路径,再逐步加料。比如你可以先从下面这个最小化配置开始:
# 一个极简的 GitLab CI 配置
stages:
- build
- test
build_job:
stage: build
script:
- echo "Building..."
- npm install
- npm run build
test_job:
stage: test
script:
- echo "Running tests..."
- npm test
注意:别把 npm install 和 npm test 写在同一个 job 里。一旦 test 失败,你完全不知道是 install 阶段出了问题还是 test 本身挂了 —— 这是我在生产线上亲眼见过的“黑盒失败”。
失败是信号,不是噪音
其实,CI 失败本身不是坏事。它就像一个警报器,告诉你哪个环节有风险。我见过最健康的团队,他们的流水线失败率在 15%~25% 之间。为什么?因为他们设置了足够多的检查点,胆敢让流水线暴露问题。
相反,如果一个团队的 CI 从来没有红过,那才要担心——可能是测试覆盖率只有 5%,也可能是构建永远只在本地跑。