Jenkins Pipeline 进阶:多平台账号关联与自动化部署
ahcoder 2025-06-08 18:49 1 浏览
引 言
在当今快速迭代的软件开发环境中,持续集成和持续交付 (CI/CD) 已成为不可或缺的实践。Jenkins 作为一款开源的自动化服务器,凭借其强大的插件生态系统和灵活的 Pipeline 功能,成为 CI/CD 领域的佼佼者。本文将介绍如何使用 Jenkins Pipeline 实现 CI/CD,并重点讲解如何将钉钉账号与 OpenLDAP 联动,以及如何实现 Jenkins、GitLab、Harbor 和禅道等多平台的账号关联和集成。
架构图
Jenkins Pipeline CI/CD
Jenkins Pipeline 是一种将构建、测试和部署等步骤以代码形式定义的机制。它使用 Groovy DSL 语法,可以将整个 CI/CD 流程编写成一个脚本文件,方便版本控制和重复使用。
部署
如果还没有部署Jenkins,可以使用下面的docker-compose.yml配置快速拉起一个Jenkins
docker-compose.yml
version: '3.7'
services:
jenkins:
image: jenkins/jenkins:lts
container_name: jenkins
environment:
- TZ=Asia/Shanghai
volumes:
- /data/jenkins/jenkins_home:/var/jenkins_home
- /var/run/docker.sock:/var/run/docker.sock
- /usr/bin/docker:/usr/bin/docker
ports:
- "8080:8080"
- "50000:500000"
expose:
- "8080"
- "50000"
privileged: true
user: root
restart: always
配置共享库
系统管理 ->系统配置-> Global Trusted Pipeline Libraries
Jenkins Pipeline CI
CI代码
下面是使用maven构建linux/win平台docker镜像的流程
@Library('jenkins-shared-library@main') _
// 引入 Jenkins 共享库,名称为 'jenkins-shared-library',使用 'main' 分支。
pipeline {
agent any
// 指定 Pipeline 在任何可用的 Jenkins Agent 上运行。
parameters {
string(name: 'BRANCH_NAME', defaultValue: 'master', description: 'Git分支名称')
// 定义一个字符串参数,用于指定 Git 分支名称,默认值为 'master'。
string(name: 'ZENTAO_REPOPATH', defaultValue: '', description: 'gitlab 项目链接')
// 定义一个字符串参数,用于指定 GitLab 项目的 URL。
string(name: 'ZENTAO_ACCOUNT', defaultValue: '', description: 'zentao 用户')
// 定义一个字符串参数,用于指定禅道(Zentao)的用户名。
choice(name: 'BUILD_PLATFORM', choices: ['linux', 'windows'], description: '构建平台')
// 定义一个选择参数,用于指定构建平台,可选值为 'linux' 或 'windows'。
}
environment {
CURRENT_DATE = sh(script: "date +'%Y%m%d%H%M%S'", returnStdout: true).trim()
// 定义一个环境变量 CURRENT_DATE,值为当前日期时间,格式为 'YYYYMMDDHHMMSS'。
BUILD_COMMIT = ''
// 定义一个环境变量 BUILD_COMMIT,初始值为空,后续会存储 Git 提交 ID。
ImageName = ''
// 定义一个环境变量 ImageName,初始值为空,后续会存储 Docker 镜像名称。
GITLAB_GROUP = ''
// 定义一个环境变量 GITLAB_GROUP,初始值为空,后续会存储 GitLab 项目组名称。
GITLAB_PROJECT = ''
// 定义一个环境变量 GITLAB_PROJECT,初始值为空,后续会存储 GitLab 项目名称。
}
stages {
stage("提取项目和项目名") {
steps {
script {
def res = getGitLabGroupAndProject.extractGitLabInfo(params.ZENTAO_REPOPATH)
// 调用共享库中的方法 extractGitLabInfo,从 GitLab 项目 URL 中提取项目组和项目名称。
GITLAB_GROUP = res.group
// 将提取到的 GitLab 项目组名称赋值给环境变量 GITLAB_GROUP。
GITLAB_PROJECT = res.project
// 将提取到的 GitLab 项目名称赋值给环境变量 GITLAB_PROJECT。
}
}
}
stage("构建邮件通知") {
steps {
script {
// 触发构建消息。
}
}
}
stage('拉取代码并构建') {
agent {
docker {
image "${GlobalVars.MavenBuildImage}"
// 使用共享库中定义的 Maven 构建镜像。
args '-v /data/.m2:/root/.m2 -v /data/jar-package:/data/jar-package'
// 挂载宿主机的 Maven 缓存目录和构建产物目录到容器中。
reuseNode true
// 重用当前节点,避免切换到其他节点。
}
}
steps {
checkout scmGit(
branches: [[name: "*/${params.BRANCH_NAME}"]],
// 指定要拉取的分支名称,使用参数 BRANCH_NAME。
extensions: [],
// 无额外的 Git 扩展配置。
userRemoteConfigs: [[
credentialsId: "${GlobalVars.GitLabcredentialsId}",
// 使用共享库中定义的 GitLab 凭据 ID。
url: "https://${GlobalVars.GitlabUrl}/${GITLAB_GROUP}/${GITLAB_PROJECT}.git"
// 指定 GitLab 项目的 URL。
]]
)
script {
sh 'mvn -B -DskipTests clean package'
// 使用 Maven 进行构建,跳过测试。
sh "cp ruoyi-admin/target/ruoyi-admin.jar /data/jar-package/${GITLAB_GROUP}-${GITLAB_PROJECT}-${CURRENT_DATE}.jar"
// 将构建产物(JAR 文件)复制到宿主机的指定目录,并重命名。
}
}
}
stage('保存构建产物') {
steps {
stash includes: 'ruoyi-admin/target/ruoyi-admin.jar', name: 'jar-package'
// 将构建产物(JAR 文件)保存为 Jenkins 的 stash,供后续阶段使用。
}
}
stage('构建信息') {
steps {
script {
wrap([$class: 'BuildUser']) {
// 使用 Jenkins 的 BuildUser 插件获取构建用户信息。
BUILD_USER = "${ZENTAO_ACCOUNT}"
// 将禅道用户赋值给环境变量 BUILD_USER。
BUILD_NAME = "${GITLAB_GROUP}/${GITLAB_PROJECT}"
// 将项目组和项目名称拼接后赋值给环境变量 BUILD_NAME。
BUILD_BRANCH = "${BRANCH_NAME}"
// 将分支名称赋值给环境变量 BUILD_BRANCH。
BUILD_COMMIT = "${getCommitId()}"
// 调用共享库中的方法 getCommitId,获取当前 Git 提交 ID,并赋值给环境变量 BUILD_COMMIT。
BUILD_PLATFORM = "${params.BUILD_PLATFORM}"
// 将构建平台赋值给环境变量 BUILD_PLATFORM。
}
currentBuild.description = """构建用户: ${BUILD_USER}\n构建项目: ${BUILD_NAME}\n构建分支: ${BUILD_BRANCH}\n构建平台: ${BUILD_PLATFORM}\nMessageID: ${BUILD_COMMIT}
"""
// 设置当前构建的描述信息,包含构建用户、项目、分支、平台和提交 ID。
}
}
}
stage('构建镜像名称') {
steps {
script {
ImageName = "${GlobalVars.HarborUrl}/${GITLAB_GROUP}/${GITLAB_PROJECT}:${CURRENT_DATE}-${BUILD_COMMIT}-${params.BUILD_PLATFORM}"
// 根据 Harbor 地址、项目组、项目名称、日期、提交 ID 和构建平台生成 Docker 镜像名称。
}
}
}
stage('打包镜像') {
steps {
script {
if (params.BUILD_PLATFORM == 'linux') {
buildDockerImage.LinuxRuoyiBuild(ImageName)
// 如果构建平台是 Linux,调用共享库中的方法 LinuxRuoyiBuild 打包 Docker 镜像。
} else if (params.BUILD_PLATFORM == 'windows') {
node('win-agent') {
unstash 'jar-package'
// 如果构建平台是 Windows,切换到 Windows 节点,并恢复之前保存的构建产物。
buildDockerImage.WindowsRuoyiBuild(ImageName)
// 调用共享库中的方法 WindowsRuoyiBuild 打包 Docker 镜像。
}
}
}
}
}
stage('推送镜像') {
steps {
script {
if (params.BUILD_PLATFORM == 'linux') {
withDockerRegistry(credentialsId: "${GlobalVars.HarborcredentialsId}", url: "https://${GlobalVars.HarborUrl}") {
sh "docker push ${ImageName}"
// 如果构建平台是 Linux,推送 Docker 镜像到 Harbor。
sh "docker rmi ${ImageName}"
// 删除本地 Docker 镜像以释放空间。
}
} else if (params.BUILD_PLATFORM == 'windows') {
node('win-agent') {
withDockerRegistry(credentialsId: "${GlobalVars.HarborcredentialsId}", url: "https://${GlobalVars.HarborUrl}") {
bat "docker push ${ImageName}"
// 如果构建平台是 Windows,推送 Docker 镜像到 Harbor。
bat "docker rmi ${ImageName}"
// 删除本地 Docker 镜像以释放空间。
}
}
}
}
}
}
}
post {
always {
cleanWs()
// 无论构建成功与否,始终清理工作空间。
}
success {
script {
// 构建成功时发送通知。
}
}
unsuccessful {
script {
// 构建失败时发送通知。
}
}
}
}
该 Jenkins Pipeline 脚本实现了一个完整的 CI 流程
- 参数化构建:支持动态指定 Git 分支、GitLab 项目、禅道用户和构建平台。
- 代码拉取与构建:从 GitLab 拉取代码并使用 Maven 进行构建。
- 镜像打包与推送:根据构建平台(Linux 或 Windows)打包 Docker 镜像并推送到 Harbor。
- 构建信息记录:记录构建用户、项目、分支、平台和提交 ID 等信息。
- 通知与清理:支持构建成功或失败时发送通知,并始终清理工作空间。
通过共享库的使用,脚本的逻辑更加简洁和模块化,便于维护和扩展。
创建构建流程
写好CI流程,下面在Jenkins添加构建流程
基于禅道关联Jenkins任务
禅道平台配置关联jenkins,方便用户调用触发
Jenkins Pipeline CD
CD 代码
@Library('jenkins-shared-library@main') _
// 引入 Jenkins 共享库,名称为 'jenkins-shared-library',使用 'main' 分支。
pipeline {
agent any
// 指定 Pipeline 在任何可用的 Jenkins Agent 上运行。
parameters {
string(name: 'SSH_USER', defaultValue: 'root', description: 'SSH User')
// 定义一个字符串参数,用于指定 SSH 用户,默认值为 'root'。
string(name: 'TARGET_IP', defaultValue: '', description: '部署机器 IP 地址')
// 定义一个字符串参数,用于指定目标机器的 IP 地址。
string(name: 'DOCKER_IMAGE', defaultValue: '', description: '运行服务镜像地址')
// 定义一个字符串参数,用于指定 Docker 镜像的名称。
string(name: 'IMAGE_VERSION', defaultValue: '', description: '运行服务镜像版本号')
// 定义一个字符串参数,用于指定 Docker 镜像的版本号。
string(name: 'SERVICE_NAME', defaultValue: '', description: '容器运行名称')
// 定义一个字符串参数,用于指定 Docker 容器的名称。
string(name: 'PORT_MAPPING', defaultValue: '', description: '端口映射,eg: 8080:8080')
// 定义一个字符串参数,用于指定 Docker 容器的端口映射。
string(name: 'ENV_VARIABLES', defaultValue: '', description: '环境变量,eg: KEY="VALUE",KEY2="VALUE2"')
// 定义一个字符串参数,用于指定 Docker 容器的环境变量。
}
environment {
SEND_BUILD_USER_EMAIL = ''
// 定义一个环境变量 SEND_BUILD_USER_EMAIL,初始值为空,后续会存储构建用户的邮箱。
}
stages {
stage('获取参数') {
steps {
script {
withBuildUser {
SEND_BUILD_USER_EMAIL = env.BUILD_USER_EMAIL
// 使用 Jenkins 的 BuildUser 插件获取构建用户的邮箱,并赋值给环境变量 SEND_BUILD_USER_EMAIL。
}
// 检查参数是否为空
if (!params.SSH_USER?.trim()) {
error "SSH 用户不能为空!"
// 如果 SSH 用户为空,抛出错误并终止 Pipeline。
}
if (!params.TARGET_IP?.trim()) {
error "目标机器 IP 地址不能为空!"
// 如果目标机器 IP 地址为空,抛出错误并终止 Pipeline。
}
if (!params.SERVICE_NAME?.trim()) {
error "服务名称不能为空!"
// 如果服务名称为空,抛出错误并终止 Pipeline。
}
if (!params.DOCKER_IMAGE?.trim()) {
error "Docker 镜像名称不能为空!"
// 如果 Docker 镜像名称为空,抛出错误并终止 Pipeline。
}
if (!params.IMAGE_VERSION?.trim()) {
error "Docker 镜像版本号不能为空!"
// 如果 Docker 镜像版本号为空,抛出错误并终止 Pipeline。
}
if (!params.PORT_MAPPING?.trim()) {
error "端口映射不能为空!"
// 如果端口映射为空,抛出错误并终止 Pipeline。
}
}
}
}
stage('部署服务') {
steps {
script {
def envVariables = ""
if (params.ENV_VARIABLES?.trim()) {
def envList = params.ENV_VARIABLES.split(',')
envVariables = envList.collect { envVar ->
"-e ${envVar.trim()}"
}.join(' ')
// 如果环境变量参数不为空,将其拆分为多个环境变量,并格式化为 Docker 命令中的 `-e` 参数。
}
def dockerCommand = ""
withCredentials([usernamePassword(credentialsId: 'devops_harbor', passwordVariable: 'HARBOR_PASSWORD', usernameVariable: 'HARBOR_USERNAME')]) {
// 使用 Jenkins 的 Credentials 插件获取 Harbor 仓库的用户名和密码。
dockerCommand = """
docker login harbor.wuyinit.com -u $HARBOR_USERNAME -p $HARBOR_PASSWORD &&
docker pull ${params.DOCKER_IMAGE}:${params.IMAGE_VERSION} &&
docker stop ${params.SERVICE_NAME} || true &&
docker rm ${params.SERVICE_NAME} || true &&
docker run -itd --name ${params.SERVICE_NAME} -p ${params.PORT_MAPPING} ${envVariables} ${params.DOCKER_IMAGE}:${params.IMAGE_VERSION}
"""
// 构建 Docker 命令,包括:
// 1. 登录 Harbor 仓库。
// 2. 拉取指定版本的 Docker 镜像。
// 3. 停止并删除已存在的同名容器。
// 4. 启动新的容器,并指定名称、端口映射和环境变量。
}
sshagent(['deploy-agent-key']) {
// 使用 Jenkins 的 SSH Agent 插件,加载指定的 SSH 私钥('deploy-agent-key')。
sh """
ssh -o StrictHostKeyChecking=no ${params.SSH_USER}@${params.TARGET_IP} << 'EOF'
${dockerCommand}
EOF
"""
// 通过 SSH 连接到目标机器,并执行 Docker 命令。
}
}
}
}
}
post {
success {
script {
// 构建成功时发送邮件通知。
}
}
unsuccessful {
script {
// 构建失败时发送邮件通知。
}
}
}
}
该 Jenkins Pipeline 脚本实现了一个完整的服务部署流程,包括:
- 参数化构建:支持动态指定 SSH 用户、目标机器 IP、Docker 镜像、版本号、服务名称、端口映射和环境变量。
- 参数检查:确保所有必填参数不为空。
- 服务部署:
- 登录 Harbor 仓库并拉取 Docker 镜像。
- 停止并删除已存在的同名容器。
- 启动新的容器,并指定名称、端口映射和环境变量。
- 通知与清理:支持构建成功或失败时发送通知。
通过共享库和 Jenkins 插件(如 Credentials、SSH Agent)的使用,脚本的逻辑更加简洁和模块化,便于维护和扩展。
钉钉与OpenLDAP的联动
为了实现统一身份认证,并基于现有的钉钉组织和人员信息,将Jenkins、GitLab、Harbor 和禅道等多平台的账号关联,我们可以使用 OpenLDAP 作为统一的用户认证中心。具体步骤如下:
1.配置 Go-Ldap-Admin 等服务:将钉钉通讯录中的用户和组织结构同步到 OpenLDAP 服务器。
2.配置各平台使用 OpenLDAP 认证: 在 Jenkins、GitLab、Harbor 和禅道的系统设置中,配置 LDAP 认证,并指定 OpenLDAP 服务器的地址、端口、Base DN 等信息。
docker-compose参考,详情查看
version: '3'
networks:
go-ldap-admin:
driver: bridge
services:
go-ldap-admin:
image: registry.cn-hangzhou.aliyuncs.com/eryajf/go-ldap-admin
container_name: go-ldap-admin
hostname: go-ldap-admin
restart: always
environment:
WAIT_HOSTS: openldap:389
configs:
- source: go_ldap_admin_config
target: /app/config.yml
ports:
- 8888:8888
volumes:
- ./data/go-ldap-admin:/app/data
depends_on:
- openldap
links:
- openldap:go-ldap-admin-openldap
networks:
- go-ldap-admin
openldap:
image: registry.cn-hangzhou.aliyuncs.com/eryajf/openldap:1.4.1
container_name: go-ldap-admin-openldap
hostname: go-ldap-admin-openldap
restart: always
environment:
TZ: Asia/Shanghai
LDAP_ORGANISATION: "eryajf.net"
LDAP_DOMAIN: "eryajf.net"
LDAP_ADMIN_PASSWORD: "123456"
command: [ '--copy-service' ]
volumes:
- ./data/openldap/database:/var/lib/ldap
- ./data/openldap/config:/etc/ldap/slapd.d
ports:
- 389:389
networks:
- go-ldap-admin
总 结
通过 Jenkins Pipeline、OpenLDAP 和钉钉的集成,我们可以实现高效的 CI/CD 流程,并统一管理多平台的用户账号。本文提供的方案只是一个简单的示例,实际应用中可以根据具体需求进行调整和扩展。
未来展望
未来,我们可以探索以下方向:
- 使用 Kubernetes 进行容器化部署,进一步提高资源利用率和部署效率。
- 引入代码质量分析工具,例如 SonarQube,提升代码质量。
- 实现自动化测试,例如使用 Selenium 进行 UI 自动化测试。
如有相关问题,请在文章后面给小编留言,小编安排作者第一时间和您联系,为您答疑解惑。
参考文献
- Jenkins 官方文档: https://www.jenkins.io/doc/
- OpenLDAP 官方文档:https://www.openldap.org/doc/
- 钉钉开发者文档:https://open.dingtalk.com/document/orgapp-server
- Go-Ldap-Admin: https://ldapdoc.eryajf.net/
相关推荐
- Linux 常用命令之 - ls 命令(linux命令ls -lh)
-
命令介绍英文原意:listdirectorycontents功能描述:用来显示指定目录内的文件列表,可通过选项控制显示内容的详细程度和颜色高亮等命令格式所在路径:/bin/ls(RedHat7之...
- 超级好玩的Linux命令之跑火车sl命令
-
之前《超级好玩的Linux命令之cowsay与xcowsay》有跟大家讲解了cowsay命令,这里再讲解一下sl命令的好玩之处。看到sl,有人一定会认为打错了,应该是ls。其实不然,sl命令也是存在的...
- Linux无法通过上翻获取history解决办法
-
1、首先通过set-o查看本机系统的shell定制情况,是否开启了history,如已经开启,转至步骤22、查看/etc/profile的配置,查看HISTSIZE字段的值可以直接使用命令:cat...
- Linux ip命令用法(linux ip 命令)
-
ip命令是一个用于配置和管理网络接口的命令行工具,它在Linux系统中非常常见。通过ip命令,可以实现IP地址配置、路由表配置、网络性能监测、IP隧道配置等功能,它提供许多参数和选项,可以实现各种不同...
- 推荐20个常用的Linux Vim快捷键及详细说明
-
:w功能:保存当前文件。示例:编辑后输入:w并回车,文件即被保存。:q功能:退出Vim。示例:输入:q退出(若文件未保存会提示需强制退出)。:wq或:x功能:保存并退出。示例:输入:wq...
- Ubuntu 22.04 Tesla V100s显卡驱动,CUDA,cuDNN,MiniCONDA3 环境的安装
-
今天来将由《蓝创精英团队》带来一个Ubuntu显卡环境的安装,主要是想记录下来,方便以后快捷使用。主要的基础环境1.显卡驱动(nvidia-smi)2.CUDA(nvidia-smi可查看...
- 一文读懂Linux操作系统的架构和原理
-
Linux操作系统介绍:Linux操作系统是一个自由和开放源代码的操作系统,由内核、文件系统、应用程序框架和用户空间组成。它可以在多种计算机硬件上运行,包括个人电脑、服务器、嵌入式设备等。Linux操...
- linux基础命令之ls命令(ls -l命令linux)
-
ls命令主要用于查看目录下的文件和文件属性。语法格式:ls参数文件名;参数和文件名可为空,则查看当前目录下的文件操作1:单独执行ls命令,则显示当前目录下的文件(不包含隐藏文件)操作2:ls-l...
- Mongodb在Linux上安装教程(mongodb linux安装)
-
正文开始:系统环境:linuxcentos7mongodb版本:4.4.0一、下载为了保证各处版本一致性及便捷性,使用官网下载安装包安装官网传送门:https://www.mongodb.com/t...
- DevOps—Linux命令行进阶(linux dev/zero)
-
作为DevOps工程师,我每天都使用Linux。在本文中,我想介绍一些我日常使用的Linux命令,帮助我更高效地工作或排除故障。xargsxargs看似非常简单,之前使用方式都是肌肉记忆,后...
- 15 个实用 Linux 命令(linux常用命令 知乎)
-
Linux命令行是系统管理员、开发者和技术爱好者的强大工具。掌握实用命令不仅能提高效率,还能解锁Linux系统的无限潜力,本文将深入介绍15个实用Linux命令。ls-列出目录内容l...
- Linux lscpu命令用法(linux lspci命令)
-
lscpu命令是用来显示CPU(CentralProcessingUnit)架构相关信息的命令。lscpu命令的用法如下:1.命令格式:lscpu[选项]2.命令选项:-`-a`显示所有...
- linux之ls详解及常用选项组合(linux ls -s)
-
===ls--help====用法:ls[选项]...[文件]...列出<文件>的信息(默认为目前的目录)。如果不指定-cftuSUX或--sort任何一个选项,则根...
- Linux strace、pstack 命令 使用详解
-
strace简介按照strace官网的描述,strace是一个可用于诊断、调试和教学的Linux用户空间跟踪器。我们用它来监控用户空间进程和内核的交互,比如系统调用、信号传递、进程状态变更等...
- linux常见面试题及参考答案(linux常见面试题及参考答案及解析)
-
1.Linux下常用的DNS服务软件是什么,举出集中常用的DNS记录,如果域名是abc.com配置好了一台邮件服务器,IP地址为202.10.0.20,该如何做解析。是否了解bind的智能解析,如...
- 一周热门
- 最近发表
-
- Linux 常用命令之 - ls 命令(linux命令ls -lh)
- 超级好玩的Linux命令之跑火车sl命令
- Linux无法通过上翻获取history解决办法
- Linux ip命令用法(linux ip 命令)
- 推荐20个常用的Linux Vim快捷键及详细说明
- Ubuntu 22.04 Tesla V100s显卡驱动,CUDA,cuDNN,MiniCONDA3 环境的安装
- 一文读懂Linux操作系统的架构和原理
- linux基础命令之ls命令(ls -l命令linux)
- Mongodb在Linux上安装教程(mongodb linux安装)
- DevOps—Linux命令行进阶(linux dev/zero)
- 标签列表
-
- linux 远程 (37)
- u盘 linux (32)
- linux 登录 (34)
- linux 路径 (33)
- linux 文件命令 (35)
- linux 是什么 (35)
- linux 界面 (34)
- 查看文件 linux (35)
- linux 语言 (33)
- linux代码 (32)
- linux 查看命令 (33)
- 关闭linux (34)
- root linux (33)
- 删除文件 linux (35)
- linux 主机 (34)
- linux与 (33)
- linux 函数 (35)
- linux .ssh (35)
- cpu linux (35)
- 查看linux 系统 (32)
- linux 防火墙 (33)
- linux 手机 (32)
- linux 镜像 (34)
- linux ip地址 (34)
- linux 用户查看 (33)