Jenkins 构建部署多模块Java应用流水线参考——筑梦之路

流水线脚本

bash 复制代码
pipeline {
    // 指定代理,any 表示可以在任何可用的 Jenkins 节点上运行
    agent any

    environment {
        // ==================== 模块基本信息配置 ====================
        // 模块名称,通常对应微服务的服务名
        MODULE_NAME = "xxx-servcie"
        // 模块路径,适用于多模块项目(Multi-module),指向具体服务的目录
        MODULE_PATH = "./${MODULE_NAME}"
        
        // ==================== Git 仓库配置 ====================
        // Git 仓库地址,请替换为实际的代码仓库 URL
        GIT_URL = 'git@git.xxx.com:xxx.git'
        // Jenkins 中存储的 Git 凭证 ID (SSH Key 或 用户名密码)
        GIT_KEY_ACR_CRED = 'git-ssh-key'
        // 需要构建的分支名称
        BRANCH = 'master'
        
        // ==================== Docker 镜像仓库配置 ====================
        // Docker 镜像仓库地址,例如阿里云容器镜像服务 (ACR)
        DOCKER_IMAGE_REGISTRY = 'registry.xxx.aliyuncs.com'
        // Jenkins 中存储的 Docker 仓库登录凭证 ID
        DOCKER_IMAGE_ACR_CRED = 'docker-cred'
        // 镜像名称前缀,通常是命名空间或项目组名称
        IMAGE_PRE_NAME = 'xxxx'
        // 镜像名称,默认使用模块名称
        IMAGE_NAME = "${MODULE_NAME}"
        // 构建镜像所使用的 Dockerfile 文件路径
        DOCKERFILE = "${MODULE_PATH}/Dockerfile"
        
        // ==================== Kubernetes 部署配置 ====================
        // Jenkins 中存储的 KubeConfig 文件凭证 ID,用于连接 K8s 集群
        KUBERNETES_CONFIG = "kubernetes-config"
        // K8s 资源名称,此处对应 Deployment 的名称
        RESOURCE_NAME = "${MODULE_NAME}"
        // K8s Pod 中的容器名称,用于精确指定更新哪个容器的镜像
        CONTAINER_NAME = "${MODULE_NAME}"
    }

    tools {
        // 配置 Maven 工具,"Maven3" 必须在 Jenkins 全局工具配置中已定义
        maven "Maven3"
    }

    stages {

        // ==================== 阶段 1: 拉取代码 ====================
        stage('Checkout') {
            steps {
                // 使用 Git 插件拉取指定分支的代码
                git branch: BRANCH, 
                url: GIT_URL,
                credentialsId: GIT_KEY_ACR_CRED
            }
        }

        // ==================== 阶段 2: Maven 打包 ====================
        stage('Package') {
            steps {
                // 执行 Maven 打包命令
                // -pl ${MODULE_PATH}: 指定构建的模块
                // -am: 同时构建所依赖的模块
                // -B: 批处理模式,减少日志输出
                // clean package: 清理并打包
                // -Ppro: 使用 'pro' Profile 配置
                // -DskipTests=true: 跳过单元测试
                sh "mvn -pl ${MODULE_PATH} -am -B clean package -Ppro -Dfile.encoding=UTF-8 -DskipTests=true"
            }
        }

        // ==================== 阶段 3: 构建与推送 Docker 镜像 ====================
        stage('Build Docker Image') {
            steps {
                script {
                    // 生成基于当前时间的时间戳 (格式: yyyyMMddHHmm) 作为镜像 Tag
                    def timestamp = new Date().format('yyyyMMddHHmm', TimeZone.getTimeZone('Asia/Shanghai'))
                    def imageTag = "${IMAGE_NAME}:${timestamp}"
                    // 拼接完整的镜像地址: 仓库地址/前缀/镜像名:标签
                    def fullImageNameWithTimestamp = "${DOCKER_IMAGE_REGISTRY}/${IMAGE_PRE_NAME}/${imageTag}"

                    // 打印构建日志
                    echo "Building Docker image: ${fullImageNameWithTimestamp}"
                    // 执行 Docker 构建命令
                    // -t: 指定镜像名称和标签
                    // -f: 指定 Dockerfile 路径
                    // ${MODULE_PATH}: 构建上下文路径
                    sh "docker build -t ${fullImageNameWithTimestamp} -f ${DOCKERFILE} ${MODULE_PATH}"

                    // 使用 withCredentials 获取 Docker 仓库的登录凭证
                    withCredentials([usernamePassword(credentialsId: DOCKER_IMAGE_ACR_CRED, usernameVariable:'REG_USER', passwordVariable:'REG_PASS')]) {
                        // 登录到 Docker 镜像仓库
                        echo "Login Docker..."
                        sh "docker login --username $REG_USER -p $REG_PASS ${DOCKER_IMAGE_REGISTRY}"
                        
                        // 推送镜像到远程仓库
                        echo "Push Docker Image ${fullImageNameWithTimestamp}"
                        sh "docker push ${fullImageNameWithTimestamp}"
                        
                        // 推送完成后,删除本地构建的镜像以节省磁盘空间
                        echo "Remove Docker Imag ${fullImageNameWithTimestamp}"
                        sh "docker rmi ${fullImageNameWithTimestamp}"
                    }
                    
                    // 输出构建成功信息
                    echo "Successfully built and pushed image: ${fullImageNameWithTimestamp}"
                    
                    // 将构建好的完整镜像名称保存到环境变量,供后续部署阶段使用
                    env.BUILT_IMAGE = fullImageNameWithTimestamp
                }
            }
        }


        // ==================== 阶段 4: 部署到 Kubernetes ====================
        stage('Deploy to Remote Kubernetes') {
            steps {
                script {
                    // 使用 withCredentials 获取 KubeConfig 文件内容
                    withCredentials([file(credentialsId: KUBERNETES_CONFIG, variable:'KUBECONFIG')]) {
                        // 设置 KUBECONFIG 环境变量,使 kubectl 命令能找到配置文件
                        sh "export KUBECONFIG=$KUBECONFIG"
                        
                        // 更新 Kubernetes Deployment 中的镜像
                        // kubectl set image deployment/<Deployment名称> <容器名称>=<新镜像地址>
                        sh "kubectl set image deployment/${RESOURCE_NAME} ${CONTAINER_NAME}=${BUILT_IMAGE}"
                    } 
                }
            }
        }


    }
}

