← 返回文章列表

CI/CD 完整指南:从理论到 K8s 实战

详细讲解 CI/CD 概念、持续集成与持续交付的区别、完整流水线设计,以及基于 Kubernetes 的企业级 CI/CD 架构实战。

10 分钟阅读
字号

一、CI/CD 是什么

1.1 基本概念

CI = Continuous Integration(持续集成)
CD = Continuous Delivery(持续交付)
    或   Continuous Deployment(持续部署)

核心思想:软件开发的"流水线"——代码从开发到生产环境的自动化流转。

1.2 传统开发 vs CI/CD

传统开发模式(问题多)

开发者A ──▶ 代码 ──▶ ──▶ ──▶ ──▶ ──▶ ──▶ ──▶ 测试环境

开发者B ──▶ 代码 ──▶ ──▶ ──▶ ──▶ ──▶ ──▶ 攒够再测

开发者C ──▶ 代码 ──▶ ──▶ ──▶ ──▶ ──▶ ──▶

问题

  • 多人代码合并困难(代码冲突地狱)
  • 最后才集成,问题发现晚
  • 测试靠人工,效率低
  • 上线靠人肉,风险高

CI/CD 开发模式(自动化)

开发者A ──▶ 代码 ──▶ ──▶ Git ──▶ 自动构建 ──▶ 自动测试 ──▶
开发者B ──▶ 代码 ──▶ ──▶ Git ──▶ 自动构建 ──▶ 自动测试 ──▶
开发者C ──▶ 代码 ──▶ ──▶ Git ──▶ 自动构建 ──▶ 自动测试 ──▶

优点:每次代码提交都自动构建测试,问题早发现,自动化发布,可回滚。


二、持续集成 CI 详解

2.1 CI 的流程

开发者 ──▶ git push ──▶ GitLab ──▶ Webhook ──▶ Jenkins 触发


                                              ┌──────────────┐
                                              │   构建阶段    │
                                              │  • 拉取代码   │
                                              │  • 安装依赖   │
                                              │  • 编译打包   │
                                              └──────────────┘


                                              ┌──────────────┐
                                              │   测试阶段    │
                                              │  • 单元测试   │
                                              │  • 代码扫描   │
                                              │  • 集成测试   │
                                              └──────────────┘


                                              ┌──────────────┐
                                              │   构建结果    │
                                              │  • 镜像推送   │
                                              │  • 通知      │
                                              └──────────────┘

2.2 CI 做什么

1. 代码编译

语言命令
Javamvn compile / gradle build
Gogo build
Pythonpython setup.py build
Node.jsnpm run build

2. 单元测试

语言框架
JavaJUnit + Mockito
Gogo test
Pythonpytest / unittest
JavaScriptJest / Mocha

3. 代码质量扫描:使用 SonarQube 检测代码异味、安全漏洞、代码覆盖率。

4. 打包构建产物:Java jar 包、Go 二进制文件、前端镜像包。


三、持续交付 vs 持续部署

3.1 持续交付(Continuous Delivery)

代码 ──▶ 自动构建测试 ──▶ 自动打包 ──▶ 人工确认 ──▶ 发布


                                    人手动点击"确认上线"

特点:测试环境自动,生成环境人工介入。

3.2 持续部署(Continuous Deployment)

代码 ──▶ 自动构建测试 ──▶ 自动打包 ──▶ 自动发布 ──▶ 生产

特点:全自动,无需人工介入。

3.3 总结

阶段说明
CI(持续集成)保证代码质量
CD(持续交付)自动到待发布状态,人工决定何时发布
CD(持续部署)代码自动发布到生产环境

生产环境通常用"持续交付",需要人工确认。


四、完整的 CI/CD 流程图

