> 技术文档 > DevOps篇之Jenkins实现k8s集群版本发布以及版本管理

DevOps篇之Jenkins实现k8s集群版本发布以及版本管理


设计思路

通过Jenkins 实现 Kubernetes 集群版本发布和版本管理。并且利用Jenkins实现多集群 K8s 发布。首先需要了解Helm 的应用场景,以及 GitLab 中配置多集群 KUBECONFIG 等问题。现在工具采用 Jenkins,所以需要重点放在 Jenkins 与 K8s 的集成上,包括版本发布流程、版本管理、回滚机制等。
1、首先,应该考虑整体架构,Jenkins 需要与 K8s 集群通信,所以需要配置 KUBECONFIG,可能涉及凭证管理。然后,版本发布的流程通常包括代码拉取、构建、测试、打包镜像、推送镜像、使用 Helm 或 kubectl 部署到 K8s。版本管理需要跟踪每个发布的版本,可能包括镜像标签、Helm Chart 版本,以及回滚的能力。
2、接下来,环境准备,包括 Jenkins 插件(如 Kubernetes 插件、Docker 插件、Credentials Binding 插件),然后是凭证配置,比如 KUBECONFIG 存储在 Jenkins 凭证中。然后是流水线设计,可能包括多个阶段:构建、测试、构建镜像、推送镜像、部署到 K8s(开发、测试、生产环境),每个阶段的具体操作。
3、版本管理方面,需要强调镜像标签的规范,比如使用 Git Commit 哈希、构建号,确保唯一性和可追溯性。使用 Helm 的话,Chart 版本也需要管理,结合 Jenkins 的构建历史,可以跟踪每个版本的部署情况。回滚机制可以利用 K8s 的 Deployment 历史或 Helm 的回滚功能,在 Jenkins 中通过命令实现。
4、还要考虑多环境部署,比如开发环境自动部署,测试和生产环境手动触发,或者按顺序部署。另外,版本控制的最佳实践,比如使用 Git 仓库管理配置文件,集成测试确保发布质量,以及通知机制,比如部署结果通过邮件或 Slack 通知团队。
在 Jenkins 中实现 Kubernetes(K8s)集群的版本发布与版本管理,核心是通过流水线自动化结合K8s 原生能力与版本控制策略,实现从代码提交到应用部署的全流程可追溯、可回滚。
以下是具体实现方案,涵盖环境配置、流水线设计、版本控制与回滚机制。

一、环境准备

1. 核心工具与插件

  • Jenkins 插件
  • Kubernetes Plugin:用于与 K8s 集群交互。
  • Docker Plugin:构建与推送镜像。
  • Credentials Binding Plugin:管理 K8s 凭证(kubeconfig)。
  • Pipeline Utility Steps:处理 YAML/JSON 配置文件。
  • Git Plugin:拉取代码与版本控制。

2. 依赖工具

  • kubectl:K8s 命令行工具(需在 Jenkins 节点安装)。
  • helm:K8s 包管理工具(用于 Chart 部署)。
  • 容器仓库:Docker Hub/Harbor(存储应用镜像)。

3. K8s 集群凭证配置

Jenkins 需通过kubeconfig访问 K8s 集群,需安全存储凭证:

  • 进入 Jenkins → Manage Jenkins → Manage Credentials。
  • 选择全局凭证 → Add Credentials,类型选择「Secret file」:
  • File:上传目标 K8s 集群的kubeconfig文件。
  • ID:命名为kubeconfig-prod(或按集群标识命名,如kubeconfig-test)。
  • Description:描述集群用途(如 “生产环境 K8s 集群”)。

二、版本发布核心策略

1. 镜像版本规范

为确保版本可追溯镜像标签需包含唯一标识,推荐格式:
[仓库地址]/[应用名]:[Git Commit哈希]-[Jenkins构建号]
示例:

harbor.example.com/apps/user-service:7f3a9b2-123
  • Git Commit 哈希:关联代码提交,便于定位源码。
  • 构建号:Jenkins 流水线的唯一编号,确保同 Commit 多次构建可区分。

2. 配置版本管理

使用Helm Chart管理 K8s 资源配置,通过values.yaml区分环境差异:

  • 通用配置:charts/user-service/values.yaml(默认副本数、端口等)。
  • 环境配置:charts/user-service/values-prod.yaml(生产环境资源限制、域名等)。
  • 版本控制:Chart 与配置文件存入 Git 仓库,每次变更通过 Git Commit 记录。

三、Jenkins 流水线实现(Jenkinsfile)

流水线分为 构建→测试→镜像推送→部署→验证 5个阶段,支持多环境部署与版本控制。
Jenkins实现K8s版本发布与管理的流水线
Jenkinsfile如下:

pipeline { agent any environment { // 应用与镜像信息 APP_NAME = \"user-service\" REGISTRY = \"harbor.example.com/apps\" // 镜像标签:Git Commit短哈希 + 构建号(唯一且可追溯) IMAGE_TAG = \"${env.GIT_COMMIT.take(7)}-${env.BUILD_NUMBER}\" // Helm Chart目录与环境配置 CHART_DIR = \"charts/${APP_NAME}\" ENV = \"prod\" // 可通过参数化设置为test/dev/prod } parameters { // 部署参数:支持选择环境、手动输入版本(用于回滚或指定历史版本) choice(name: \'DEPLOY_ENV\', choices: [\'dev\', \'test\', \'prod\'], description: \'部署环境\') string(name: \'SPECIFY_IMAGE_TAG\', defaultValue: \'\', description: \'指定镜像版本(如空则使用当前构建版本)\') } stages { // 阶段1:拉取代码并构建 stage(\'Build\') { steps { script { checkout scm // 拉取Git代码 // 后端构建示例(Maven),前端可替换为npm/yarn sh \'mvn clean package -DskipTests\' } } } // 阶段2:单元测试与代码质量检查 stage(\'Test\') { steps { sh \'mvn test\' // 执行单元测试 // 可选:集成SonarQube代码质量检查 withSonarQubeEnv(\'SonarQube\') { sh \'mvn sonar:sonar\' } } post { always { junit \'target/surefire-reports/*.xml\' // 收集测试报告 } } } // 阶段3:构建并推送镜像 stage(\'Build & Push Image\') { when { // 若未指定历史版本,则构建新镜像 expression { return params.SPECIFY_IMAGE_TAG == \'\' } } steps { script { // 登录容器仓库 withCredentials([usernamePassword(credentialsId: \'registry-creds\', usernameVariable: \'USER\', passwordVariable: \'PWD\')]) { sh \"docker login ${REGISTRY} -u ${USER} -p ${PWD}\" } // 构建镜像 sh \"docker build -t ${REGISTRY}/${APP_NAME}:${IMAGE_TAG} .\" // 推送镜像(同时打latest标签便于引用) sh \"docker push ${REGISTRY}/${APP_NAME}:${IMAGE_TAG}\" sh \"docker tag ${REGISTRY}/${APP_NAME}:${IMAGE_TAG} ${REGISTRY}/${APP_NAME}:latest\" sh \"docker push ${REGISTRY}/${APP_NAME}:latest\" } } } // 阶段4:部署到K8s集群(使用Helm) stage(\'Deploy to K8s\') { steps { script { // 确定最终使用的镜像版本(优先用户指定,否则用当前构建版本) finalImageTag = params.SPECIFY_IMAGE_TAG ?: IMAGE_TAG  // 加载K8s集群凭证(kubeconfig) withCredentials([file(credentialsId: \"kubeconfig-${params.DEPLOY_ENV}\", variable: \'KUBECONFIG\')]) { // 配置kubectl与helm使用目标集群 sh \"export KUBECONFIG=${KUBECONFIG}\" // 检查Helm Release是否存在,存在则升级,否则安装 def releaseExists = sh script: \"helm list -n ${params.DEPLOY_ENV} | grep -q ${APP_NAME}-${params.DEPLOY_ENV}\", returnStatus: true if (releaseExists == 0) {  // 升级部署(使用环境专属values文件)  sh \"\"\" helm upgrade ${APP_NAME}-${params.DEPLOY_ENV} ${CHART_DIR} \\  --namespace ${params.DEPLOY_ENV} \\  --set image.repository=${REGISTRY}/${APP_NAME} \\  --set image.tag=${finalImageTag} \\  -f ${CHART_DIR}/values-${params.DEPLOY_ENV}.yaml  \"\"\" } else {  // 首次部署(创建命名空间)  sh \"\"\" helm install ${APP_NAME}-${params.DEPLOY_ENV} ${CHART_DIR} \\  --namespace ${params.DEPLOY_ENV} \\  --create-namespace \\  --set image.repository=${REGISTRY}/${APP_NAME} \\  --set image.tag=${finalImageTag} \\  -f ${CHART_DIR}/values-${params.DEPLOY_ENV}.yaml  \"\"\" } // 等待部署完成(超时5分钟) sh \"kubectl rollout status deployment/${APP_NAME}-${params.DEPLOY_ENV} -n ${params.DEPLOY_ENV} --timeout=5m\" } } } } // 阶段5:部署后验证与版本记录 stage(\'Verify & Record\') { steps { script { finalImageTag = params.SPECIFY_IMAGE_TAG ?: IMAGE_TAG  // 验证Pod状态 withCredentials([file(credentialsId: \"kubeconfig-${params.DEPLOY_ENV}\", variable: \'KUBECONFIG\')]) { sh \"\"\"  export KUBECONFIG=${KUBECONFIG}  # 检查所有Pod是否运行  if ! kubectl get pods -n ${params.DEPLOY_ENV} -l app=${APP_NAME} | grep -q \'Running\'; then echo \"部署后Pod状态异常,终止流程\" exit 1  fi  # 记录版本信息(存储到文件或数据库)  echo \"部署记录:环境=${params.DEPLOY_ENV},应用=${APP_NAME},版本=${finalImageTag},时间=$(date)\" >> deployment-history.log \"\"\" }  // 提交版本记录到Git(可选,用于集中追溯) sh \"\"\" git config --global user.name \"jenkins\" git config --global user.email \"jenkins@example.com\" git add deployment-history.log git commit -m \"Record deployment: ${APP_NAME} ${finalImageTag} to ${params.DEPLOY_ENV}\" git push origin main \"\"\" } } } } post { // 部署结果通知(邮件/Slack) success { emailext to: \'dev-team@example.com\', subject: \"[$APP_NAME] 部署成功到 ${params.DEPLOY_ENV}\", body: \"版本: ${finalImageTag}\\n构建链接: ${BUILD_URL}\" } failure { emailext to: \'dev-team@example.com\', subject: \"[$APP_NAME] 部署失败到 ${params.DEPLOY_ENV}\", body: \"版本: ${finalImageTag}\\n构建链接: ${BUILD_URL}\" } }}

四、版本管理与回滚机制

1. 版本追踪

  • 镜像版本:通过IMAGE_TAG(Git Commit + 构建号)唯一标识,与代码提交强关联。
  • 部署记录:通过deployment-history.log记录每次部署的环境、版本、时间,并存入 Git 仓库,实现集中追溯。
  • Jenkins 构建历史:每个构建对应唯一版本,可通过构建号快速定位部署记录。

2. 回滚操作

利用 K8s 和 Helm 的原生回滚能力,在 Jenkins 中通过参数化触发:

// 回滚专用阶段(可添加到流水线或单独创建回滚Job)stage(\'Rollback\') { when { parameter(name: \'NEED_ROLLBACK\', value: \'true\') // 通过参数控制是否回滚 } steps { withCredentials([file(credentialsId: \"kubeconfig-${params.DEPLOY_ENV}\", variable: \'KUBECONFIG\')]) { sh \"\"\" export KUBECONFIG=${KUBECONFIG} # 回滚到Helm历史版本(如版本2) helm rollback ${APP_NAME}-${params.DEPLOY_ENV} 2 -n ${params.DEPLOY_ENV} # 验证回滚结果 kubectl rollout status deployment/${APP_NAME}-${params.DEPLOY_ENV} -n ${params.DEPLOY_ENV} \"\"\" } }}
  • 回滚触发:通过 Jenkins 参数SPECIFY_IMAGE_TAG输入历史版本号,或直接调用helm rollback指定 Helm Release 版本。
  • 版本查询:通过helm history ${RELEASE_NAME} -n ${NAMESPACE}查看历史版本。

五、多环境与多集群扩展

1. 多环境部署通过流水线参数

DEPLOY_ENV(dev/test/prod)区分环境,结合不同values-xxx.yaml配置:

  • 开发环境(dev):副本数少、资源限制低,自动部署。
  • 生产环境(prod):副本数多、资源限制高,手动触发(通过input步骤确认)。

2. 多集群部署

如需部署到多个 K8s 集群,可扩展凭证与流水线逻辑:
1.为每个集群配置独立凭证(如kubeconfig-prod-1、kubeconfig-prod-2)。
2.在流水线中通过参数选择目标集群,循环部署:

stage(\'Deploy to Multi Clusters\') { steps { script { def clusters = [\'prod-1\', \'prod-2\'] // 目标集群列表 for (cluster in clusters) { withCredentials([file(credentialsId: \"kubeconfig-${cluster}\", variable: \'KUBECONFIG\')]) { sh \"export KUBECONFIG=${KUBECONFIG}\" sh \"helm upgrade ... # 部署命令,使用当前集群配置\" } } } }}

六、最佳实践

1.权限最小化:K8s 集群为 Jenkins 创建专用ServiceAccount,仅授予deployments、services等必要资源的操作权限。
2.镜像安全扫描:在Build & Push Image阶段集成 Trivy/Clair 扫描镜像漏洞,高风险漏洞阻断部署。
3.灰度发布:结合 K8s 的RollingUpdate策略(通过 Helm 配置maxSurge和maxUnavailable),实现平滑更新。
4.自动化测试:部署到测试环境后,自动执行 API 测试、负载测试,通过后才允许部署到生产。
5.备份与恢复:定期备份 Helm Release 配置和 K8s 资源清单,应对集群级故障。