mobile wallpaper 1mobile wallpaper 2mobile wallpaper 3mobile wallpaper 4
580 字
2 分钟
CI/CD 持续集成与持续部署
2024-02-03

某电商团队每周二凌晨手动部署,一次上线要三名运维加班到天亮,还时不时因为漏步骤导致线上故障。引入 CI/CD(Continuous Integration/Continuous Deployment,持续集成与持续部署) 后,代码合并到主分支即可自动完成构建、测试、发布,部署时间从 4 小时缩短到 15 分钟。

一、CI/CD 概述#

1. 持续集成流程#

graph TB subgraph "持续集成流程" A["代码提交"] --> B["编译构建"] B --> C["单元测试"] C --> D["静态分析"] D --> E["打包制品"] E --> F["集成测试"] end
阶段工具耗时目标
编译构建Maven/Gradle/npm< 5 分钟
单元测试JUnit/Pytest< 10 分钟
静态分析SonarQube< 5 分钟
打包制品Docker/jar< 5 分钟

2. 持续部署流程#

graph LR A["代码提交"] --> B["镜像构建"] B --> C["测试环境部署"] C --> D["自动化测试"] D --> E["预生产部署"] E --> F["生产部署"]

二、GitHub Actions#

GitHub Actions 是 GitHub 内置的 CI/CD 平台,通过 YAML 文件定义工作流,与代码仓库深度集成,无需额外部署服务。

1. 基础配置#

.github/workflows/ci.yml
name: CI Pipeline
on:
push:
branches: [main, develop]
pull_request:
branches: [main]
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Set up JDK 17
uses: actions/setup-java@v4
with:
java-version: "17"
distribution: "temurin"
- name: Build with Maven
run: mvn clean package -DskipTests
- name: Run Tests
run: mvn test
- name: SonarQube Scan
uses: sonarsource/sonarqube-scan-action@master
env:
SONAR_HOST_URL: ${{ secrets.SONAR_HOST_URL }}
SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }}

2. 多环境部署#

.github/workflows/deploy.yml
name: Deploy to Environments
on:
push:
branches: [main]
jobs:
deploy-staging:
runs-on: ubuntu-latest
environment: staging
steps:
- uses: actions/checkout@v4
- name: Deploy to Staging
run: |
kubectl config use-context staging
kubectl apply -f k8s/
- name: Smoke Test
run: |
curl -f https://staging.example.com/health
deploy-production:
runs-on: ubuntu-latest
needs: deploy-staging
environment: production
steps:
- uses: actions/checkout@v4
- name: Deploy to Production
run: |
kubectl config use-context production
kubectl apply -f k8s/

三、Jenkins 流水线#

Jenkins 是历史最悠久的开源 CI/CD 服务器,通过 Jenkinsfile 声明式或脚本式语法定义流水线,插件生态极为丰富。

1. Jenkinsfile 声明式流水线#

// Jenkinsfile
pipeline {
agent any
environment {
DOCKER_IMAGE = "myapp:${BUILD_NUMBER}"
REGISTRY = "registry.example.com"
}
stages {
stage('Build') {
steps {
sh 'mvn clean package -DskipTests=false'
}
}
stage('Test') {
parallel {
stage('Unit Tests') {
steps {
sh 'mvn test'
}
}
stage('Integration Tests') {
steps {
sh 'mvn verify -DskipUnitTests'
}
}
}
}
stage('Security Scan') {
steps {
sh 'trivy image --severity HIGH,CRITICAL ${REGISTRY}/${DOCKER_IMAGE}'
}
}
stage('Build Image') {
steps {
sh '''
docker build -t ${REGISTRY}/${DOCKER_IMAGE} .
docker push ${REGISTRY}/${DOCKER_IMAGE}
'''
}
}
stage('Deploy to Staging') {
steps {
sh '''
kubectl config use-context staging
kubectl set image deployment/myapp myapp=${REGISTRY}/${DOCKER_IMAGE}
'''
}
}
stage('Smoke Test') {
steps {
sh 'curl -f https://staging.example.com/health || exit 1'
}
}
stage('Deploy to Production') {
when {
branch 'main'
}
steps {
input message: 'Approve deployment?', ok: 'Deploy'
sh '''
kubectl config use-context production
kubectl set image deployment/myapp myapp=${REGISTRY}/${DOCKER_IMAGE}
'''
}
}
}
post {
always {
cleanWs()
}
failure {
slackSend channel: '#alerts', message: "Build ${BUILD_NUMBER} failed"
}
}
}

2. 流水线最佳实践#