┌─────────┐     ┌─────────┐     ┌─────────┐     ┌─────────┐
│  开发   │────▶│  提交   │────▶│  构建   │────▶│  测试   │
│  写代码  │     │  push  │     │ compile │     │UT/IT    │
└─────────┘     └─────────┘     └─────────┘     └────┬────┘


                                                  ┌─────────┐
                                                  │ 质量扫描│
                                                  │ SonarQube│
                                                  └────┬────┘


                                                  ┌─────────┐
                                                  │ 打包镜像│
                                                  │ Docker │
                                                  └────┬────┘

                              ┌────────────────────────┼────────┐
                              ▼                        ▼        ▼
                        ┌──────────┐           ┌──────────┐
                        │ 测试环境  │           │ 预发环境  │
                        │ SIT/UAT  │           │ Staging  │
                        └────┬─────┘           └────┬─────┘
                             │                     │
                             ▼                     ▼
                        ┌──────────┐           ┌──────────┐
                        │ 自动化测试│           │ 自动化测试│
                        │ 回归测试  │           │ 回归测试  │
                        └────┬─────┘           └────┬─────┘
                             │         ┌───────────┘
                             │         │
                             │         ▼
                             │   ┌──────────┐
                             │   │ 人工验收  │
                             │   │ 审批     │
                             │   └────┬─────┘
                             │        │
                             │        ▼
                             │   ┌──────────┐
                             └──▶│ 生产环境  │
                                 │ Product  │
                                 └──────────┘

五、环境说明

环境说明
开发环境(Dev)开发人员本地,代码编写、调试
测试环境(SIT/QA)系统集成测试、功能测试
预发环境(Staging/UAT)用户验收测试,最接近生产环境
生产环境(Production)真实用户访问,金丝雀发布/灰度发布

六、企业级 CI/CD 架构

6.1 架构图

┌──────────────────────────────────────────────────────────┐
│                      开发机 (test06)                     │
│                     192.168.8.116                        │
│                                                          │
│   开发者写代码 ──▶ git push ──▶ GitLab                  │
└──────────────────────────────────────────────────────────┘


┌──────────────────────────────────────────────────────────┐
│                      工具集群 (test07)                    │
│                     192.168.8.117                        │
│                                                          │
│   ┌─────────┐  ┌─────────┐  ┌─────────┐               │
│   │Jenkins │  │ GitLab  │  │ Harbor  │               │
│   │  CI/CD  │  │ 代码仓库  │  │ 镜像仓库  │               │
│   │  调度   │  │         │  │         │               │
│   └─────────┘  └─────────┘  └─────────┘               │
└──────────────────────────────────────────────────────────┘

              ┌───────────────┴───────────────┐
              ▼                               ▼
┌────────────────────────┐      ┌────────────────────────┐
│    测试集群 (test04)   │      │   生产集群 (test05)   │
│   192.168.8.114       │      │   192.168.8.115       │
│                        │      │                        │
│   • RD 测试           │      │   • product 命名空间  │
│   • 功能验证          │      │   • staging 命名空间  │
│                        │      │                        │
└────────────────────────┘      └────────────────────────┘

6.2 具体流程

Step 1:开发机写代码

# 克隆代码仓库
git clone ssh://git@git.k8s.local:30022/root/greenhat.git
 
# 创建开发分支
git checkout -b feature/login
 
# 编写代码
vim main.go
 
# 提交并推送
git add .
git commit -m "feat: 添加登录功能"
git push origin feature/login

Step 2:GitLab 接收代码,触发 Webhook

GitLab 检测到代码 push,发送 Webhook 到 Jenkins。

Step 3:Jenkins 动态创建 Pod Agent

Jenkins Master ◀──调度──▶ K8s API


                    动态创建 Pod Agent
                    (jnlp 镜像)
                    执行完自动销毁

Step 4:CI 流水线执行

