基于Kubernetes的CI/CD实践方案,通过Jenkins、SonarQube、Harbor等技术栈搭建完整的自动化流水线
本文介绍了基于Kubernetes的CI/CD实践方案,通过Jenkins、SonarQube、Harbor等技术栈搭建完整的自动化流水线。主要内容包括:1)CI/CD概念解析,阐述持续集成与持续交付的关系;2)项目架构设计,采用动态Slave实现资源优化;3)详细的环境部署和权限配置流程;4)完整的Jenkinsfile配置,支持多环境部署;5)实际开发测试与生产发布流程演示。该方案实现了从代码
1. CI/CD 概述
1.1 CI(持续集成)
持续集成是一种软件开发实践,通过自动化工具对代码进行编译、测试和打包,减少人工干预,提高构建效率。它的核心理念是将代码频繁地集成到共享存储库中,并通过自动化构建和测试流程来验证代码的正确性。
核心价值:
-
为开发人员提供即时反馈
-
帮助快速定位并修复问题
-
加速软件开发周期
-
提高软件质量
1.2 CD(持续交付)
持续交付是一种软件开发实践,通过自动化工具建立一套自动化的流水线,将应用程序部署到不同的环境中(开发环境、测试环境和生产环境等)。
核心价值:
-
自动化执行构建、测试、部署和发布
-
确保软件随时随地可靠交付
-
缩短交付周期
-
降低发布风险
1.3 CI/CD 关系
-
持续集成是持续交付的基础
-
CI 提高代码质量和可维护性,为 CD 提供基础
-
CD 促进更快代码交付,推动 CI 实施
-
两者相辅相成,共同推动软件开发持续改进
2. 项目架构
2.1 技术栈
-
Jenkins - 自动化服务器
-
SonarQube - 代码质量检查
-
Harbor - 镜像仓库
-
Container - 容器运行时
-
Kubernetes - 容器编排平台
2.2 项目目标
搭建完整的 CI/CD 管道,模拟实际生产环境项目开发部署流程,实现:
-
持续集成
-
持续交付
-
持续部署
3. 环境部署
3.1 基础设施
所有服务均运行在 Kubernetes 集群上,使用 NFS 共享存储。
部署文档:
-
Kubernetes 部署:https://www.cuiliangblog.cn/detail/section/15287639
-
NFS 共享存储:https://www.cuiliangblog.cn/detail/section/116191364
-
Container 部署:https://www.cuiliangblog.cn/detail/section/99861101
-
Harbor 部署:https://www.cuiliangblog.cn/detail/section/99861101
-
GitLab 部署:https://www.cuiliangblog.cn/detail/section/131418586
-
Jenkins 部署:https://www.cuiliangblog.cn/detail/section/131416735
-
SonarQube 部署:https://www.cuiliangblog.cn/detail/section/165547985
4. 权限配置
4.1 Harbor 配置
项目创建:
-
创建
spring_boot_demo项目 -
设置项目为私有
用户管理:
bash
# 创建普通用户 cuiliang # 配置项目用户权限 # 设置角色为开发者
权限说明:
| 角色 | 权限 |
|---|---|
| 访客 | 对项目有只读权限 |
| 开发人员 | 对项目有读写权限 |
| 维护人员 | 读写权限 + 创建 webhook 权限 |
| 项目管理员 | 完整权限,包括用户管理 |
4.2 GitLab 配置
群组管理:
-
创建
develop开发组 -
组权限设置为私有
项目管理:
-
创建
sprint boot demo项目 -
项目类型为私有
用户权限:
bash
# 创建普通用户 cuiliang # 将用户添加到 develop 组 # 设置角色为 Developer # 配置分支权限
5. Jenkins 配置
5.1 插件安装
| 插件名称 | 功能描述 | 参考文档 |
|---|---|---|
| GitLab Plugin | GitLab 集成 | https://www.cuiliangblog.cn/detail/section/127410630 |
| SonarQube Scanner | 代码质量检查 | https://www.cuiliangblog.cn/detail/section/165534414 |
| Kubernetes Plugin | K8s 集成 | https://www.cuiliangblog.cn/detail/section/127230452 |
| Email Extension | 邮件推送 | https://www.cuiliangblog.cn/detail/section/133029974 |
| Version Number | 版本号管理 | https://plugins.jenkins.io/versionnumber/ |
| Content Replace | 文件内容替换 | https://plugins.jenkins.io/content-replace/ |
5.2 Jenkins Slave 镜像制作
Dockerfile:
dockerfile
FROM jenkins/inbound-agent:latest-jdk17 USER root COPY kubectl /usr/bin/kubectl COPY nerdctl /usr/bin/nerdctl COPY buildctl /usr/bin/buildctl
构建命令:
bash
docker build -t harbor.local.com/cicd/jenkins-slave:v1.0 .
6. 动态 Slave 架构
6.1 架构优势
-
按需创建:根据构建需求动态创建 Slave
-
自动清理:Job 完成后自动删除 Slave Pod
-
资源优化:避免资源长期占用
-
环境隔离:每次构建都是全新的环境
6.2 工作流程
-
Jenkins Master 接收 Build 请求
-
根据配置的 Label 动态创建 Jenkins Slave Pod
-
Slave 注册到 Master 并执行 Job
-
Job 完成后注销 Slave 并删除 Pod
-
系统恢复到初始状态
7. 流水线配置
7.1 Job 配置
构建触发器:
-
配置 Webhook,代码提交时触发构建
-
支持分支过滤
流水线定义:
-
从 SCM 获取 Jenkinsfile
-
脚本路径:
Jenkinsfile-k8s.groovy
7.2 多环境支持
| 环境 | 分支 | 命名空间 | 域名 |
|---|---|---|---|
| 测试环境 | test | test | demo.test.com |
| 生产环境 | master | prod | demo.local.com |
8. 完整 Jenkinsfile
groovy
pipeline {
agent {
kubernetes {
yaml '''
apiVersion: v1
kind: Pod
metadata:
labels:
app: jenkins-slave
spec:
containers:
- name: jnlp
image: harbor.local.com/cicd/jenkins-slave:v1.0
resources:
limits:
memory: "512Mi"
cpu: "500m"
securityContext:
privileged: true
volumeMounts:
- name: buildkit
mountPath: "/run/buildkit/"
- name: containerd
mountPath: "/run/containerd/containerd.sock"
- name: kube-config
mountPath: "/root/.kube/"
readOnly: true
- name: maven
image: harbor.local.com/cicd/maven:3.9.3
resources:
limits:
memory: "512Mi"
cpu: "500m"
command:
- 'sleep'
args:
- '9999'
volumeMounts:
- name: maven-data
mountPath: "/root/.m2"
- name: buildkitd
image: harbor.local.com/cicd/buildkit:v0.13.2
resources:
limits:
memory: "256Mi"
cpu: "500m"
securityContext:
privileged: true
volumeMounts:
- name: buildkit
mountPath: "/run/buildkit/"
- name: buildkit-data
mountPath: "/var/lib/buildkit/"
- name: containerd
mountPath: "/run/containerd/containerd.sock"
volumes:
- name: maven-data
persistentVolumeClaim:
claimName: jenkins-maven
- name: buildkit
hostPath:
path: /run/buildkit/
- name: buildkit-data
hostPath:
path: /var/lib/buildkit/
- name: containerd
hostPath:
path: /run/containerd/containerd.sock
- name: kube-config
secret:
secretName: kube-config
'''
retries 2
}
}
environment {
HARBOR_CRED = "harbor-cuiliang-password"
IMAGE_NAME = ""
IMAGE_APP = "demo"
branchName = ""
}
stages {
stage('拉取代码') {
environment {
GITLAB_CRED = "gitlab-cuiliang-password"
GITLAB_URL = "http://gitlab.cicd.svc/develop/sprint_boot_demo.git"
}
steps {
echo '开始拉取代码'
checkout scmGit(branches: [[name: '*/*']], extensions: [], userRemoteConfigs: [[credentialsId: "${GITLAB_CRED}", url: "${GITLAB_URL}"]])
script {
def branch = env.GIT_BRANCH ?: 'master'
branchName = branch.split('/')[-1]
}
echo '拉取代码完成'
}
}
stage('编译打包') {
steps {
container('maven') {
echo '开始编译打包'
sh 'mvn clean package'
echo '编译打包完成'
}
}
}
stage('代码审查') {
environment {
SONARQUBE_SCANNER = "SonarQubeScanner"
SONARQUBE_SERVER = "SonarQubeServer"
}
steps {
echo '开始代码审查'
script {
def scannerHome = tool "${SONARQUBE_SCANNER}"
withSonarQubeEnv("${SONARQUBE_SERVER}") {
sh "${scannerHome}/bin/sonar-scanner"
}
}
echo '代码审查完成'
}
}
stage('构建镜像') {
environment {
HARBOR_URL = "harbor.local.com"
HARBOR_PROJECT = "spring_boot_demo"
IMAGE_TAG = ''
IMAGE_NAME = ''
}
steps {
echo '开始构建镜像'
script {
if (branchName == 'master') {
IMAGE_TAG = VersionNumber versionPrefix: 'p', versionNumberString: '${BUILD_DATE_FORMATTED, "yyMMdd"}.${BUILDS_TODAY}'
} else if (branchName == 'test') {
IMAGE_TAG = VersionNumber versionPrefix: 't', versionNumberString: '${BUILD_DATE_FORMATTED, "yyMMdd"}.${BUILDS_TODAY}'
} else {
error("Unsupported branch: ${params.BRANCH}")
}
IMAGE_NAME = "${HARBOR_URL}/${HARBOR_PROJECT}/${IMAGE_APP}:${IMAGE_TAG}"
sh "nerdctl build --insecure-registry -t ${IMAGE_NAME} . "
}
echo '构建镜像完成'
echo '开始推送镜像'
withCredentials([usernamePassword(credentialsId: "${HARBOR_CRED}", passwordVariable: 'HARBOR_PASSWORD', usernameVariable: 'HARBOR_USERNAME')]) {
sh """nerdctl login --insecure-registry ${HARBOR_URL} -u ${HARBOR_USERNAME} -p ${HARBOR_PASSWORD}
nerdctl push --insecure-registry ${IMAGE_NAME}"""
}
echo '推送镜像完成'
echo '开始删除镜像'
script {
sh "nerdctl rmi -f ${IMAGE_NAME}"
}
echo '删除镜像完成'
}
}
stage('项目部署') {
environment {
YAML_NAME = "k8s.yaml"
}
steps {
echo '开始修改资源清单'
script {
if (branchName == 'master' ) {
NAME_SPACE = 'prod'
DOMAIN_NAME = 'demo.local.com'
} else if (branchName == 'test') {
NAME_SPACE = 'test'
DOMAIN_NAME = 'demo.test.com'
} else {
error("Unsupported branch: ${params.BRANCH}")
}
}
contentReplace(configs: [fileContentReplaceConfig(configs: [fileContentReplaceItemConfig(replace: "${IMAGE_NAME}", search: 'IMAGE_NAME'),
fileContentReplaceItemConfig(replace: "${NAME_SPACE}", search: 'NAME_SPACE'),
fileContentReplaceItemConfig(replace: "${DOMAIN_NAME}", search: 'DOMAIN_NAME')],
fileEncoding: 'UTF-8',
filePath: "${YAML_NAME}",
lineSeparator: 'Unix')])
echo '修改资源清单完成'
sh "cat ${YAML_NAME}"
echo '开始部署资源清单'
sh "kubectl apply -f ${YAML_NAME}"
echo '部署资源清单完成'
}
}
}
post {
always {
echo '开始发送邮件通知'
emailext(subject: '构建通知:${PROJECT_NAME} - Build # ${BUILD_NUMBER} - ${BUILD_STATUS}!',
body: '${FILE,path="email.html"}',
to: 'cuiliang0302@qq.com')
echo '邮件通知发送完成'
}
}
}
9. 项目演示
9.1 开发测试阶段
开发流程:
bash
# 切换到 test 分支 git checkout -b test origin/test # 修改代码版本信息 vim src/main/java/com/example/springbootdemo/HelloWorldController.java # 提交代码 git add . git commit -m "test环境更新版本至v2" git push
自动化流程触发:
-
自动创建 Jenkins Slave Pod
-
执行编译、打包、代码审查
-
构建测试环境镜像(标签格式:t231215.1)
-
部署到 test 命名空间
-
发送邮件通知
9.2 生产发布阶段
发布流程:
bash
# 切换到 master 分支 git checkout master # 更新生产环境版本 vim src/main/java/com/example/springbootdemo/HelloWorldController.java # 提交代码 git add . git commit -m "生产环境更新版本至v2" git push
自动化流程触发:
-
执行完整 CI/CD 流程
-
构建生产环境镜像(标签格式:p231215.1)
-
部署到 prod 命名空间
-
生产环境服务更新
10. 项目资源
代码仓库:
部署效果:
-
测试环境:http://demo.test.com
11. 总结
本项目成功实现了基于 Kubernetes 的完整 CI/CD 流水线,具备以下特点:
11.1 技术优势
-
完整的自动化流程:从代码提交到生产部署全自动化
-
多环境支持:测试环境和生产环境独立部署
-
动态资源管理:按需创建和销毁构建资源
-
代码质量保障:集成 SonarQube 代码审查
-
安全可靠:私有镜像仓库和权限控制
11.2 业务价值
-
提升开发效率:自动化流程减少人工操作
-
提高软件质量:持续的代码审查和测试
-
降低发布风险:标准化部署流程
-
快速迭代能力:支持频繁的版本发布
通过这个项目,团队可以实现高效的持续集成和持续交付,为业务快速发展提供强有力的技术支撑。
更多推荐




所有评论(0)