CI/CD 流水线
- CI 与 CD 的边界
- CI 持续集成
- CD(持续交付/持续部署)
- 自动化流程示例:
- Jenkins 引入到 CI/CD 流程
- 在本地或服务器上安装 Jenkins。
- 配置 Jenkins 环境
- 流程设计
- CI 阶段:Jenkins 流水线实现
- CD 阶段:Jenkins 流水线实现
- 完整流程概述
- 发版
- 发版的内容
- 发版的过程
- 发版的类型
- 发版与版本号
- 发版的目的
CI(Continuous Integration,持续集成)
CD(Continuous Delivery 或 Continuous Deployment,持续交付或持续部署)
CI 与 CD 的边界
CI:从代码提交到 Docker 镜像推送至 Docker Hub。
CD:从 Kubernetes 拉取镜像到应用运行及服务暴露
示例:
- CI: 通过mvn 创建spring boot 项目,创建java类,通过dockerfile构建镜像至docker hub
- CD: 在k8s拉取dockerhub镜像,运行应用程序,创建server进行端口映射,创建ingress暴露服务
CI 持续集成
CI 主要关注代码的开发、构建和质量保证,最终目标是生成一个稳定的可交付产物(如 Docker 镜像)
通过 Maven 创建 Spring Boot 项目
- 初始化项目结构,编写代码逻辑。
- 提交代码到版本控制系统(如 Git)
创建 Java 类
- 开发新功能或修复问题,更新代码库。
通过 Dockerfile 构建镜像
- 使用 Maven 构建项目 (mvn clean package) 并生成 JAR 文件。
- 使用 Dockerfile 将 JAR 文件打包成 Docker 镜像。
推送镜像至 Docker Hub
使用 CI 工具(如 Jenkins、GitLab CI/CD)实现自动化:
- 代码提交后触发流水线。
- 运行测试(单元测试、集成测试)。
- 构建并生成 Docker 镜像。
- 将镜像推送至 Docker Hub 或其他镜像仓库。
CD(持续交付/持续部署)
CD 主要关注如何将 CI 生成的镜像部署到实际运行环境(如 Kubernetes 集群),并确保服务的正常暴露。
在 Kubernetes 上拉取 Docker Hub 镜像
- 使用 Kubernetes Deployment 清单(YAML 文件)描述应用程序的镜像和资源需求。
- 从 Docker Hub 拉取生成的镜像,创建容器实例。
- 运行应用程序
通过 Kubernetes Deployment 控制器管理应用程序的副本(Pod)。
- 创建 Service 并进行端口映射
定义 Kubernetes Service(如 ClusterIP、NodePort 或 LoadBalancer),将应用的内部端口映射到集群外部。
- 创建 Ingress 暴露服务
定义 Ingress 资源,提供 HTTP(S) 路由规则,将外部流量路由到 Service。
- 配置域名和证书(可选,支持 HTTPS)。
自动化流程示例:
CI 流程
- 开发者提交代码至 Git 仓库(触发 CI 流水线)。
- CI 工具执行以下步骤:
拉取代码。
使用 mvn clean package 构建项目。
构建 Docker 镜像(基于 Dockerfile)。
运行测试以验证代码和镜像质量。
将镜像推送至 Docker Hub。
CD 流程
- 部署工具(如 ArgoCD、FluxCD 或 Jenkins)监听到新镜像的更新。
- 执行以下步骤:
拉取新的 Docker 镜像到 Kubernetes 集群。
创建/更新 Deployment,将镜像部署到 Pod 中。
配置 Service 以进行端口映射。
创建 Ingress 暴露服务,为用户提供访问入口。
Jenkins 引入到 CI/CD 流程
通过 Jenkins 的 CI/CD 流水线,整个开发到部署的流程自动化,减少人工干预,提高交付效率和可靠性。
基于Jenkins+K8S+harbor+git等技术链助力DevOps在企业落地实践
在本地或服务器上安装 Jenkins。
确保安装了必要的插件:
Pipeline(支持声明式流水线)。
Docker(支持 Docker 构建)。
Kubernetes CLI(支持 kubectl 命令)。
Git(拉取代码)。
Maven Integration(构建 Spring Boot 项目)
配置 Jenkins 环境
- 配置全局工具:
安装 JDK 和 Maven。
配置 Docker 和 kubectl 的路径。 - 添加 Jenkins 凭据:
Docker Hub 凭据(用于推送镜像)。
Kubernetes 集群凭据(用于 CD 部署)。
流程设计
CI 阶段:Jenkins 流水线实现
CI 的目标是构建、测试和将 Docker 镜像推送到 Docker Hub
CI 阶段:Jenkins 流水线实现
Jenkinsfile for CI
在项目根目录创建一个 Jenkinsfile,内容如下
pipeline {
agent {
docker { image 'maven:3.8.7-openjdk-17' } // 使用 Maven 镜像
}
environment {
DOCKER_HUB_CREDENTIALS = credentials('docker-hub-id') // Docker Hub 凭据
DOCKER_IMAGE = 'your-docker-hub-repo/spring-boot-app'
}
stages {
stage('Checkout Code') {
steps {
checkout scm
}
}
stage('Build and Test') {
steps {
sh 'mvn clean package'
}
}
stage('Build Docker Image') {
steps {
sh 'docker build -t ${DOCKER_IMAGE}:latest .'
}
}
stage('Push Docker Image') {
steps {
withDockerRegistry([credentialsId: 'docker-hub-id', url: '']) {
sh 'docker push ${DOCKER_IMAGE}:latest'
}
}
}
}
}
Jenkins 配置
- 在 Jenkins 上创建一个 Pipeline Job,链接到代码仓库(如 GitHub)。
- Jenkins 会自动执行流水线,完成代码构建、测试、镜像打包与推送。
CD 阶段:Jenkins 流水线实现
CD 的目标是将 Docker 镜像拉取到 Kubernetes 中,并完成部署。
创建 Kubernetes 配置文件
- deployment.yaml(用于部署镜像到 Kubernetes 集群):
apiVersion: apps/v1
kind: Deployment
metadata:
name: spring-boot-app
spec:
replicas: 2
selector:
matchLabels:
app: spring-boot-app
template:
metadata:
labels:
app: spring-boot-app
spec:
containers:
- name: spring-boot-app
image: your-docker-hub-repo/spring-boot-app:latest
ports:
- containerPort: 8080
- service.yaml(用于暴露服务端口):
apiVersion: v1
kind: Service
metadata:
name: spring-boot-service
spec:
type: NodePort
ports:
- port: 8080
targetPort: 8080
nodePort: 30001
selector:
app: spring-boot-app
- ingress.yaml(用于 Ingress 暴露服务):
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: spring-boot-ingress
spec:
rules:
- host: springboot.example.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: spring-boot-service
port:
number: 8080
Jenkinsfile for CD 在项目根目录扩展 Jenkinsfile 或创建新的 Pipeline Job:
pipeline {
agent any
environment {
KUBECONFIG_CREDENTIALS = credentials('k8s-config-id') // Kubernetes 配置凭据
}
stages {
stage('Deploy to Kubernetes') {
steps {
withKubeConfig([credentialsId: 'k8s-config-id']) {
sh 'kubectl apply -f deployment.yaml'
sh 'kubectl apply -f service.yaml'
sh 'kubectl apply -f ingress.yaml'
}
}
}
}
}
Jenkins 配置
- 创建新的 Pipeline Job,配置为自动触发(如监控 Docker Hub 镜像更新)。
- Jenkins 执行流水线,完成镜像拉取和 Kubernetes 部署。
完整流程概述
CI 阶段
提交代码到 Git 仓库后,触发 CI。
Jenkins 构建 Spring Boot 项目,生成 Docker 镜像,并推送至 Docker Hub。
CD 阶段
Jenkins 检测到新镜像(或手动触发),执行 Kubernetes 部署。
创建 Deployment、Service 和 Ingress 资源,将应用运行在 Kubernetes 集群中。
发版
发版是软件开发和运维过程中常见的术语,指的是将开发完成的功能、修复或改动版本发布给用户或部署到生产环境的过程。它是软件开发生命周期中的一个重要阶段。
发版的内容
发版通常包含以下内容:
- 新功能: 提供给用户的新特性或增强功能。
- Bug 修复: 修复已知问题或漏洞。
- 性能优化: 提高软件运行效率或资源利用率。
- 版本升级: 依赖库、框架或工具的版本更新。
- 配置更新: 改动配置项以适应新的需求或部署环境。
发版的过程
发版通常包括以下几个步骤:
- 开发和测试
开发团队完成代码开发。
测试团队进行功能测试、回归测试、性能测试等,确保版本质量。 - 打包和构建
使用构建工具(如 Maven、Gradle)将代码打包。
可能会生成可执行文件、Docker 镜像或其他可交付产物。 - 版本管理
确定发版版本号(如 v1.0.0)。
提交对应的版本标签到版本控制系统(如 Git 标签)。 - 部署
将构建好的版本部署到生产或预生产环境。
可以通过 CI/CD 流水线实现自动化部署。 - 通知和发布
发布版本公告,包括新增功能说明、修复内容和已知问题。
通知用户或相关方新版本已上线。 - 监控和验证
部署后监控系统运行状况,确保应用正常运行。
根据用户反馈修复问题(如果有)。
发版的类型
根据影响范围和目标环境,发版可以分为以下几种类型:
- 测试环境发版: 部署到测试环境,用于测试功能是否符合预期。
- 预生产环境发版: 部署到与生产环境一致的预生产环境,用于模拟真实场景验证。
- 生产环境发版: 正式发布到用户可访问的生产环境。
- 灰度发布: 部分用户或节点先体验新版本,验证稳定性后逐步扩大范围。
- 紧急发版: 修复重大问题或安全漏洞的快速发版,通常跳过部分流程。
发版与版本号
发版通常伴随版本号的更新,遵循 语义化版本号 的规则:
- 主版本号(Major):重大更新或不兼容改动(如 1.0.0 -> 2.0.0)。
- 次版本号(Minor):新增功能,向下兼容(如 1.0.0 -> 1.1.0)。
- 修订版本号(Patch):Bug 修复或小的改进(如 1.0.0 -> 1.0.1)。
发版的目的
- 将新功能或改进快速、安全地交付给用户。
- 修复系统问题,保证用户体验和系统稳定性。
- 保持软件版本的可管理性和一致性。
发版是一种规范化的软件发布过程,从开发完成到生产环境上线都需要经过严格的管理。它可以通过 CI/CD 工具自动化,并根据不同需求选择适合的发版策略(如灰度发布、蓝绿部署等)。