软件研发 --- CI/CD简介
一、传统部署方式(无 CI/CD 或 初级 CI/CD)
这种模式通常手动操作较多,自动化程度较低,常见于早期项目或小型团队。
-
准备环境:
-
手动配置服务器(物理机、虚拟机或云主机)。
-
安装操作系统、运行时环境(如 Node.js, Python, Java JRE/JDK)、数据库(如 MySQL, PostgreSQL, Redis)、Web 服务器(如 Nginx, Apache)等依赖软件。
-
配置防火墙、安全组规则、域名解析等网络设置。
-
(可选)配置负载均衡器。
-
-
代码打包/构建:
-
开发人员在本地或特定的“构建服务器”上运行构建命令(如
npm run build
,mvn clean package
,docker build
)生成可部署的产物(如 Jar/War 包、静态文件目录、Docker 镜像)。
-
-
传输部署包:
-
手动将构建好的产物(如 Jar 包、静态文件压缩包、Docker 镜像文件)通过
scp
、rsync
、FTP 或者简单的上传下载方式,复制到目标服务器上的指定目录。
-
-
部署与启动:
-
在目标服务器上手动操作:
-
停止旧版本服务(如
systemctl stop myapp
,kill <pid>
)。 -
备份旧版本文件(可选但推荐)。
-
解压部署包或替换文件。
-
执行数据库迁移脚本(如果涉及,通常手动运行
migrate
命令)。 -
启动新版本服务(如
systemctl start myapp
,java -jar app.jar
,docker run ...
)。 -
重启 Web 服务器(如
systemctl reload nginx
)。
-
-
-
验证:
-
手动访问网站或调用 API,检查核心功能是否正常。
-
查看日志文件是否有错误。
-
特点: 步骤繁琐、容易出错、重复劳动多、部署频率低、回滚较慢(需要手动操作)、缺乏一致性和可追溯性。
二、基于 CI/CD 的部署方式
CI/CD 的核心是自动化和流水线,目标是实现快速、可靠、频繁的软件交付。
-
CI (持续集成):
-
代码提交: 开发者将代码推送到共享的版本控制仓库(如 GitLab, GitHub, Bitbucket)。
-
触发构建: 代码提交(通常到特定分支,如
main
/master
或develop
)自动触发 CI 服务器(如 Jenkins, GitLab CI/CD, GitHub Actions, CircleCI, Travis CI)。 -
自动化构建与测试: CI 服务器执行预设的流水线任务:
-
拉取代码: 获取最新提交的代码。
-
安装依赖: 安装项目所需的各种库(
npm install
,pip install -r requirements.txt
,mvn dependency:resolve
)。 -
代码质量检查 (可选): 运行 Linter、静态代码分析工具(如 ESLint, Pylint, SonarQube)。
-
构建: 编译代码、打包、生成可部署产物(如 Jar/War 包、静态资源、Docker 镜像)。
-
单元测试 & 集成测试: 运行自动化测试套件。关键步骤! 如果测试失败,流水线通常会中止,并向团队发出通知。
-
存储产物: 将成功的构建产物上传到制品仓库(如 Nexus, Artifactory, Docker Registry, AWS S3)以便后续部署使用。
-
-
-
CD (持续交付/持续部署):
-
触发部署:
-
持续交付: CI 阶段成功后,流水线准备好部署包(如上传到制品库),但部署到生产环境通常需要手动审批触发。
-
持续部署: CI 阶段成功后,流水线自动将变更部署到目标环境(如测试、预发布、生产)。这是更高级、更自动化的形式,要求极高的测试覆盖率和流程成熟度。
-
-
部署到目标环境:
-
流水线任务(可能在同一个流水线中,也可能是被触发的另一个流水线)会根据配置,将构建好的产物部署到指定的环境:
-
测试环境: 部署最新构建,供 QA 或自动化测试验证。
-
预发布环境 (Staging): 模拟生产环境,进行最终验收测试、性能测试等。
-
生产环境: 部署经过验证的版本。
-
-
部署方式:
-
脚本化部署: CI/CD 工具通过 SSH 连接到目标服务器,执行部署脚本(停止服务、备份、替换文件、迁移数据库、启动服务)。
-
容器化部署 (主流): CI/CD 工具将构建好的 Docker 镜像推送到镜像仓库,然后在目标环境(通常是 Kubernetes 集群 或 Docker Swarm)触发滚动更新(
kubectl apply
,docker service update
)。Kubernetes 控制器会自动完成新 Pod 的创建、健康检查、流量切换和旧 Pod 的终止。 -
Serverless 部署: CI/CD 工具通过 CLI 或 SDK 将函数代码包或容器镜像部署到 Serverless 平台(如 AWS Lambda, Azure Functions)。
-
基础设施即代码 (IaC): 部署过程通常伴随着使用 Terraform, CloudFormation, Ansible 等工具来确保目标环境的基础设施配置一致且版本化。
-
-
-
自动化验证:
-
部署后,流水线可以自动运行简单的冒烟测试或健康检查,快速验证服务是否基本可用。
-
-
通知与反馈: 流水线每个阶段(成功/失败)的结果会通知给团队(如 Slack, Email)。
-
部署过程简述(基于 CI/CD + Kubernetes 示例)
-
开发者 Push 代码到 Git 仓库的
main
分支。 -
GitLab CI Runner 被触发:
-
拉取代码。
-
npm install
安装依赖。 -
npm run test
运行单元测试。 -
npm run build
生成静态文件。 -
docker build -t my-registry.com/my-app:$CI_COMMIT_SHA .
构建 Docker 镜像(用提交 SHA 打标签)。 -
docker push my-registry.com/my-app:$CI_COMMIT_SHA
推送镜像到私有仓库。 -
运行集成测试(可选,可能在独立环境)。
-
-
CI 阶段成功,触发 CD 阶段部署到 Staging:
-
使用
kubectl
或 Helm 命令,将 Kubernetes 部署 (Deployment) 中的镜像标签更新为my-registry.com/my-app:$CI_COMMIT_SHA
。 -
Kubernetes 执行滚动更新:启动新 Pod -> 通过健康检查 -> 将流量切换到新 Pod -> 终止旧 Pod。
-
自动运行冒烟测试验证 Staging 环境。
-
-
(持续交付模式)手动审批部署到生产环境。
-
CD 阶段部署到生产:
-
类似步骤 3,但目标是生产环境的 Kubernetes 集群。
-
通常会采用蓝绿部署或金丝雀发布策略,以最小化风险。
-
-
监控与日志: 部署后,通过 Prometheus/Grafana 监控指标,通过 ELK 或 Loki 查看日志。如有问题,快速回滚(通常也是自动化或一键操作)。
使用 CI/CD 的核心优势
-
自动化: 减少人工操作,提高效率,避免人为错误。
-
快速反馈: 开发人员能立即知道代码提交是否破坏了构建或测试。
-
频繁发布: 使小批量、低风险地频繁发布新特性成为可能。
-
一致性: 保证构建、测试、部署过程在不同环境的一致性。
-
可靠性: 自动化测试和标准化流程提高了部署质量。
-
可回滚: 回滚通常更快、更容易(尤其是容器化部署)。
-
可追溯性: 每个部署对应特定的代码提交和构建产物,便于追踪问题。
-
标准化: 团队使用统一的流程。
总结
-
传统部署: 手动步骤多,易出错,效率低,适合简单应用或初期探索。
-
CI/CD 部署: 自动化程度高,流程标准化,支持快速迭代,是现代软件开发运维的标准实践。核心在于将构建、测试、部署等步骤自动化串联成流水线,并通过严格的测试保障质量。
在实际项目中,部署方式的选择和 CI/CD 流水线的复杂度会根据具体需求(如发布频率、团队规模、技术栈、基础设施、风险承受能力)而调整。现在越来越多的项目,尤其是新项目,都会优先采用 CI/CD 流程。