传统软件开发中,集成是一个痛苦且耗时的阶段。开发者各自完成功能后,在项目末期集中集成,往往发现大量冲突和 bug,修复成本极高。持续集成 (Continuous Integration, CI) 的理念是:让开发者频繁地(每天多次)将代码合并到主干,通过自动化构建和测试快速发现集成问题。持续交付 (Continuous Delivery, CD) 在此基础上,将自动化部署的能力延伸到预生产环境,使得软件可以随时进入生产环境。
CI 流水线 的典型阶段:
CD 流水线 的典型阶段:
# .gitlab-ci.yml 或 Jenkinsfile 示例
stages:
- build
- test
- package
- deploy
build:
stage: build
script:
- mvn compile
- mvn package
test:
stage: test
script:
- mvn test
- sonar-scanner
package:
stage: package
script:
- docker build -t myapp:${CI_COMMIT_SHA} .
- docker push myapp:${CI_COMMIT_SHA}
deploy:
stage: deploy
script:
- kubectl set image deployment/myapp myapp=myapp:${CI_COMMIT_SHA}
一条流水线可能包含数十个步骤,涉及编译、测试、打包、部署等多个阶段。一个设计良好的流水线应该快(快速反馈)、稳(失败时快速定位)、可重现(环境一致)。
流水线设计模式:
# 并行执行多个测试作业
test:unit:
stage: test
script: npm run test:unit
test:integration:
stage: test
script: npm run test:integration
needs: []
test:e2e:
stage: test
script: npm run test:e2e
needs: []
# 依赖缓存
cache:
paths:
- node_modules
- .m2/repository
# 并行矩阵 (测试不同环境)
deploy:
stage: deploy
parallel:
matrix:
- ENVIRONMENT: [staging, production]
script: deploy_to_${ENVIRONMENT}
CI 流水线的最终产出是制品 (Artifact),如 Docker 镜像、jar 包、npm 包等。制品不仅需要存储,还需要版本管理、安全扫描、访问控制。制品仓库(如 Docker Registry、Nexus、JFrog Artifactory)是 CI/CD 体系中承上启下的关键组件。
制品仓库的核心功能:
# Docker 镜像构建和推送
docker build -t myapp:${CI_COMMIT_SHA} .
docker tag myapp:${CI_COMMIT_SHA} registry.example.com/myapp:${CI_COMMIT_SHA}
docker push registry.example.com/myapp:${CI_COMMIT_SHA}
# 使用环境特定的标签
docker tag registry.example.com/myapp:${CI_COMMIT_SHA} registry.example.com/myapp:latest
docker tag registry.example.com/myapp:${CI_COMMIT_SHA} registry.example.com/myapp:staging
docker push registry.example.com/myapp:latest
docker push registry.example.com/myapp:staging
# 制品版本命名规范
# 推荐: v{主版本}.{次版本}.{补丁}-{构建号}
# 示例: v1.2.3-20250523-1234
# 使用 Helm 打包和推送
helm package ./chart --version ${VERSION}
helm push myapp-${VERSION}.tgz registry.example.com/helm-charts
传统的停机部署(停止服务 → 更新 → 重启)会导致服务中断,对于高可用系统不可接受。现代部署策略通过流量控制和多版本共存的方式,实现零宕机的部署。常见的三种策略:蓝绿部署(两套环境切换)、金丝雀部署(逐步放量)、滚动部署(逐步替换)。
| 策略 | 原理 | 优点 | 缺点 |
|---|---|---|---|
| 蓝绿部署 | 两套完全相同的环境(蓝/绿),流量切换 | 快速回滚,部署简单 | 资源成本翻倍 |
| 金丝雀部署 | 先部署新版本到少量实例,逐步扩大 | 风险可控,可收集真实流量验证 | 部署时间长,需要流量控制 |
| 滚动部署 | 逐个替换旧版本实例,保持总容量不变 | 资源利用率高,无额外成本 | 回滚慢,升级过程中可能有不一致 |
# 蓝绿部署 (通过 Service 切换标签)
# 蓝色版本 (当前)
kubectl apply -f deployment-blue.yaml
# 绿色版本 (新)
kubectl apply -f deployment-green.yaml
# 切换流量 (修改 Service 的 selector)
kubectl patch service myapp -p '{"spec":{"selector":{"version":"green"}}}'
# 金丝雀部署 (使用 Istio 或 Service 权重)
# 流量权重: 90% 旧, 10% 新
kubectl apply -f virtualservice-canary.yaml
# 滚动部署 (Kubernetes Deployment 默认策略)
# 配置滚动更新参数
apiVersion: apps/v1
kind: Deployment
spec:
strategy:
type: RollingUpdate
rollingUpdate:
maxSurge: 25%
maxUnavailable: 25%
传统的 CI/CD 流程中,部署是通过命令式的脚本执行的(如 kubectl apply)。这种方式存在几个问题:环境漂移(实际状态与期望状态不一致)、审计困难(谁部署了什么)、回滚复杂(需要手动恢复)。GitOps 将Git 作为唯一的真理来源,用声明式配置描述系统的期望状态,通过自动同步机制将实际状态调整为期望状态。
GitOps 工作流:
# Git 仓库结构 (应用配置)
myapp-config/
├── apps/
│ ├── myapp
│ │ ├── deployment.yaml
│ │ ├── service.yaml
│ │ └── configmap.yaml
│ └── mysql
│ ├── statefulset.yaml
│ └── pvc.yaml
├── environments/
│ ├── staging/
│ │ └── values.yaml
│ └── production/
│ └── values.yaml
└── argo-cd/
├── application-staging.yaml
└── application-production.yaml
# Argo CD Application 定义
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
name: myapp-staging
namespace: argocd
spec:
project: default
source:
repoURL: https://github.com/example/myapp-config
targetRevision: HEAD
path: apps/myapp
destination:
server: https://kubernetes.default.svc
namespace: staging
syncPolicy:
automated:
prune: true
selfHeal: true
Argo CD 是 Kubernetes 生态中最流行的 GitOps 工具之一。它是一个声明式的 GitOps 持续交付工具,能够自动同步 Git 仓库中的配置到 Kubernetes 集群。Argo CD 的核心功能包括:多集群管理、差异可视化、自动同步、回滚、钩子等。
Argo CD 核心组件:
同步过程:
# 使用 Argo CD 钩子执行数据库迁移
apiVersion: batch/v1
kind: Job
metadata:
name: db-migration
annotations:
argocd.argoproj.io/hook: PreSync # 在同步前执行
argocd.argoproj.io/hook-delete-policy: BeforeHookCreation # 钩子执行前删除旧实例
spec:
template:
spec:
containers:
- name: migrate
image: myapp:latest
command: ["sh", "-c", "python manage.py migrate"]
restartPolicy: Never
# 查看 Application 同步状态
kubectl get application myapp -n argocd -o wide
# 手动触发同步
argocd app sync myapp
# 查看同步历史
argocd app history myapp