说明文档

bash 复制代码
# Jenkins Pipeline 文档

本文档详细说明了 Jenkins 流水线 (`Jenkinsfile`) 的配置、功能和使用方法。该流水线用于自动化构建、打包 Docker 镜像并部署到 Kubernetes 集群。

## 1. 概述

此流水线主要用于 Java 微服务项目的 CI/CD 流程,包含以下主要步骤:
1.  **代码拉取 (Checkout)**: 从 Git 仓库拉取指定分支的代码。
2.  **编译打包 (Package)**: 使用 Maven 编译并打包 Java 项目。
3.  **构建镜像 (Build Docker Image)**: 构建 Docker 镜像并推送到远程镜像仓库 (ACR)。
4.  **部署 (Deploy)**: 更新 Kubernetes 集群中的 Deployment 以使用新镜像。

## 2. 前置条件 (Prerequisites)

在运行此流水线之前,需要在 Jenkins 中配置以下凭证和工具:

### 2.1 Jenkins 凭证 (Credentials)

| 凭证 ID (Credentials ID) | 类型 | 描述 |
| :--- | :--- | :--- |
| `git-ssh-key` | SSH Username with private key | 用于拉取 Git 代码的 SSH 私钥。 |
| `docker-cred` | Username with password | 用于登录 Docker 镜像仓库 (如阿里云 ACR) 的用户名和密码。 |
| `kubernetes-config` | Secret file | Kubernetes 集群的 `kubeconfig` 配置文件,用于连接 K8s 集群。 |

### 2.2 全局工具配置 (Global Tool Configuration)

| 工具名称 | 类型 | 描述 |
| :--- | :--- | :--- |
| `Maven3` | Maven | 需要在 Jenkins 全局工具配置中添加名为 "Maven3" 的 Maven 安装。 |

### 2.3 环境变量 (Environment Variables)

流水线中使用 `environment` 块定义了全局变量,请根据实际项目修改:

| 变量名 | 默认值示例 | 说明 |
| :--- | :--- | :--- |
| `MODULE_NAME` | `"xxx-servcie"` | 服务模块名称,通常对应微服务名。 |
| `MODULE_PATH` | `"./${MODULE_NAME}"` | 模块所在路径,适用于多模块项目。 |
| `GIT_URL` | `'git@git.xxx.com:xxx.git'` | Git 仓库地址 (SSH)。 |
| `BRANCH` | `'master'` | 构建的目标分支。 |
| `DOCKER_IMAGE_REGISTRY` | `'registry.xxx.aliyuncs.com'` | Docker 镜像仓库地址。 |
| `IMAGE_PRE_NAME` | `'xxxx'` | 镜像命名前缀 (Namespace)。 |
| `RESOURCE_NAME` | `"${MODULE_NAME}"` | K8s Deployment 资源名称。 |
| `CONTAINER_NAME` | `"${MODULE_NAME}"` | K8s Pod 容器名称。 |

## 3. 流水线阶段详解 (Pipeline Stages)

### 3.1 Checkout (拉取代码)
- **功能**: 从配置的 Git 仓库拉取代码。
- **配置**: 使用 `GIT_URL`, `BRANCH`, `GIT_KEY_ACR_CRED`。

### 3.2 Package (Maven 打包)
- **功能**: 使用 Maven 对指定模块进行编译和打包。
- **命令**: `mvn -pl ${MODULE_PATH} -am -B clean package -Ppro -Dfile.encoding=UTF-8 -DskipTests=true`
    - `-pl`: 指定构建模块。
    - `-am`: 同时构建依赖模块。
    - `-Ppro`: 使用 `pro` 环境配置。
    - `-DskipTests=true`: 跳过单元测试。

### 3.3 Build Docker Image (构建与推送镜像)
- **功能**: 
    1.  生成时间戳标签 (e.g., `202310271030`)。
    2.  构建 Docker 镜像。
    3.  登录 Docker 仓库并推送镜像。
    4.  清理本地构建的镜像。
- **输出**: 将构建好的完整镜像地址保存到 `BUILT_IMAGE` 环境变量。

### 3.4 Deploy to Remote Kubernetes (部署到 K8s)
- **功能**: 更新 Kubernetes 集群中的应用镜像。
- **机制**: 
    1.  加载 `kubeconfig` 文件。
    2.  执行 `kubectl set image` 命令滚动更新 Deployment。

## 4. 常见问题排查 (Troubleshooting)

- **Maven 报错**: 检查 `Maven3` 是否配置正确,以及 `settings.xml` 是否包含必要的私服配置。
- **Docker 登录失败**: 检查 `docker-cred` 凭证是否正确,以及 Jenkins 节点是否有权访问镜像仓库。
- **Kubernetes 部署失败**: 
    - 检查 `kubernetes-config` 凭证内容是否有效。
    - 确认 Jenkins 节点安装了 `kubectl` 客户端。
    - 确认 `RESOURCE_NAME` 和 `CONTAINER_NAME` 与 K8s 集群中的实际资源名称匹配。

---
*文档生成日期: 2026-01-01*
相关推荐
shayudiandian2 小时前
【Java】常用类
java
雨中飘荡的记忆2 小时前
MyBatis类型处理模块详解
java·mybatis
金牌归来发现妻女流落街头2 小时前
【线程池 + Socket 服务器】
java·运维·服务器·多线程
wanghowie2 小时前
01.03 Spring核心|事务管理实战
java·后端·spring
大模型铲屎官2 小时前
【操作系统-Day 47】揭秘Linux文件系统基石:图解索引分配(inode)与多级索引
linux·运维·服务器·人工智能·python·操作系统·计算机组成原理
Chen不旧2 小时前
Java模拟死锁
java·开发语言·synchronized·reentrantlock·死锁
千寻技术帮2 小时前
10356_基于Springboot的老年人管理系统
java·spring boot·后端·vue·老年人
最贪吃的虎2 小时前
Redis 除了缓存,还能干什么?
java·数据库·redis·后端·缓存
崎岖Qiu2 小时前
【设计模式笔记24】:JDK源码分析-Comparator中的「策略模式」
java·笔记·设计模式·jdk·策略模式