公司动态
【CI/CD·入门篇】CI vs CD vs Continuous Deployment:三个层次的区别与联系
前言很多人把 CI/CD 当成一个词来用但实际上它是三个递进的层次。理解这三个层次的边界决定了你团队自动化的成熟度。本篇用三个实际的流水线配置让你直观感受从 CI 到 CD 到 Continuous Deployment 的演进。一、三个层次的关系一个递进模型Level 1: Continuous Integration持续集成 代码合并 → 自动构建 → 自动测试 → 反馈结果 产出可运行的构建产物 Level 2: Continuous Delivery持续交付 CI 自动部署到类生产环境 随时可发布状态 产出随时可以点击发布的系统 Level 3: Continuous Deployment持续部署 CD 自动发布到生产环境无人工干预 产出每次通过测试的代码自动上线三者是包含关系┌─────────────────────────────────────────┐ │ Continuous Deployment │ │ ┌───────────────────────────────────┐ │ │ │ Continuous Delivery │ │ │ │ ┌─────────────────────────────┐ │ │ │ │ │ Continuous Integration │ │ │ │ │ │ 代码 → 构建 → 测试 → 反馈 │ │ │ │ │ └─────────────────────────────┘ │ │ │ │ 部署到预发/测试环境 │ │ │ │ 保持随时可发布状态 │ │ │ └───────────────────────────────────┘ │ │ 自动部署到生产环境 │ └─────────────────────────────────────────┘二、Level 1持续集成CI长什么样目标每次代码提交后自动构建和测试快速发现问题。这个阶段不涉及任何部署。流水线配置GitLab CI 示例# .gitlab-ci.yml — 仅 CI 阶段 stages: - build - test - scan variables: MAVEN_OPTS: -Dmaven.repo.local.m2/repository # 构建阶段 build: stage: build image: maven:3.9-eclipse-temurin-17 cache: key: maven-${CI_COMMIT_REF_SLUG} paths: - .m2/repository script: - mvn clean compile -DskipTests artifacts: paths: - target/ expire_in: 1 hour rules: - if: $CI_PIPELINE_SOURCE merge_request_event - if: $CI_COMMIT_BRANCH main # 单元测试阶段 unit-test: stage: test image: maven:3.9-eclipse-temurin-17 needs: [build] script: - mvn test artifacts: reports: junit: target/surefire-reports/TEST-*.xml paths: - target/site/jacoco/ rules: - if: $CI_PIPELINE_SOURCE merge_request_event - if: $CI_COMMIT_BRANCH main # 代码质量扫描 code-scan: stage: scan image: sonarsource/sonar-scanner-cli:latest needs: [unit-test] script: - sonar-scanner -Dsonar.projectKeymyapp -Dsonar.sourcessrc -Dsonar.host.url$SONAR_HOST -Dsonar.login$SONAR_TOKEN rules: - if: $CI_COMMIT_BRANCH main这条流水线做到了什么1. PR 或 main 分支提交时自动触发2. 编译代码——有编译错误立即失败3. 跑单元测试——测试不过立即失败4. 代码质量扫描——输出质量报告5.没有部署任何东西到任何环境**培训要点**很多团队以为用了 Jenkins 就是做 CI/CD了实际上如果流水线只做到编译测试连产物都没有固化那只是 CI 的第一步。三、Level 2持续交付CD多了什么目标在 CI 基础上把构建产物打包成可部署的格式Docker 镜像自动部署到测试和预发环境保持系统处于随时可发布状态。但生产环境的发布需要人工触发。流水线配置增加部署阶段# .gitlab-ci.yml — CI CD持续交付 stages: - build - test - scan - package # 新增打包镜像 - deploy-test # 新增部署测试环境 - deploy-staging # 新增部署预发环境 - release # 新增准备发布人工审批后触发 # ... build / test / scan 同上 ... # 打包 Docker 镜像 package: stage: package image: docker:24 needs: [unit-test] services: - docker:24-dind script: - docker build -t $CI_REGISTRY_IMAGE:$CI_COMMIT_SHORT_SHA . - docker login -u $CI_REGISTRY_USER -p $CI_REGISTRY_PASSWORD $CI_REGISTRY - docker push $CI_REGISTRY_IMAGE:$CI_COMMIT_SHORT_SHA rules: - if: $CI_COMMIT_BRANCH main # 部署到测试环境 deploy-test: stage: deploy-test image: bitnami/kubectl:latest needs: [package] environment: name: test url: https://test.myapp.com script: - kubectl set image deployment/myapp app$CI_REGISTRY_IMAGE:$CI_COMMIT_SHORT_SHA -n test - kubectl rollout status deployment/myapp -n test --timeout180s rules: - if: $CI_COMMIT_BRANCH main # 部署到预发环境需要手动触发 deploy-staging: stage: deploy-staging image: bitnami/kubectl:latest needs: [deploy-test] environment: name: staging url: https://staging.myapp.com when: manual # ← 关键手动触发 script: - kubectl set image deployment/myapp app$CI_REGISTRY_IMAGE:$CI_COMMIT_SHORT_SHA -n staging - kubectl rollout status deployment/myapp -n staging --timeout180s rules: - if: $CI_COMMIT_BRANCH main # 准备生产发布需要人工审批 release: stage: release when: manual # ← 人工审批后才执行 script: - echo Release $CI_COMMIT_SHORT_SHA is ready for production - kubectl label deployment/myapp -n staging release-candidate$CI_COMMIT_SHORT_SHA rules: - if: $CI_COMMIT_BRANCH main关键区别| 特征 | CI | CD持续交付 ||------|-----|---------------|| 自动构建 | 是 | 是 || 自动测试 | 是 | 是 || 构建产物固化 | 否 | 是Docker镜像 || 自动部署测试环境 | 否 | 是 || 自动部署预发环境 | 否 | 是可设手动触发 || 生产部署 | 否 |否需人工触发|| 系统状态 | 知道代码能编译 | 随时可发布 |**踩坑提示**when: manual 是持续交付的关键——它保证生产部署永远需要人确认。如果漏了这个配置你的持续交付就变成了持续部署——测试没通过就上线了。四、Level 3持续部署Continuous Deployment的终极形态目标去掉所有人工审批环节通过测试的代码自动部署到生产环境。这需要极高的测试覆盖率和完善的监控告警支撑。流水线配置移除手动触发# .gitlab-ci.yml — CI CD Continuous Deployment stages: - build - test - scan - package - deploy-test - deploy-staging - deploy-prod # 新增自动部署生产环境 # ... 前面阶段同上 ... # 部署到预发环境自动 deploy-staging: stage: deploy-staging image: bitnami/kubectl:latest needs: [deploy-test] environment: name: staging script: - kubectl set image deployment/myapp app$CI_REGISTRY_IMAGE:$CI_COMMIT_SHORT_SHA -n staging - kubectl rollout status deployment/myapp -n staging --timeout180s # 在预发环境跑冒烟测试 - | for i in $(seq 1 30); do STATUS$(curl -s -o /dev/null -w %{http_code} https://staging.myapp.com/health) if [ $STATUS 200 ]; then break; fi sleep 5 done if [ $STATUS ! 200 ]; then exit 1; fi rules: - if: $CI_COMMIT_BRANCH main # 自动部署到生产环境金丝雀模式 deploy-prod-canary: stage: deploy-prod image: bitnami/kubectl:latest needs: [deploy-staging] environment: name: production script: # 第一步金丝雀部署——只更新1个Pod - kubectl set image deployment/myapp app$CI_REGISTRY_IMAGE:$CI_COMMIT_SHORT_SHA -n production - | # 等待金丝雀Pod健康 kubectl rollout status deployment/myapp -n production --timeout300s # 观察5分钟检查错误率 sleep 300 ERROR_RATE$(curl -s http://monitoring:9090/api/v1/query \ -d queryrate(http_requests_total{status~\5..\,namespace\production\}[5m]) \ | jq -r .data.result[0].value[1]) if [ $(awk BEGIN {print ($ERROR_RATE 0.01)}) -eq 1 ]; then echo Error rate too high, rolling back kubectl rollout undo deployment/myapp -n production exit 1 fi # 第二步全量更新 - kubectl scale deployment/myapp --replicas10 -n production rules: - if: $CI_COMMIT_BRANCH main持续部署的前提条件1.测试覆盖率 80%没有充分的自动化测试自动部署等于自杀2.完善的监控告警部署后能自动检测异常并自动回滚3.金丝雀/蓝绿部署能力降低自动部署的风险4.数据库变更零停机使用扩展-收缩模式5.功能开关Feature Flags新功能可以先上线再开启自动回滚配置示例# 监控驱动的自动回滚Prometheus ArgoCD apiVersion: argoproj.io/v1alpha1 kind: Rollout metadata: name: myapp spec: strategy: canary: steps: - setWeight: 10 # 10%流量到新版本 - pause: { duration: 5m } # 观察5分钟 analysis: # 自动分析指标 templates: - templateName: success-rate args: - name: service-name value: myapp - setWeight: 50 # 通过后增加到50% - pause: { duration: 5m } - setWeight: 100 # 全量上线五、你的团队在哪个层次| 信号 | CI | CD | Continuous Deployment ||------|-----|------|----------------------|| 部署频率 | 每周 | 每天 | 每小时 || 部署方式 | 手动 | 手动点击 | 全自动 || 测试覆盖率 | 50% | 70% | 80% || 回滚方式 | 手动找包 | 一键回滚 | 自动回滚 || 监控告警 | 基础 | 完善 | 驱动回滚 || 团队心态 | 紧张 | 从容 | 习惯 |**实践建议**不要急于追求 Continuous Deployment。先把 CI 做扎实再迈向持续交付最后在测试和监控都成熟后再尝试自动部署。跳级发展只会让线上事故频发。六、本篇要点回顾1. CI 构建测试CD CI自动部署到预发Continuous Deployment CD自动上线生产2. 持续交付的标志是when: manual持续部署的标志是自动触发自动回滚3. 金丝雀部署 自动指标分析是持续部署的安全网4. 功能开关Feature Flags让新功能可以先部署再开启降低风险5. 团队应按 CI → CD → Continuous Deployment 逐步演进不可跳级下一篇预告《工具链全景Jenkins、GitLab CI、GitHub Actions、Drone 对比选型》——了解了三个层次我们来看看实现这些层次需要哪些工具以及如何选型。