// Jenkinsfile 最佳实践
pipeline {
options {
buildDiscarder(logRotator(numToKeepStr: '10'))
timeout(time: 30, unit: 'MINUTES')
disableConcurrentBuilds()
}
parameters {
string(name: 'DEPLOY_ENV', defaultValue: 'staging',
description: 'Deployment environment')
booleanParam(name: 'RUN_SONAR', defaultValue: true,
description: 'Run SonarQube scan')
}
environment {
APP_NAME = 'myapp'
REGISTRY = 'registry.example.com'
}
}

四、制品管理#

1. Docker 镜像管理#

Docker 镜像是云原生时代最主流的制品格式,多阶段构建可以显著减小镜像体积。

# Dockerfile 多阶段构建
# 构建阶段
FROM maven:3.9-eclipse-temurin-17 AS builder
WORKDIR /app
COPY pom.xml .
RUN mvn dependency:go-offline
COPY src ./src
RUN mvn clean package -DskipTests
# 运行阶段
FROM eclipse-temurin:17-jre-alpine
WORKDIR /app
# 从构建阶段复制
COPY --from=builder /app/target/*.jar app.jar
# 安全配置
RUN addgroup -S appgroup && adduser -S appuser -G appgroup
USER appuser
# 健康检查
HEALTHCHECK --interval=30s --timeout=3s --start-period=5s --retries=3 \
CMD wget -qO- http://localhost:8080/health || exit 1
ENTRYPOINT ["java", "-jar", "app.jar"]

2. Helm Chart 管理#

Helm 是 Kubernetes 的包管理器,通过 Chart 模板化定义应用的部署配置,支持参数化和版本管理。

Chart.yaml
apiVersion: v2
name: myapp
description: My Application Helm Chart
version: 1.0.0
appVersion: "1.0.0"
---
replicaCount: 3
image:
repository: registry.example.com/myapp
pullPolicy: IfNotPresent
tag: "latest"
service:
type: ClusterIP
port: 8080
ingress:
enabled: true
className: nginx
annotations:
cert-manager.io/cluster-issuer: letsencrypt-prod
hosts:
- host: myapp.example.com
paths:
- path: /
pathType: Prefix
tls:
- secretName: myapp-tls
hosts:
- myapp.example.com
resources:
limits:
cpu: 1000m
memory: 1Gi
requests:
cpu: 100m
memory: 256Mi
autoscaling:
enabled: true
minReplicas: 2
maxReplicas: 10
targetCPUUtilizationPercentage: 70

五、GitOps 部署#

GitOps 是一种以 Git 仓库为唯一事实来源的部署范式,所有基础设施和应用配置都通过 Git 提交来驱动变更。

1. ArgoCD 部署#

ArgoCD 是 Kubernetes 原生的 GitOps 持续交付工具,自动监控 Git 仓库并与集群状态同步。

# ArgoCD Application
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
name: myapp
namespace: argocd
spec:
project: default
source:
repoURL: https://github.com/org/myapp
targetRevision: HEAD
path: deploy/helm
helm:
valueFiles:
- values.yaml
parameters:
- name: image.tag
value: latest
destination:
server: https://kubernetes.default.svc
namespace: production
syncPolicy:
automated:
prune: true
selfHeal: true
allowEmpty: false
syncOptions:
- CreateNamespace=true
retry:
limit: 5
backoff:
duration: 5s
factor: 2
maxDuration: 3m

2. 部署策略#

Canary(金丝雀) 部署是一种渐进式发布策略,先将新版本路由少量流量,确认无异常后再逐步扩大比例。

# 金丝雀部署
apiVersion: argoproj.io/v1alpha1
kind: Rollout
metadata:
name: myapp-rollout
spec:
replicas: 10
strategy:
canary:
steps:
- setWeight: 10
- pause: { duration: 10m }
- setWeight: 30
- pause: { duration: 10m }
- setWeight: 50
- pause: { duration: 10m }
- setWeight: 80
- pause: { duration: 10m }
- setWeight: 100
canaryMetadata:
labels:
role: canary
stableMetadata:
labels:
role: stable
canaryService:
name: myapp-canary
stableService:
name: myapp-stable

六、总结#

阶段关键实践
持续集成频繁提交、自动化测试、快速构建
持续部署渐进式部署、回滚机制
制品管理镜像签名、版本控制、安全扫描
GitOps声明式配置、自动化同步
graph LR A["代码提交"] --> B["CI 流水线"] B --> C["制品仓库"] C --> D["CD 流水线"] D --> E["Kubernetes"] E -->|同步| A

支持与分享

如果这篇文章对你有帮助,欢迎支持作者或分享给更多人

CI/CD 持续集成与持续部署
https://blog.souloss.com/posts/deploy/deploy-ci-cd-continuous-integration-and-deployment/
作者
Souloss
发布于
2024-02-03
许可协议
CC BY-NC-SA 4.0

部分信息可能已经过时