3. CI/CD 基础概念:从手工到自动化的认知拐点
说实话,我第一次接触 CI/CD 时,觉得这就是个“编译打包的自动化脚本”。后来被现实狠狠教育了——没有理解这些基础概念,流水线搭得再花哨,也只是一个会报错的玩具。
咱们这门课要跟国密接口打交道,测一次签名验签可能要调七八个工具。如果不先把 CI/CD 的底子打牢,后面你连“为什么我的国密流水线跑了两小时还没完”都分析不出来。
所以这一章,我带你把四个核心概念掰开揉碎:持续集成、持续部署、流水线、制品。
3.1 持续集成:别等周五下午才合并代码
持续集成,英文叫 Continuous Integration,缩写 CI。说白了就是:你每一次提交代码,系统都自动拉下来、编译、跑单元测试、给检查结果。
我在项目中遇到过最典型的反例:团队五个人,各写各的国密接口模块,攒了两周才合并。结果一跑,A 的签名算法依赖跟 B 的消息摘要库版本冲突,修了三天。这就是典型的“集成地狱”。
持续集成的核心目标就是打破它。你想想看——每次提交都验证,冲突早发现,修复成本低到可以忽略。
CI 的核心价值
- 早发现集成问题,避免“爆炸式冲突”
- 保证代码库始终处于可发布状态
- 强制团队养成小步提交习惯
3.2 持续部署:从“我点一下”到“自动上线”
持续部署(Continuous Deployment)是 CI 的下一站。CI 帮你确保代码没问题,CD 则负责把没问题的代码 自动 送到目标环境。
很多人分不清持续交付和持续部署。我习惯这么记:
| 概念 | 含义 | 区别 |
|---|---|---|
| 持续交付 | 每次 CI 通过后,生成可部署的版本,但需要手动确认才上线 | 有人拍板 |
| 持续部署 | CI 通过后,自动推送到生产环境,无人干预 | 全自动 |
在国密接口的场景下,我更建议先用持续交付。为什么?国密算法涉及合规审核,有些环节还是得过一次人工。你可以让流水线自动打包、自动部署到测试环境,但上生产前留个“确认按钮”。
避坑提示
我曾经在一个项目里直接上了全自动持续部署。结果一次签名算法的配置项写错,部署后所有接口返回 “ILLEGAL_KEY”。虽然五分钟就回滚了,但监控告警把运维同学半夜喊起来骂了半小时。后来我学乖了——关键接口加个“手动确认”环节,不丢人。
3.3 流水线:你的自动化“传送带”
流水线(Pipeline)就是把 CI 和 CD 做成的一系列自动化步骤。你可以把它想象成一条工厂传送带:代码从一端进去,依次经过编译、测试、打包、部署,最后从另一端出来一个可运行的服务。
每条流水线由 阶段(Stage) 和 任务(Job) 组成。我给你看一个最基础的国密接口流水线结构:
流水线:国密代理签名服务
├── 阶段1:代码检查(lint、代码规范)
├── 阶段2:单元测试(跑全部单测)
├── 阶段3:国密算法验证(SM2/SM3/SM4 功能测试)
├── 阶段4:构建打包(生成 Docker 镜像)
└── 阶段5:部署测试环境(推送到测试 K8s 集群)
为什么叫“流水线”?因为它们是串行的——阶段 2 失败了,阶段 3 根本不会启动。这样你能精确定位到哪一步出了问题。
我个人的习惯
流水线别设计得太长。超过 7 个阶段的流水线,出问题时排查起来非常痛苦。我曾经接手过一个 12 阶段的流水线,每次跑完要 40 分钟,光看日志就要翻十几屏。后来我拆成两条:一条 CI 流水线(代码检查 + 单测 + 国密验证),一条 CD 流水线(镜像构建 + 部署),分开跑,清晰多了。
3.4 制品:你的“交付物”长什么样
制品(Artifact)是流水线产出的“东西”。它可以是:
- 一个编译好的
.jar包 - 一个 Docker 镜像
- 一个 npm 包
- 一份国密签名验证报告
理解制品的关键在于:它应当是不可变的、版本化的、可追溯的。你不能覆盖它,也不能修改它。你要的是“某年某月某日,从某次提交构建出的某版本制品”。
我在做国密接口 CI/CD 集成时,制品库用的最多的就是 Nexus 和 Harbor。Nexus 管 jar 包,Harbor 管镜像。国密算法模块编译出来的东西,我都会打上 sm2-v1.2.3 这种清晰标签。
制品管理的三个原则
- 不可变:制品发布后禁止修改,只能新建版本
- 可追溯:每个制品必须关联 Git commit ID 和构建时间
- 可复现:只要保留制品和构建参数,随时能重建出相同环境
3.5 四者的关系:一张图说清楚
这些概念不是孤立的。持续集成驱动流水线,流水线产出制品,制品又被持续部署推到目标环境。我画了张图,你看看就明白了:
我画这条线的逻辑是:
- 持续集成 触发你的流水线——没有提交,流水线就不启动
- 流水线 里跑各种阶段,最后产出一个或多个 制品
- 持续部署 拿到制品,把它推到测试、预生产或生产环境
你想想看,如果 CI、流水线、制品、CD 四者脱节,你会有多痛苦?CI 跑了但没产出可部署的包,CD 部署了但没人知道用的是哪个版本的制品。嗯,这些坑我都踩过。
3.6 把这些概念串起来:一个最简单的实战场景
假设你在做一个 SM2 签名服务。你需要写一段代码,然后发布到测试环境让前端联调。在没有 CI/CD 的时候,你的步骤是:
- 本地写完代码,手动编译
- 把 jar 包 scp 到测试服务器
- ssh 上去停掉旧进程、启动新进程
- 出了问题,排查半天发现是本地编译的版本不对
有了 CI/CD,这套流程变成:
- 你提交代码到 Git 仓库
- 持续集成自动触发流水线
- 流水线跑:代码检查 → 单元测试 → SM2 功能验证 → 构建 Docker 镜像
- 流水线产出制品(Docker 镜像,Tag 是 commit SHA)
- 持续部署把镜像推送到测试环境的 K8s 集群
- 测试通过后,你点击“确认上线”,持续交付把同一份制品部署到生产
整个过程你只做了一件事:提交代码。剩下的全是自动化的。这也就是 CI/CD 最迷人的地方。
注意
国密接口对构建环境有特殊要求。比如 SM2 签名算法需要用 指定版本的 OpenSSL 或 经国家密码管理局认证的密码卡驱动。这些驱动必须提前固化在流水线的构建镜像里,否则跑出来的制品可能连签名都生成不了。一定要在流水线里显式声明这些依赖版本。
3.7 这一章你该带走什么
- 持续集成 是“频繁合并 + 自动验证”,目标是早发现问题
- 持续部署 是“自动把验证通过的代码推上线”,持续交付则在中间留个确认步骤
- 流水线 是自动化的步骤组,它是 CI/CD 的执行载体
- 制品 是流水线的产出,必须不可变、版本化、可追溯
我个人觉得,这四个概念就像开车:
- CI 是你的仪表盘——随时告诉你车况
- 流水线是你的发动机——提供动力
- 制品是你的汽油——能量载体
- CD 是你的自动驾驶——把车开到目的地
没有哪个都跑不远。但一旦把它们组合起来,你就从“手工修车工”变成了“自动化车队管理者”。下一站,我们就要上车动手了。