CI/CD 是让团队能一天发布很多次、而且安全的那套自动化。它用一条会在每次变更上构建、测试、发布的流水线,取代了手动构建和手工部署服务器这种易错的仪式。回报不只是快:更小、更频繁的发布安全,因为每次携带的改动更少、更容易回退。它与 容器(制品)和 Kubernetes(部署目标)天然搭配。

⚡ 速览要点
  • CI = 持续集成——频繁合并到主干,并在每次提交上跑自动构建 + 测试,立刻发现破坏。
  • CD = 持续交付(始终可部署、按按钮发布)或持续部署(每个通过的构建自动上线)。
  • 一次构建,推同一个制品——一个不可变镜像不变地穿过 dev → staging → prod,所以你测的就是你发的。
  • 流水线分阶段、带门禁——源码 → 构建 → 测试 → 安全扫描 → 部署,每个都是必须通过的门。
  • 部署策略限制爆炸半径——滚动、蓝绿、金丝雀,在速度/成本与安全间取舍。
  • 快速回滚是安全网——不可变制品让回滚变成切标签,而非重新构建。
tldr

持续集成在每次提交上跑自动构建和测试套件,让问题尽早暴露。持续交付让每个通过的构建都可部署;持续部署则自动上线。流水线一次构建出不可变制品,并让同一个制品在门禁后穿过各环境。用滚动/蓝绿/金丝雀策略安全发布,把回滚保持为一步快操作。更小、更频繁的发布比一次性大发布更安全。

为什么用 CI/CD

手动发布因为可预见的原因失败:分支分叉数周后集成很痛,机器之间构建不一致,半夜跑部署步骤的人会出错。把从提交到生产的路径自动化,让发布可复现、快、可逆。更深的洞见反直觉但已被充分验证:频繁地部署反而降低风险,因为每次部署只含一个小而可理解的改动,出问题易于追踪和撤销——与含成千上万改动的季度发布正相反。

持续集成

CI 是把每个人的工作频繁(理想是一天多次)集成进一条共享主干的实践,并在每次推送上跑自动构建和测试套件。要点是在引发问题的那次提交后几分钟内、趁作者记忆犹新时,就抓住集成问题和回归,而不是几周后大合并时才发现一团乱麻。CI 依赖一套扎实、快速、可靠的测试;没有它,"绿色"流水线毫无意义。

流水线各阶段

CI/CD 流水线是一串阶段,每个都是必须通过才能进入下一个的门(gate):

典型流水线
提交 ─▶ [ 源码 ] ─▶ [ 构建 ] ─▶ [ 测试 ] ─▶ [ 扫描 ] ─▶ [ 部署 ]
                      │            │           │            │
                   编译 +       单测 +      安全/        滚动 /
                   构建镜像      集成测试     lint/SAST    金丝雀
                      │            │           │            │
                      └── 任一阶段失败 → 停止、通知 ───────┘

  只构建一次 → 产出制品(如 image:sha)→ 把它往后推

GitHub Actions、GitLab CI、Jenkins、CircleCI 等工具用声明式(通常是仓库里的一个 YAML 文件)定义这些阶段。流水线在触发时自动运行——push、pull request、合并到主干,或打 tag。

持续交付 vs 持续部署

"CD" 是两个相关但不同的概念,这个区别是经典面试点:

方面持续交付(Continuous Delivery)持续部署(Continuous Deployment)
最终状态每个构建都可部署每个通过的构建已被部署
到生产人工审批(按一下按钮)全自动,无人介入
何时用你想要一个人/业务的门你完全信任你的测试

两者都需要同样有纪律的流水线;唯一区别是是否由人按下"发布"。持续部署是更进阶的终态,要求对自动化测试有非常高的信心。

一次构建,推同一个制品

一条基础原则:只构建一次制品,并让同一个制品穿过每个环境。如果你为 staging 重新构建、再为 prod 重新构建,你发布的就是从没测过的东西。用容器这很自然——流水线构建出 myapp:<git-sha>,对它跑测试,到生产的就是这同一个不可变镜像。制品带版本且不可变,这也正是回滚轻而易举的原因。

部署策略

你如何替换运行中的版本,决定了一次坏部署的爆炸半径:

滚动 vs 蓝绿 vs 金丝雀
滚动     : 一次替换几个实例   v1 v1 v1 → v2 v1 v1 → v2 v2 v2
蓝绿     : 起一整套 v2("绿"),切流量,留着 v1("蓝")以便回退
金丝雀   : 把 1% → 5% → 50% → 100% 流量导向 v2,边导边看指标
策略做法取舍
滚动逐步替换实例不需额外容量;短暂版本混跑;回滚较慢
蓝绿整套并行环境,切流量瞬时切换 & 回滚;部署期间双倍基础设施
金丝雀先放一小部分,边看边放爆炸半径最小;需要好的指标 + 自动化

金丝雀对高风险服务最安全,因为一次坏发布在自动监控抓到并停止前只命中一小撮用户——这也是它和 可观测性 紧密搭配的原因。

回滚

最重要的安全属性是能快速回到一个已知良好状态。因为制品不可变且带版本,回滚通常就是"重新部署上一个镜像标签"——几秒,而非重新构建。蓝绿让它变成切流量;金丝雀让它变成"停止放量"。推论:一个你没法快速回滚的部署,就是一个你不该做的部署。(数据库迁移是需要小心的例外——让 schema 变更向后兼容,使新旧代码能在过渡期共存;见 编码与演化。)

质量门禁与实践

常见坑

总结

CI/CD 把发布变成一条可复现、自动化、可逆的流水线:每次提交都集成并测试,一次构建出不可变制品并往后推,用一种限制爆炸半径的策略(滚动/蓝绿/金丝雀)发布——以快速回滚作为安全网。文化上的回报是:小而频繁的部署比稀有的大发布更安全。

🎯 面试速答

CI 对比 CD?CI = 每次提交自动构建+测试以尽早发现破坏;CD = 持续交付(始终可部署、人工发布)或持续部署(每个绿色构建自动上线)。
为什么只构建一次制品?把同一个不可变制品推过各环境,意味着你发的正是你测的;按环境重新构建有漂移风险。
滚动 vs 蓝绿 vs 金丝雀?滚动逐步替换(无额外容量);蓝绿在两套完整环境间切换(瞬时回滚、双倍基础设施);金丝雀先放一小部分并看指标(爆炸半径最小)。
怎么快速回滚?重新部署上一个不可变制品/标签(或切流量)。让数据库迁移向后兼容,使各版本代码能共存。
部署 vs 发布?特性开关把两者解耦——把代码暗着部署,再打开特性,无需再次部署。

← 上一篇
Docker 与容器