CI/CD 基础回顾:持续集成与持续部署

做灰度回滚,说白了就是跟 CI/CD 打交道。如果你连持续集成和持续部署的底子都没打牢,后面谈分层支持那就是空中楼阁。我带团队这么多年,见过太多人把 CI 和 CD 混为一谈,结果回滚的时候手忙脚乱。

持续集成 (CI) 到底在干什么?

持续集成,就是让代码在合并到主干之前,能自动编译、测试、打包。我习惯用一个比喻:你写文章,写完一段就让别人帮你读一遍,发现问题马上改。而不是写了十页再通读,那样改起来成本太高。

CI 的核心价值就两点:

  • 尽早发现问题 — 代码一提交就触发构建和测试,bug 半小时内就能暴露。
  • 保证主干稳定 — 通过门禁机制,不合格的代码压根进不了主干。
关键指标:CI 的成熟度常用“提交到反馈时长”来衡量。我个人追求的是 < 5 分钟。如果你的团队还在等半小时,那就是该优化的时候了。

持续部署 (CD) 不只是“自动发布”

持续部署分两种:Continuous Delivery 和 Continuous Deployment。前者是“随时可以发布到生产”,需要人工按个按钮;后者是“自动发布到生产”,代码一过门禁,直接上线。

说实话,我在金融项目里很少用全自动 CD,风险太高。但我们做灰度发布时,CI 层面先做分层,CD 层面再做分批推送——这套组合拳非常有效。

# 一个简化的 CD Pipeline 配置示例(Jenkinsfile)
pipeline {
    agent any
    stages {
        stage('Build & Unit Test') {
            steps {
                sh 'make build'
                sh 'make test'
            }
        }
        stage('Containerize') {
            steps {
                sh 'docker build -t myapp:${BUILD_TAG} .'
            }
        }
        stage('Deploy to Staging') {
            steps {
                sh 'kubectl apply -f k8s/staging.yaml'
            }
        }
        stage('Smoke Test') {
            steps {
                sh 'curl -f http://staging.myapp.com/health'
            }
        }
        stage('Deploy to Canary') {
            when { branch 'main' }
            steps {
                // 灰度部署逻辑
                sh 'kubectl apply -f k8s/canary.yaml'
            }
        }
        stage('Deploy to Production') {
            when { branch 'main' }
            input '确认发布到生产?'
            steps {
                sh 'kubectl apply -f k8s/prod.yaml'
            }
        }
    }
}
我的习惯是:在 CD 流程里至少保留两处人工卡点——一次是灰度验证通过后,一次是生产全量发布前。宁可慢半拍,不要出大事。

Pipeline 核心要素

Pipeline 就是 CI/CD 的骨架。不管用哪个工具,核心要素都跑不出下面这五样:

要素 说明 常见坑
触发条件 Push、PR、定时、手动 忘记配置分支过滤,导致所有分支都跑全量构建
阶段 (Stage) 构建→测试→打包→部署 阶段间没有依赖关系,并行跑出冲突
步骤 (Step) 具体执行的命令或操作 步骤内写死凭证,安全隐患
制品 (Artifact) 构建产物(镜像、jar、zip) 制品管理混乱,回滚时找不到旧版本
环境 Dev→Staging→Canary→Prod 环境配置不统一,灰度验证失效

有一次我接手一个项目,Pipeline 里十几个阶段全写在一个文件里,没有分层。灰度回滚时想只回滚某个微服务,结果整个流水线都重跑了一遍,耗时两小时。后来我把它拆成了三层:基础构建层、灰度验证层、生产部署层。每个层独立触发,互不阻塞。

常用 CI 工具对比

市面上的工具多得眼花缭乱,其实挑对了能用好多年。我简单列一下用过的几个主流工具:

工具 部署方式 适合团队 灰度支持
Jenkins 自建 大型团队 / 高度定制需求 强(Pipeline as Code,灵活)
GitLab CI 云端 / 自建 中大型 / 已用 GitLab 的团队 中等(环境变量 + 手动触发)
GitHub Actions 云端 中小型 / 开源项目 中等(Matrix + 环境)
CircleCI 云端 中型 / 追求速度 一般(Orbs 扩展)
Argo Workflows Kubernetes 原生 云原生 / K8s 重度用户 强(DAG + 参数化)
我曾经犯过一个错误:在一个中小型项目里强行上了自建 Jenkins,结果维护成本比开发成本还高。后来全量迁移到 GitLab CI,一个月就稳定了。选工具一定要看团队规模,别为了技术炫酷给自己挖坑。

你想想看,灰度回滚这件事,如果没有分层清晰的 CI 支持,回滚就成了“全量回滚”或者“手动回滚”。CI 在灰度场景下的角色,就是提供可复现的构建、可追溯的制品、可控制的部署。这三样缺一不可。

CI / CD 核心知识体系 CI / CD 流水线 持续集成 (CI) 自动构建 + 单元测试 代码质量门禁 制品打包 & 存储 持续部署 (CD) 环境管理 (Dev→Staging) 灰度/金丝雀发布 生产部署 & 回滚 Pipeline 核心要素 触发条件 → 阶段 → 步骤 → 制品 → 环境 这是骨架
把这个图记在脑子里:等你后面学灰度回滚的 CI 分层支持时,就会发现其实就是把 CI 这条分支拆成了“基础层”、“灰度层”、“回滚层”,而 CD 分支则负责按层执行不同的部署策略。