pipeline {
    agent any
 
    environment {
        REGISTRY = 'harbor.k8s.local'
        PROJECT = 'greenhat'
        IMAGE = "${REGISTRY}/${PROJECT}/app"
    }
 
    stages {
        stage('拉取代码') {
            steps {
                git 'ssh://git@git.k8s.local:30022/root/greenhat.git'
            }
        }
 
        stage('构建') {
            steps {
                sh 'go build -o app .'
            }
        }
 
        stage('单元测试') {
            steps {
                sh 'go test ./... -v'
            }
        }
 
        stage('代码扫描') {
            steps {
                script {
                    def scannerHome = tool 'SonarQube'
                    withSonarQubeEnv('SonarQube') {
                        sh "${scannerHome}/bin/sonar-scanner"
                    }
                }
            }
        }
 
        stage('制作镜像') {
            steps {
                sh """
                    docker build -t ${IMAGE}:${BUILD_NUMBER} .
                    docker tag ${IMAGE}:${BUILD_NUMBER} ${IMAGE}:latest
                """
            }
        }
 
        stage('推送镜像') {
            steps {
                sh """
                    docker login ${REGISTRY} -u admin -p Harbor12345
                    docker push ${IMAGE}:${BUILD_NUMBER}
                    docker push ${IMAGE}:latest
                """
            }
        }
 
        stage('部署到测试环境') {
            steps {
                sh """
                    kubectl set image deployment/app \
                      app=${IMAGE}:${BUILD_NUMBER} \
                      -n test
                """
            }
        }
    }
}

Step 5:部署到测试环境

kubectl set image deployment/app \
  app=harbor.k8s.local/greenhat/app:v1.0.1 \
  -n test

K8s 调度流程:

  1. kube-apiserver 收到请求
  2. Deployment Controller 更新 ReplicaSet
  3. Scheduler 选择节点
  4. kubelet 在选中的节点上启动新 Pod
  5. kubelet 从 Harbor 拉取镜像
  6. 启动容器

Step 6:人工审批

stage('部署到生产环境') {
    when {
        branch 'master'
    }
    steps {
        input message: '确认部署到生产环境?',
              ok: '确认',
              submitter: 'ops-team'
        sh """
            kubectl set image deployment/app \
              app=${IMAGE}:${BUILD_NUMBER} \
              -n production
        """
    }
}

Step 7:部署到生产环境(金丝雀发布)

# 先更新 10% 的 Pod
kubectl patch deployment/app -n product ...
 
# 观察指标(5-10分钟)
# • 错误率是否上升
# • 响应时间是否正常
# • Pod 是否 Running
 
# 确认无问题后全量更新
kubectl scale deployment/app --replicas=10 -n product

七、金丝雀发布(Canary Release)

背景:以前矿工下矿井前,会先放一只金丝雀进去测试氧气是否充足。

v1 版本(老版本)

   │ 100% 流量 ────────────────────────────────────┐
   │                                                   │
   │                        升级中...
   │                        10% 流量 ─────────────┐ │
   │                                           ▼    │
   │                                    ┌──────────┐ │
   │                                    │ v2 版本   │ │
   │                                    │ (新版本)  │ │
   │                                    │ 10% 流量  │ │
   │                                    └──────────┘ │
   │                                           │
   │                              观察错误率、响应时间
   │                                           │
   │                                       ✅ 没问题
   │                                           │
   │                                全量切换到 v2

如果有问题? 回滚到 v1。


八、回滚机制

需要回滚的情况

  • 错误率突然上升
  • 响应时间暴增
  • 新版本有 Bug
  • 业务指标异常

回滚命令

# 快速回滚到上一个版本
kubectl rollout undo deployment/app -n product
 
# 回滚到指定版本
kubectl rollout undo deployment/app --to-revision=3 -n product
 
# 查看部署历史
kubectl rollout history deployment/app -n product

九、总结

CI/CD 流程一句话总结

开发机写代码 ──▶ GitLab 接收 ──▶ Jenkins 触发 ──▶
 
CI(持续集成):
  拉代码 → 编译 → 测试 → 扫描 → 打包镜像 → 推送到 Harbor
 
CD(持续交付/部署):
  部署测试环境 → 自动化测试 → 部署预发 → 人工审批 → 部署生产

核心价值

  • 自动化:减少人工干预,降低错误率
  • 快速迭代:代码提交后快速反馈
  • 质量保障:每个阶段都有测试和检查
  • 可回滚:出问题可以快速回退到稳定版本
分享

// RELATED_POSTS

0%