主页 > 手机  > 

Jenkins部署、使用与原理分析

Jenkins部署、使用与原理分析

文章目录 前言1、概述2、系统架构2.1、主节点2.2、代理节点2.3、插件系统2.4、存储与日志系统2.5、用户界面与API2.6、通信协议 3、功能模块3.1、主节点模块3.1.1、用户管理3.1.2、系统配置3.1.3、任务调度3.1.4、数据存储 3.2、代理节点模块3.2.1、构建执行3.2.2、通信模块 3.3、插件系统模块3.3.1、源码管理插件3.3.2、构建工具插件3.3.3、流水线插件3.3.4、测试工具插件3.3.5、通知与报告插件3.3.6、部署工具插件 3.4、存储与日志系统模块3.4.1、存储系统3.4.2、日志管理 3.5、用户界面与API模块3.5.1、Web界面3.5.2、REST API3.5.3、CLI工具 4、业务流程4.1、安装Jenkins4.1.1、安装JDK4.1.2、安装Maven4.1.3、安装Git4.1.4、安装Jenkins4.1.5、启动Jenkins 4.2、 基本配置4.2.1、安装插件4.2.2、工具设置 4.3、测试用例4.3.1、定时拉取并部署项目4.3.1.1、下载安装Tomcat4.3.1.2、安装相关插件4.3.1.3、构建测试项目4.3.1.3.1、创建新项目4.3.1.3.2、设置构建目标4.3.1.3.3、设置定时触发器 4.3.1.4、查看构建结果 4.3.2、预处理操作4.3.3、自动发送邮件 5、原理分析5.1、Web框架5.1.1、Stapler简介5.1.2、Stapler的主要组件5.1.3、Stapler与Jenkins的集成5.1.4、根据请求定位后端代码 5.2、高级视图5.2.1、数据流架构5.2.2、架构组成 5.3、可扩展性5.3.1、基本概念5.3.2、具体实现 5.4、安全性5.4.1、安全架构5.4.2、插件的安全性5.4.3、检查Jelly文件的权限5.4.4、认证方式5.4.5、认证流程 5.5、流水线5.5.1、流水线概述5.5.2、流水线语法5.5.2.1、流水线语法概述5.5.2.2、声明式流水线5.5.2.3、脚本化流水线 5.5.3、流水线功能扩展5.5.3.1、分支和Pull Request支持5.5.3.2、Docker集成5.5.3.3、共享库 5.5.4、流水线开发工具5.5.5、流水线示例 5.6、单/多节点架构5.6.1、单节点架构5.6.2、多节点架构 6、参考文献总结


前言

  本博客的主要内容为Jenkins的部署、使用与原理分析。本博文内容较长,因为涵盖了Jenkins的几乎全部内容,从部署的详细过程到如何使用Jenkins进行持续集成(Continuous Integration,CI)和持续交付/部署(Continuous Delivery/Deployment,CD),并对Jenkins的原理进行了详细分析,相信认真读完本博文,各位读者一定会对Jenkins有更深的了解。以下就是本篇博客的全部内容了。


1、概述

  Jenkins是一个功能强大的开源自动化服务器,广泛应用于软件开发中的持续集成(Continuous Integration,CI)和持续交付/部署(Continuous Delivery/Deployment,CD)。它通过自动化构建、测试、发布流程,帮助团队加速软件开发生命周期,提升软件质量和交付效率。

核心特点 跨平台支持 Jenkins基于Java开发,支持运行在多种操作系统上,包括Windows、Linux和macOS,适合不同开发环境。丰富的插件生态系统 Jenkins的强大之处在于其插件生态系统,目前拥有1800多种插件,支持与常见工具和平台的集成,例如: 版本控制系统:Git、SVN、Mercurial等。构建工具:Maven、Gradle、Ant等。容器化:Docker、Kubernetes。通知系统:Slack、Email、Webhooks。测试框架:JUnit、Selenium等。 分布式构建 Jenkins支持分布式构建,可以将任务分配给多个节点(代理服务器)执行,提升构建效率,适合大规模项目。灵活的任务触发 支持多种任务触发方式,包括代码提交、定时调度、手动触发等。可根据具体需求自定义触发条件。 直观的Web界面 Jenkins提供用户友好的Web界面,便于配置任务、查看构建状态、分析日志和生成报告。支持多语言开发 Jenkins可以构建和测试多种编程语言(如Java、Python、C/C++、Go等)的项目,适合跨语言开发团队。 适用场景 持续集成(CI) 通过监控代码仓库中的变更(如Git提交),自动触发构建和测试,及时发现代码缺陷,确保代码的稳定性。持续交付/部署(CD) 自动将经过测试的代码部署到开发、测试或生产环境,缩短软件交付周期。分布式开发与构建 在多个代理节点上并行执行任务,加速复杂项目的构建和测试。DevOps流程支持 与DevOps工具链无缝集成,实现从代码提交到部署上线的自动化工作流。 优势 开源免费:任何人都可以免费使用,企业也能定制开发以满足特定需求。可扩展性强:通过插件扩展功能,满足多种使用场景。社区支持:Jenkins社区活跃,拥有大量教程、文档和技术支持资源。分布式支持:可以处理大型、复杂的多项目构建。支持敏捷开发:帮助开发团队快速响应需求变化。 缺点 学习曲线陡峭:初学者需要一定时间熟悉其配置和插件管理。维护成本高:复杂项目中需要手动调整任务和插件配置,可能导致管理成本上升。插件依赖问题:部分插件可能存在兼容性问题,需要及时更新或更换。界面现代化不足:相比一些现代CI/CD工具,Jenkins的用户界面显得稍显陈旧。 历史与背景 Jenkins的前身是Hudson,最初由Sun Microsystems于2004年推出。2010年,由于商标问题,Hudson社区的开发者决定分支项目并重命名为Jenkins。自那以后,Jenkins一直保持活跃开发,成为CI/CD领域的领导者。总结 Jenkins是CI/CD工具的经典之作,以其稳定性、功能丰富性和灵活性在软件开发中占据重要地位。对于需要高度自动化和定制化的开发团队,Jenkins是一个非常值得信赖的选择。 2、系统架构

  Jenkins的系统架构设计灵活且高度可扩展,支持分布式构建和大规模自动化任务管理。它的架构分为核心组件和功能模块,各部分协同工作,共同实现持续集成和持续交付。以下是Jenkins的系统架构详细介绍:

2.1、主节点

  主节点是Jenkins的核心组件,负责管理系统的整体运行,是协调任务执行和系统配置的关键角色。主要功能包括:

用户界面 提供Web界面,供用户配置、管理和监控任务。任务调度 负责将构建任务分发到合适的代理节点上执行。系统管理 处理插件安装、用户权限管理和全局配置。存储管理 保存任务的配置文件、构建结果以及系统运行日志。插件加载 管理Jenkins系统中的插件加载与卸载,支持功能的动态扩展。 2.2、代理节点

  代理节点是Jenkins的任务执行单元,主节点通过分布式管理将具体的构建任务分发到代理节点,从而提高系统的执行效率。

特点 分布式架构 代理节点可以运行在不同操作系统(如Windows、Linux或macOS)上,提供多样化支持。隔离性 每个代理节点可以配置独立的环境(例如JDK、Docker容器),适应不同任务需求。通信协议 主节点通过JNLP(Java Network Launch Protocol)、SSH或WebSocket与代理节点通信。 优势 提升系统的并行处理能力 通过多个代理节点并行执行任务,加速整体任务执行效率。减轻主节点的计算压力 代理节点负责实际的构建任务,主节点仅负责管理和调度。支持多种开发环境和构建工具 提供对不同开发语言、框架和工具的兼容性。 2.3、插件系统

  插件系统是Jenkins的核心组成部分,支持几乎无限的功能扩展和系统集成。

功能扩展 通过插件支持版本控制系统(如Git、SVN)、构建工具(如Maven、Gradle)、通知服务(如Email、Slack)。集成能力 支持与其他工具(如Docker、Kubernetes、JIRA)无缝集成,扩展系统能力。插件管理 提供插件管理器,支持在线安装、更新和删除插件操作。安全插件 提供权限管理和安全防护功能,增强系统安全性。 2.4、存储与日志系统

  存储与日志系统是Jenkins用于持久化数据和记录系统运行情况的关键模块。

存储功能 构建历史 保存每次任务的构建状态、执行日志以及生成的工件(Artifacts)。系统配置 记录任务配置文件、用户权限设置和插件配置。支持外部存储 支持集成外部存储服务(如S3、NFS),扩展数据存储能力。 日志管理 构建日志 记录每次任务的执行细节,便于问题诊断和性能分析。系统日志 记录Jenkins核心事件和系统错误信息。日志轮转 支持日志轮转,防止日志文件过度增长占用磁盘空间。 2.5、用户界面与API

  用户界面与 API模块提供了丰富的交互功能和编程接口,是 Jenkins 用户体验和自动化管理的核心所在。

用户界面 Web界面 提供任务管理、构建状态监控和日志查看的可视化界面。扩展功能 支持与Blue Ocean插件结合,提供现代化的流水线视图。 API支持 REST API 提供通过HTTP请求进行任务触发、状态查询和数据获取的能力。CLI工具 提供命令行操作方式,支持脚本化任务管理和快速批量操作。 2.6、通信协议

  通信协议模块负责主节点与代理节点之间的通讯,为任务分发和数据同步提供底层支持。

协议类型 JNLP(Java Network Launch Protocol) 用于代理节点与主节点的通信,适合动态分配代理节点的场景。SSH 通过安全通道连接代理节点,适合静态代理的稳定通信。WebSocket 通过插件支持的现代通信方式,适合云端部署和高效传输需求。

  总之,Jenkins的系统架构设计灵活、模块化,支持主节点管理和代理节点执行的分布式模式。通过插件系统扩展功能、支持多种通信协议和存储方式,Jenkins能够满足大规模、复杂项目的持续集成和持续交付需求。

3、功能模块

  Jenkins的功能模块与其系统架构紧密关联,每个模块都为持续集成(CI)和持续交付/部署(CD)提供必要支持。以下是Jenkins的功能模块详细介绍。

3.1、主节点模块

  主节点是Jenkins的核心,负责系统配置、用户管理、任务调度和数据存储等功能模块,确保整个系统的稳定运行。

3.1.1、用户管理

  用户管理是Jenkins的核心基础,提供多角色支持、权限分配和认证机制,确保不同类型用户能够安全、高效地使用系统资源。

用户角色 支持管理员、开发者和访客等不同角色,能够针对不同用户类别灵活分配权限,满足团队协作需求。权限控制 通过插件(如Role Strategy Plugin)实现精细化权限管理,允许基于用户或用户组设置权限,覆盖任务创建、构建触发、查看日志等操作。认证方式 内置用户数据库:默认自带用户注册与管理功能,便于快速上手。外部认证系统集成:支持连接LDAP、Active Directory等外部系统,实现企业级用户管理。单点登录与第三方认证:支持通过SSO或OAuth插件进行认证,便于用户跨多个平台无缝登录。 3.1.2、系统配置

  系统配置为Jenkins提供基础功能设置,包括全局参数配置、插件管理和安全设置,确保系统能够高效且安全地运行。

全局配置 提供设置系统范围内参数的能力,例如邮件通知服务器、JDK路径、构建工具版本等,确保任务执行环境统一。插件管理 提供便捷的插件管理界面,支持从在线市场直接安装插件,也支持离线安装。用户可以查看已安装插件的版本,更新插件至最新版本,或移除不再需要的插件。 安全配置 提供HTTPS支持,确保Web界面和API访问安全。包括CSRF防护机制和API Token验证功能,保护系统免受恶意攻击。 3.1.3、任务调度

  任务调度负责任务的分配与触发,是Jenkins主节点协调代理节点的重要组成。

任务分发 任务分发基于标签系统,自动选择最适合的代理节点执行任务。支持动态资源分配,例如动态启动Docker容器作为代理节点,优化资源使用效率。 任务队列管理 提供任务队列监控功能,用户可以随时查看待执行任务的状态。支持任务优先级插件,允许用户调整任务执行顺序。 触发方式 定时触发:支持使用Cron表达式设置任务的自动触发时间。代码提交触发:通过Webhooks实现代码提交后自动构建。手动触发:通过界面或REST API触发构建任务。 3.1.4、数据存储

  数据存储用于保存任务构建数据和历史记录,为用户提供全面的任务执行数据参考。

构建数据 每次构建任务的配置、日志和结果都会保存,便于任务回溯和问题排查。支持对构建工件(如编译产物)的归档与下载。历史记录 提供任务的执行历史状态和变更日志,支持任务执行的趋势图和统计分析。用户可以通过图表查看任务的成功率、失败率及变更趋势。 3.2、代理节点模块

  代理节点模块负责具体的任务执行,支持分布式构建和多环境运行,确保任务的高效执行与资源的充分利用。

3.2.1、构建执行

  构建执行是代理节点的核心任务,支持多语言、多平台构建环境和动态资源分配。

任务执行 兼容多语言构建,包括Java、Python、C++等。无缝集成常见构建工具(如Maven、Gradle、Ant)。 环境支持 运行在不同系统平台上,包括Windows、Linux 和macOS。提供Docker容器化构建环境,实现任务隔离。 资源管理 动态分配计算资源,根据任务需求调整分配。支持并发任务处理,提高任务执行效率。 3.2.2、通信模块

  通信模块保证主节点与代理节点间的实时信息交互和任务协调。

协议支持 支持JNLP、SSH和WebSocket等协议,确保灵活可靠的通信。支持防火墙后代理节点的反向连接。 状态报告 实时反馈代理节点任务执行状态,包括任务开始、执行进度和完成状态。提供代理节点运行日志,便于调试和维护。 3.3、插件系统模块

  Jenkins的插件系统是其功能扩展的核心,通过多种插件,满足用户在源码管理、构建、测试、部署等各环节的个性化需求。

3.3.1、源码管理插件

  源码管理插件帮助Jenkins集成主流版本控制系统,支持任务的自动化触发和变更记录获取。

版本控制支持 集成多种版本控制工具,包括Git、SVN和Mercurial,满足不同开发团队的需求。触发机制 集成Webhooks功能,在代码提交后自动触发构建任务。支持针对特定分支、标签或变更记录设置触发条件。 功能扩展 提供代码分支选择、变更记录检索、子模块支持等功能,便于精确构建和版本追踪。 3.3.2、构建工具插件

  构建工具插件为任务的构建流程提供全面支持,集成了多种主流的构建工具和依赖环境管理。

构建工具支持 Java项目:Maven、Gradle、Ant。C/C++项目:CMake、Make。前端项目:NPM、Yarn。 自动化依赖配置 自动检测构建工具的环境配置,并支持动态安装和依赖管理。 3.3.3、流水线插件

  流水线插件用于定义和管理任务的自动化流程,从代码检出到部署全程覆盖。

Pipeline Plugin 提供脚本化定义构建流程的能力,用户可通过Groovy编写完整的流水线脚本。Blue Ocean Plugin 提供直观的可视化编辑界面,简化复杂流水线的配置和监控。Declarative Pipelin 用更简单的语法定义流水线,适合标准化的构建流程。 3.3.4、测试工具插件

  测试工具插件提供测试框架集成和测试报告分析功能,帮助用户提升软件质量。

集成测试框架 单元测试:JUnit、TestNG等。自动化UI测试:Selenium。 测试报告与分析 自动生成测试报告,支持趋势分析,帮助用户快速定位测试失败原因。 3.3.5、通知与报告插件

  通知与报告插件确保用户能够及时获取任务执行状态和构建结果。

通知方式 支持多渠道通知,包括邮件、Slack、Microsoft Teams等。提供Webhooks,用于与其他系统集成。 报告功能 自动生成构建状态报告,支持导出为HTML、XML等格式,便于归档和共享。 3.3.6、部署工具插件

  部署工具插件支持自动化部署和持续交付,集成主流云服务和容器管理平台。

云服务集成 支持AWS、Google Cloud、Azure等云平台,便于实现基于云的自动化部署。容器化部署 集成Docker和Kubernetes,提供镜像管理和容器编排功能。 3.4、存储与日志系统模块

  存储与日志模块是Jenkins数据持久化和问题调试的核心组件,为任务执行提供全面的记录支持。

3.4.1、存储系统

  存储系统负责保存Jenkins的任务配置信息和构建生成的工件,为持续集成和部署提供数据基础。

构建工件存储 默认存储于主节点的本地文件系统中。支持与外部存储服务(如NFS、Amazon S3)集成,满足大规模数据存储需求。 任务配置存储 每个任务的配置以XML文件保存,便于系统备份和迁移。 3.4.2、日志管理

  日志管理模块提供任务执行和系统运行的详细记录,便于调试和安全性审计。

构建日志 记录每次任务执行的详细过程,便于问题排查和性能分析。支持实时查看和日志文件导出。 系统日志 记录Jenkins核心事件、插件事件和系统错误。提供日志轮转功能,防止日志文件无限增长占用磁盘空间。 审计日志 记录用户操作和权限变更,帮助提升系统的安全性和可追溯性。 3.5、用户界面与API模块

  用户界面与API模块提供交互式操作界面和自动化管理接口,是Jenkins易用性和集成能力的关键部分。

3.5.1、Web界面

  Web界面是Jenkins的主要交互方式,通过直观的可视化界面,用户可以轻松管理任务和监控系统状态。

仪表盘 展示任务列表、状态摘要和构建执行历史,便于用户总览系统状态。任务详情页 提供任务配置、执行日志和工件下载入口,支持查看和分析任务执行过程。流水线视图 显示任务流程图和执行状态,帮助用户直观了解任务流转情况。管理界面 提供系统配置、用户管理、插件管理等功能入口,简化系统维护操作。 3.5.2、REST API

  REST API提供编程接口,支持系统的自动化管理和与外部工具的集成。

功能支持 提供任务触发、状态查询、数据获取等接口,支持JSON或XML格式的返回数据。用途 实现与外部系统的集成,例如自定义仪表盘和构建监控工具。自动化执行Jenkins操作,提升管理效率。 3.5.3、CLI工具

  CLI工具是Jenkins提供的一种命令行操作方式,适用于脚本化和自动化管理场景。

命令行支持 提供命令行工具,支持批量执行任务、查看状态等操作,适合脚本化管理和快速操作。

  总之,Jenkins的功能模块设计覆盖了持续集成与交付的全流程,结合主节点的核心管理功能、代理节点的分布式任务执行能力,以及插件系统的灵活扩展,能够满足不同规模和复杂度的项目需求。

4、业务流程 4.1、安装Jenkins 4.1.1、安装JDK 首先更新软件列表: $ sudo apt-get update 然后使用下面的命令来安装JDK: $ sudo apt install openjdk-17-jdk -y 然后执行下面的命令来验证JDK是否安装成功: $ java -version

出现如下图所示的内容即代表JDK安装成功:

然后执行下面的命令将安装好的JDK导出到环境变量中:

$ echo "export JAVA_HOME=/usr/lib/jvm/java-17-openjdk-amd64" >> ~/.bashrc $ echo "export PATH=\$JAVA_HOME/bin:\$PATH" >> ~/.bashrc $ source ~/.bashrc 4.1.2、安装Maven 首先更新软件列表: $ sudo apt-get update 然后使用下面的命令来安装Maven: $ sudo apt-get install maven -y 然后执行下面的命令来验证Maven是否安装成功: $ mvn -version

出现如下图所示的内容即代表Maven安装成功:

然后配置Maven的镜像源为国内镜像源:

$ sudo gedit /usr/share/maven/conf/settings.xml 然后将下面的内容添加到上面打开的文件中的<mirrors>标签中,最后保存修改后退出: <mirror> <id>alimaven</id> <mirrorOf>central</mirrorOf> <url>http://maven.aliyun /nexus/content/groups/public/</url> </mirror> 然后执行下面的命令将安装好的Maven导出到环境变量中: $ echo 'export MAVEN_HOME=/usr/share/maven' >> ~/.bashrc $ echo 'export PATH=$MAVEN_HOME/bin:$PATH' >> ~/.bashrc $ source ~/.bashrc 4.1.3、安装Git 首先更新软件列表: $ sudo apt-get update 然后使用下面的命令来安装Git: $ sudo apt-get install git -y 然后执行下面的命令来验证Git是否安装成功: $ git --version

出现如下图所示的内容即代表Git安装成功:

然后设置Git的全局配置(在这里需要输入自己的信息):

$ git config --global user.name "IronmanJay" $ git config --global user.email "1975686676@qq " 然后执行下面的命令将安装好的Git导出到环境变量中: $ echo 'export PATH=$PATH:/usr/bin' >> ~/.bashrc $ source ~/.bashrc 4.1.4、安装Jenkins 首先添加Jenkins的APT密钥: $ cd ~ $ wget -q -O - pkg.jenkins.io/debian/jenkins.io.key | sudo apt-key add - 然后添加Jenkins存储库: $ sudo sh -c 'echo deb http://pkg.jenkins.io/debian-stable binary/ > /etc/apt/sources.list.d/jenkins.list' 然后执行下面的命令来下载Jenkins的GPG密钥文件: $ sudo wget -O /usr/share/keyrings/jenkins-keyring.asc pkg.jenkins.io/debian/jenkins.io-2023.key 然后执行下面的命令修改Jenkins的源配置文件: $ echo "deb [signed-by=/usr/share/keyrings/jenkins-keyring.asc] pkg.jenkins.io/debian-stable binary/" | sudo tee /etc/apt/sources.list.d/jenkins.list 然后执行下面的命令来安装Jenkins: $ sudo apt-get update $ sudo apt-get install jenkins -y 4.1.5、启动Jenkins 首先执行下面的命令来启动Jenkins服务: $ sudo systemctl start jenkins 然后执行下面的命令来设置Jenkins开机自启: $ sudo systemctl enable jenkins 然后执行下面的命令来获取Jenkins的解锁密码: $ sudo cat /var/lib/jenkins/secrets/initialAdminPassword

然后将Jenkins的解锁密码记录下来:

然后打开浏览器,并访问下面的地址:

http://localhost:8080

然后输入刚刚我们获取到的Jenkins的解锁密码并按一下“继续”按钮:

然后按如下图所示进行选择:

然后按如下图所示进行选择(我在这里设置的用户名为“iie-iisd”,密码为“iie-iisd#210”):

然后按如下图所示进行选择:

然后按如下图所示进行选择:

然后就会来到Jenkins的主界面了:

4.2、 基本配置 4.2.1、安装插件

  Jenkins的插件是扩展Jenkins功能的模块,可用于集成工具、添加新功能或定制持续集成和持续交付(CI/CD)流程。我们可以按照下面的方法来配置和使用Jenkin的各种各样的插件。

首先我们按如下图所示进行选择,进入到Jenkins的系统管理界面中,并进入到插件管理界面中:

对于我们感兴趣的插件,我们可以按照下面的方式对其进行安装:

对于已经安装好的插件,我们可以按照下面的方式对其进行编辑:

在此处,我们还可以导入我们本地的插件:

4.2.2、工具设置

  在正式使用Jenkins之前,我们还要设置之前下载好的JDK、Maven和Git的环境变量,为了方便后续使用。

首先按照如下图所示进行选择,进入到Jenkins的工具设置界面中:

然后设置Java的环境变量(其值为“4.1.1、安装JDK”章节中设置的Java的环境变量):

然后确认Git的环境变量是否如下图所示(其值为“4.1.3、安装Git”章节中设置的Git的环境变量):

然后设置Maven的环境变量(其值为“4.1.2、安装Maven”章节中设置的Maven的环境变量),最后点击“保存”按钮即可:

然后关闭浏览器,并执行下面的命令来重启Jenkins服务:

$ sudo systemctl restart jenkins 最后重新打开浏览器,访问下面的网址重新进入Jenkins的系统即可: http://localhost:8080 4.3、测试用例 4.3.1、定时拉取并部署项目

  在现代软件开发中,持续集成与持续部署(CI/CD)是提高开发效率和质量的关键手段。Jenkins作为一款广泛使用的CI/CD工具,支持多种插件和灵活配置,使其成为开发团队的理想选择。本章节以我自己的开源项目(多任务集成管理系统)为例,详细介绍了如何通过Jenkins实现从源码管理、自动化构建到部署的完整流程,帮助开发者快速掌握自动化工具的应用技巧。

4.3.1.1、下载安装Tomcat 首先来到当前用户根目录中: $ cd ~ 然后执行下面的命令来下载Tomcat: $ wget dlcdn.apache.org/tomcat/tomcat-9/v9.0.97/bin/apache-tomcat-9.0.97.tar.gz 然后将下载好的Tomcat解压到执行目录中: $ sudo mkdir /opt/tomcat $ tar -zxf apache-tomcat-9.0.97.tar.gz $ sudo mv apache-tomcat-9.0.97 /opt/tomcat/ 然后设置Tomcat的环境变量: $ echo 'export CATALINA_HOME=/opt/tomcat/apache-tomcat-9.0.97' >> ~/.bashrc $ echo 'export PATH=$CATALINA_HOME/bin:$PATH' >> ~/.bashrc $ source ~/.bashrc 然后编辑下面的文件: $ gedit /opt/tomcat/apache-tomcat-9.0.97/conf/tomcat-users.xml 在打开的文件的<tomcat-users>标签中添加下面的内容以启动浏览器管理Tomcat功能,最后保存修改后退出即可: <role rolename="manager-gui"/> <user username="admin" password="password" roles="manager-gui"/> 然后编辑下面的文件: $ sudo gedit /opt/tomcat/apache-tomcat-9.0.97/conf/server.xml

在打开的文件中,按如下图所示进行修改,目的是避免端口冲突,最后保存修改后退出即可:

然后启动Tomcat服务:

$ sudo chmod +x /opt/tomcat/apache-tomcat-9.0.97/bin/startup.sh $ sudo /opt/tomcat/apache-tomcat-9.0.97/bin/startup.sh 然后打开浏览器访问下面的地址: http://localhost:8081/ 最后出现如下图所示的内容即代表Tomcat下载安装完毕: 4.3.1.2、安装相关插件

首先进入到Jenkins的插件配置界面(具体细节参考“4.2.1、安装插件”章节中的内容)来下载安装Gitee插件:

然后继续下载安装Maven插件:

检查Gradle插件已经下载安装完毕(系统自带),如果检查没有Gradle插件,请按照上面的方法对其进行下载安装:

4.3.1.3、构建测试项目 4.3.1.3.1、创建新项目

首先来到Jenkins工具的主界面,并按如下图所示选择来新建项目:

然后按如下图所示进行选择:

4.3.1.3.2、设置构建目标

首先按如下图所示进行选择,输入我的项目的Gitee地址:

然后按如下图所示进行选择:

在这里设置用户名和密码以及其它信息:

然后选择我们刚刚创建好的凭证:

4.3.1.3.3、设置定时触发器

按如下图所示进行选择和配置触发器(即在框中输入“H/10 * * * *”,该设置表示每10分钟检测一次目标项目是否有新的提交):

然后指定目标项目的“pom.xml”文件的路径(即在框中输入“pom.xml”,因为这里需要输入相对目录)和mvn执行目标和选项(即在框中输入“package -Dmaven.test.skip=true”,该配置表示跳过测试直接将项目打包):

然后按如下图所示进行选择,用以指示构建后的操作:

然后在出现的框中输入下面的内容(这些配置表示该项目成功构建后,会将其自动部署到Tomcat中):

echo "Deploying updated." # 停止 Tomcat sudo /opt/tomcat/apache-tomcat-9.0.97/bin/shutdown.sh sleep 5 # 等待 5 秒,确保 Tomcat 完全停止 # 确保 .jar 文件存在 if [ -f target/springboot-0.0.1-SNAPSHOT.jar ]; then echo "Copying jar file to Tomcat webapps directory..." sudo cp target/springboot-0.0.1-SNAPSHOT.jar /opt/tomcat/apache-tomcat-9.0.97/webapps/ROOT.war else echo "Jar file not found!" exit 1 fi # 重启 Tomcat echo "Starting Tomcat..." sudo /opt/tomcat/apache-tomcat-9.0.97/bin/startup.sh echo "Deployment completed." 然后在命令行终端执行下面的命令: $ sudo gedit /etc/sudoers 在打开的文件的最后添加下面的内容(这样修改的目的是配置Jenkins允许无密码使用sudo),最后保存修改后退出: jenkins ALL=(ALL) NOPASSWD: ALL 最后保存以上配置即可: 4.3.1.4、查看构建结果

如果顺利执行上面的操作后,会来到如下图所示的界面中,我们只需要构建该测试项目即可:

该任务执行一会后,就会出现如下图所示的内容,按照我下图中红框和红箭头处所示进行操作即可:

可以发现,该任务构建并且执行成功。这说明我们成功设置定时任务从目标项目中拉取提交信息,并将其部署到本地,实现了我们持续集成与持续部署(CI/CD)的目的:

4.3.2、预处理操作

  在有些项目的构建前,往往需要做一些预处理操作,比如检查依赖环境、下载/更新依赖和清理旧文件等,如果人工来做这些操作,往往非常复杂,为了解决该问题,Jenkins给我们提供了对于项目构建的预处理操作。下面我们还将以“4.3.1、定时拉取并部署项目”章节中的项目为例,继续对其进行持续集成与持续部署(CI/CD)的操作。

首先来到Jenkins的主界面,并按如下图所示进行选择:

然后按如下图所示进行选择:

然后在出现的框中输入下面的内容,这样配置的目的是在构建该项目之前,执行操作来清理旧文件,以避免出现未知问题:

echo "Cleaning up previous builds..." rm -rf /var/lib/jenkins/workspace/*/target/*

最后保存以上修改即可:

然后我们重新构建该测试项目:

然后按如下图所示进行选择:

可以发现,我们的预处理命令已经成功执行了,这说明我们的测试成功了:

4.3.3、自动发送邮件

  Jenkins支持自动发送邮件功能,通常用于在构建完成后通知相关人员,例如构建成功或失败的情况。我们仍以“4.3.1、定时拉取并部署项目”章节中的项目来进行本章节的演示。

首先来到Jenkins的主界面,并按如下图所示进行选择:

然后按如下图所示进行配置,设置要接受邮件的邮箱:

然后继续按如下图所示进行配置,最后保存本次修改即可:

然后再次回到Jenkins的主界面,并打开之前测试过的项目:

然后配置该项目:

然后按如下图所示进行配置,最后保存本次修改即可:

之后我们就可以正常构建项目了,若项目构建失败,将会给目标邮箱发送邮件提醒:

5、原理分析 5.1、Web框架

  在分析Jenkins的原理时发现,其源码过于庞大,若是要一点点分析几乎是不现实的,所以我们采用一种“讨巧”的方法,即通过其Web框架对Jenkins的原理进行分析。为什么要这么做呢?

  因为Stapler是Jenkins核心的Web框架,用于将Jenkins的后端逻辑与前端视图无缝集成。Jenkins的许多功能和用户交互界面都依赖Stapler来实现动态的、灵活的URL映射和请求处理。所以本章节将从Stapler入手来对Jenkins的原理进行分析。

5.1.1、Stapler简介

  Stapler是一个轻量级的Java Web框架,与传统框架(如Spring MVC)不同,Stapler更强调对象与URL的自然映射关系。它通过将URL路径直接映射到Java对象的方法或字段,提供了一种直观、高效的方式来处理HTTP请求。对Stapler有了初步的了解之后,我们来看一下其核心理念。

URL即对象路径 URL的每一级路径都被视为一个对象或对象的属性。例如,http://localhost:8080/user/iie-iisd映射为: /user→调用Jenkins.getUser(String id)返回User对象。/iie-iisd→User对象的具体实例。 动态调用方法 URL的尾部路径通常会映射到一个方法。例如:/configSubmit会调用doConfigSubmit()方法。 无 XML 配置 Stapler不需要繁琐的XML配置,通过注解和类的方法定义直接驱动框架。 5.1.2、Stapler的主要组件 路径解析与对象绑定 Stapler会解析URL,将路径的每一段映射到对象或方法。例如,路径/user/iie-iisd/account会依次调用Jenkins.getUser()和User.getAccount()。 动态方法调用 Stapler会根据HTTP请求类型(如GET、POST)动态调用对象的方法。方法名以do开头的函数(如doSubmit)通常被用来处理POST请求。 请求与响应处理 请求通过StaplerRequest对象传递,包含表单数据和请求信息。响应通过StaplerResponse对象传递,支持返回JSON、页面重定向等。 视图绑定 Stapler使用Java Server Pages(JSP)或Groovy模板绑定视图和数据。对象的名称会映射到对应的视图文件,例如User类的视图可能是user/index.jelly。 5.1.3、Stapler与Jenkins的集成

  Jenkins使用Stapler作为其核心的Web层框架,使得Jenkins的所有Web界面和HTTP API都基于Stapler构建。Stapler是Jenkins提供动态扩展能力和友好界面的关键技术。

Jenkins的URL路由实现 路径解析与核心类 Jenkins的根路径/映射到Jenkins类的实例。/user/:id由Jenkins.getUser(String id)方法处理,返回对应的User对象。 方法映射 URL的尾部路径映射到方法,如/configSubmit会调用doConfigSubmit()。Stapler根据HTTP方法(GET、POST 等)决定具体调用的方法。 插件支持 Jenkins的插件可以通过扩展StaplerProxy接口,将自定义的对象和方法暴露到URL路径下。例如,插件可以通过http://localhost:8080/plugin/my-plugin/暴露功能。 动态视图渲染 Jenkins的许多UI使用Stapler与Jelly文件绑定数据与视图。例如,User对象可能通过user/configure.jelly文件渲染用户配置页面。

  总之,Stapler是Jenkins Web层的基石,其轻量、高效的URL到对象映射机制为Jenkins提供了灵活的扩展性和直观的功能路由。Stapler支持Jenkins的模块化设计,使开发者可以通过简单的对象定义和方法调用快速添加新功能。

5.1.4、根据请求定位后端代码

  在前面的章节我们提到过,Jenkins的代码过于庞杂,所以手动逐一分析不太现实,所以我们换一种角度,即我们只关注我们感兴趣的部分,利用Stapler的特性,根据不同功能的请求去定位后端代码,进而对其进行分析。故在本章节我们将介绍如何使用这种方法,且后续不再强调。

首先来到Jenkins的前端界面后打开浏览器控制台界面(按一下“F12”即可):

然后查看所有网络信息(当然,每次查看之前都要清除之前的网络信息):

比如我们要新建一个任务,即点击“新建Item”,可以查看到其对应的网络请求:

可以发现该网络请求对应的后端接口为“http://localhost:8080/view/all/newJob”,所以可以在Jenkins的源码中直接定位处理该请求的源码:

5.2、高级视图

  Jenkins的架构是一个分布式、高度可扩展的系统。通过核心的Jenkins Master和多个代理节点之间的通信,它能够灵活地处理各种构建和部署任务。Stapler框架为Web交互提供了一个强大的工具,插件系统则使得Jenkins能够根据用户需求进行定制。本章节将会从Jenkins的高级视图入手,从更高的层次分析Jenkins的执行流程。

5.2.1、数据流架构

  本章节我们将会从Jenkins工作时的数据流入手,详细分析其每一部分在整个工作的生命周期中扮演的角色及其定位。关于Jenkins的数据流架构图如下图所示。

  上图展示了Jenkins的网络流量及高层架构设计,概述了Jenkins本身、内部代理与外部服务之间使用各种协议的通信流。下面我们对其各部分进行详细分析。

协议与流量概述 SSH(红色):用于Jenkins与代理之间的通信(例如,SSH代理、Inbound代理)。HTTP(S)(蓝色):用于Jenkins Web界面的通信、集成、以及与外部服务(如更新中心或制品管理器)的通信。SMTP(紫色):用于通过SMTP服务器发送电子邮件。Jenkins Remoting(绿色):用于Jenkins代理之间的通信(Jenkins Remoting TCP-IP、JNLP或WebSocket)。 图中组件 互联网或私有网络: 来自外部服务、集成和最终用户访问Jenkins服务器的通信,通常通过HTTP或HTTPS。外部组件可以包括API集成和最终用户请求。 企业私有网络: 这是Jenkins与内部服务(如制品管理器或内部源代码管理(SCM)系统)的通信。Jenkins Remoting TCP-IP用于连接企业内部网络中的代理。 Jenkins: Jenkins的核心接收请求,管理代理(通过SSH或Remoting),并执行作业和与外部系统的集成等任务。 企业代理(可选): 如果使用代理,它负责在Jenkins和外部世界(如互联网、更新、外部SCM系统)之间进行路由。 外部服务: 表示来自外部系统的通信,如更新中心、外部制品管理器和SCM系统。 流量分析 最终用户:用户通过HTTP或HTTPS访问Jenkins(默认端口8080用于HTTP,443用于HTTPS)。Jenkins代理:Jenkins主节点与代理之间通过SSH和Jenkins Remoting进行通信。外部服务:Jenkins与外部服务(如更新、使用统计信息、制品管理等)通过HTTP/HTTPS或SSH进行通信。 安全考虑 默认禁用SSH用于外部通信:出于安全考虑,默认情况下禁用SSH访问Jenkins,确保只有特定的代理或授权用户才能通过SSH连接。SMTP:图中包含了SMTP服务器,用于发送通知邮件,但这也提示了需要注意邮件通信的安全性。 其它说明 端口号:默认端口号(如HTTP的8080端口和HTTPS的443端口)可以通过配置进行修改。TLS(HTTPS):Jenkins支持TLS加密来确保通信的安全。 5.2.2、架构组成

  该架构展示了Jenkins系统的关键组成部分,涵盖了用户交互层(CLI、HTTP、Web UI、Remoting)、Jenkins内部处理层(Stapler 框架、业务逻辑)、以及存储层(XML 配置)。其中,插件的扩展机制使得Jenkins可以不断增加新功能和特性,从而满足不同用户和使用场景的需求。

用户交互层 命令行接口 (CLI): 提供命令行交互的方式,通常用于自动化脚本或通过工具(如 curl, wget)进行机器对机器的通信。CLI提供一种通过命令行执行Jenkins操作的方式,可以触发Jenkins作业、获取结果等。HTTP端点: Jenkins通过HTTP端点提供Web服务,用户和系统可以通过HTTP请求与Jenkins交互。例如,Jenkins的REST API、Webhooks等都是基于HTTP端点进行通信。Web用户界面: 提供图形用户界面(GUI),通常是用户与Jenkins交互的主要方式。用户通过浏览器访问Jenkins Web UI,进行配置、监控构建和管理插件等。Web UI通常使用Jelly或Groovy视图进行渲染,允许对数据的呈现进行动态处理。Remoting: Jenkins使用Remoting协议与代理节点进行通信,特别是通过JNLP(Java网络启动协议)或WebSocket连接实现与远程代理的通信。Remoting是Jenkins分布式构建的一部分,使得构建任务能够在不同的机器上分布执行。 Jenkins内部处理层 Stapler框架: Stapler是Jenkins的Web框架,负责请求的路由、处理和安全性。它负责将用户的HTTP请求映射到具体的处理逻辑,并确保请求的数据通过相应的处理流程进行校验和处理。Stapler支持URL路由、表单数据绑定、模型渲染等功能,是Jenkins的核心框架之一。业务层: 业务层包含了Jenkins的核心功能,如调度作业、模型处理等。具体来说,这个层次包括: 作业调度:管理作业的启动、执行和调度。模型处理:处理Jenkins中不同的数据模型,如作业模型、用户模型等。任务调度:基于时间、依赖关系等条件调度作业的执行。 存储层 存储层: 存储层主要由Jenkins主目录(JENKINS_HOME)中的XML文件组成。这些文件用于持久化存储Jenkins的各种配置、作业状态、插件数据等。XML文件通常包含作业的配置文件、系统配置文件和插件设置等,是Jenkins持久化数据的核心部分。 插件层 插件扩展: Jenkins本身并不提供所有功能,很多功能都是通过插件来扩展的。插件可以添加新的功能、集成新的工具或系统。例如,LDAP插件可以帮助Jenkins集成LDAP认证系统,Git插件可以实现Git仓库的集成等。插件是Jenkins能够无限扩展的核心机制,随着功能需求的增加,更多的插件被开发和集成到Jenkins中。 5.3、可扩展性 5.3.1、基本概念

  Jenkins的可扩展性依赖于多个核心机制的结合,包括扩展注解、描述符与可描述对象、Action扩展等。这些机制使得插件和核心功能能够灵活地互动、扩展和定制,从而增强了Jenkins在自动化、CI/CD等场景中的应用能力。同时,Jenkins还提供了一些工具和注解,帮助开发者进行访问控制、菜单显示、序列化等操作,进一步提升了系统的可定制性和安全性。

访问控制注解 (@Restricted) @Restricted注解用于限制访问权限,确保某些操作或功能只有特定用户或用户组可以执行。它主要用于控制插件中的某些操作的可访问性,防止未经授权的用户进行访问。 应用场景: 限制对特定功能或资源的访问,仅授权特定用户组或管理员访问。在需要保护系统关键功能时,可使用该注解进行访问控制。 如何显示菜单项到所有项目 为了将自定义的菜单项显示到所有Jenkins项目中,开发者可以使用扩展点机制,在Jenkins UI中添加新的菜单项或按钮。这些菜单项可以通过Action类实现,确保它们在所有项目中统一显示,方便用户进行交互。 应用场景: 在每个项目页面上显示统一的操作菜单。提供全局访问的功能,如报告生成、日志查看等。 如何序列化匿名类 匿名类通常用于临时实现某些接口或类,但为了保证这些类能够在Jenkins重启或分布式环境中保持其状态,它们必须能够被序列化。开发者可以通过实现Serializable接口或其他方法来确保匿名类的序列化。 应用场景: 使用匿名类作为扩展点时,必须考虑其在 Jenkins 重启后的状态保存。在分布式系统中,保证匿名类对象能够被正确序列化传递。 常见扩展点列表 Jenkins提供了多个常见的扩展点,插件可以通过这些扩展点来实现自定义功能。例如,以下是几个典型的扩展点: 构建步骤 (Build Steps):插件可以通过扩展构建步骤来加入自定义的构建逻辑。构建触发器 (Build Triggers):插件可以通过扩展构建触发器来定义触发构建的条件。构建后操作 (Post-build Actions):插件可以扩展构建后操作来进行后续的处理。 应用场景:通过扩展常见扩展点,插件可以定制Jenkins的行为,满足特定需求。这些扩展点的使用使得Jenkins在自动化过程中更具灵活性和可扩展性。 如何定义新的扩展点 在某些情况下,现有的扩展点无法满足需求,此时开发者可以定义新的扩展点。定义新的扩展点通常涉及以下几个步骤: 创建一个接口或抽象类,供其他插件来实现。使用 @Extension 注解,使得插件中的实现被 Jenkins 识别和注册。通过注册机制将新的扩展点暴露给 Jenkins 和其他插件。 应用场景:当现有扩展点无法满足需求时,可以自定义扩展点以适应新的功能。新的扩展点可以提供额外的功能,例如自定义的构建后操作或不同的用户认证方式。 项目视图导航的扩展点 Jenkins提供了用于扩展项目视图导航的扩展点,允许开发者为不同的项目视图添加自定义的导航组件。例如,可以为不同的项目页面添加新的菜单项、按钮或链接,增强用户体验。 应用场景: 定制项目视图,添加特定的导航或功能按钮。为项目页面提供额外的控制或信息面板,优化用户界面的布局和交互。 5.3.2、具体实现

  Jenkins设计时考虑了可扩展性,既包括内部的核心部分,也包括插件的扩展。Jenkins的可扩展性通过以下几个概念的结合来实现:

扩展注解(@Extension) 扩展注解允许Jenkins发现类、实例化它们,并将它们注册到其超类和接口的全局实现列表中。这不仅适用于核心部分的实现,也适用于插件提供的实现。插件可以为核心或其他插件定义的扩展点提供实现。当Jenkins需要提供一个列表时(例如,安全域实现列表),它会查询所有标有@Extension注解的SecurityRealm子类型。 应用场景: 插件可以通过注解为核心的扩展点提供功能。例如,LDAP、Jenkins 用户数据库等可以通过此机制作为SecurityRealm的实现。 描述符与可描述对象 (Descriptors和Describables) Descriptor和Describable用于当需要多个同类扩展实例时。例如,构建步骤通常会使用这些机制。Descriptor用来存储它们的全局配置,并作为工厂,而Describable则是具有独立、实例化配置的具体实例。这类似于面向对象编程中的类与对象的关系。 应用场景: 多个扩展实例的配置管理。Descriptor负责配置的存储和实例化,而Describable则代表具体的扩展实例。 Actionable和Actions Actionable是一个抽象类,允许子类通过Action实现扩展。Action实现用于将任意数据与模型对象一起存储,或为其呈现提供附加内容。具体细节因子类而异,通常Actionable对象会在侧边栏显示动作,并将请求路由到Action的getUrlName()方法,从而使其能够为Actionable对象贡献页面。 应用场景: Actionable对象能够显示在侧边栏中,用户可以通过点击链接跳转到相关页面。Action允许扩展对象的功能,提供更多用户交互的方式。 5.4、安全性

  Jenkins的安全性依赖于清晰的权限模型、灵活的认证机制和全面的ACL管理。通过核心安全组件与插件的结合,Jenkins提供了强大的访问控制和认证支持,确保了敏感操作的安全性。在开发Jenkins插件时,开发者需要遵循最佳实践,通过权限检查、UI动态渲染等方式,提升整体系统的安全性。

5.4.1、安全架构

  Jenkins的安全架构主要包括以下核心组件:

权限(Permission) 表示需要安全保护的操作,通常为动词形式,例如“配置”、“管理”等。认证(Authentication) 表示当前用户的身份及其角色(或组)。所有线程在Jenkins中运行时,隐式携带一个Authentication对象。如果线程不由用户请求启动(如Executor),则携带“系统”的全能认证对象。访问控制列表(ACL) 决定当前线程的认证对象是否具备某一权限。访问控制对象(AccessControlled) 实现了ACL的对象,如Job、Jenkins、User等。

  以下示例代码展示了如何在执行敏感操作前检查权限:

  在此代码中,只有具有Administer权限的用户才能执行JVM关闭操作。若用户没有权限,则会抛出异常。

5.4.2、插件的安全性

  开发Jenkins插件时,需要完成以下安全性工作:

识别敏感操作 找出会更改服务器状态的代码,这些代码需要调用checkPermission进行权限检查。找到最近的访问控制对象 例如,如果this对象已被访问控制,直接使用它,否则寻找逻辑上的最近祖先对象,或者退而求其次使用Jenkins单例对象。选择适当的权限对象 权限对象通常在扩展点中定义为静态常量。如果不确定,可以使用Jenkins.ADMINISTER作为默认权限。

  下面这段代码的目的是检查当前线程的用户是否具备指定的权限,从而决定是否允许执行某些操作。

5.4.3、检查Jelly文件的权限

  在Jenkins插件开发中,Jelly文件用于描述HTML页面中的布局和动态内容。为了保护敏感数据或操作,通常需要对用户权限进行检查,以决定是否允许用户访问页面或显示某些内容。Jelly文件中提供了内置的方式来实现这种基于权限的动态渲染。

保护整个页面 如果希望对一个HTML页面进行全局保护,可以在Jelly文件的<l:layout>标签中使用permission属性。假设有一个管理页面,只有管理员才能访问,其Jelly文件内容如下: 如果当前用户具备ADMINISTER权限,将渲染整个页面。如果用户没有权限,将自动拒绝访问。

部分禁用页面渲染 在某些情况下,并不需要保护整个页面,而是根据用户权限动态显示或隐藏页面的一部分内容。此时,可以使用<j:if>标签进行条件判断。假设我们希望只有管理员可以看到“删除按钮”,普通用户无法看到: 如果当前用户具备ADMINISTER权限,页面会显示“删除项目”按钮。如果用户没有权限,“删除项目”按钮不会出现在页面上。

5.4.4、认证方式

  Jenkins使用Acegi Security(Spring Security的前身)实现认证,支持以下认证方式:

Web UI 使用登录表单,字段为j_username和j_password。REST API 使用基本认证:用户名/密码或用户名/API令牌。Jenkins CLI(命令行工具) 通过--username和--password参数直接传递。使用-auth参数传递username:password或username:apiToken。使用SSH本地密钥进行认证。 5.4.5、认证流程

  认证流程根据使用的方法有所不同:

Web UI和REST API 基于登录名/密码的认证,通过AbstractPasswordBasedSecurityRealm类委托给配置的SecurityRealm。CLI(命令行工具) 提供用户名和密码作为参数,或使用API令牌。 使用SSH本地密钥的认证,通过SSHD模块完成。

  以下图表展示了不同认证方式的流程:

Web UI和REST API流程 这张图展示了Jenkins的身份验证流程,涵盖Web UI和REST API两种访问方式。整体逻辑是用户提交登录信息后,经过验证组件处理,成功后标记为已认证(Authenticated)。

对于Web UI,用户通过HTML表单提交用户名和密码(字段为j_username和j_password),请求被传递到AbstractPasswordBasedSecurityRealm,后者将验证逻辑委托给配置的SecurityRealm(Jenkins的身份验证核心组件)。如果认证成功,用户会被标记为“已认证”,同时用户信息存储在Request#getSession中,表示用户已经“登录”(Logged in)。对于 REST API,支持两种认证方式:使用登录名/密码或登录名/API Token。两者都通过Basic Auth进行身份验证。BasicHeaderRealPasswordAuthenticator用于处理登录名/密码的请求,而BasicHeaderApiTokenAuthenticator则用于处理登录名/API Token 的请求。验证过程与Web UI类似,同样由AbstractPasswordBasedSecurityRealm和SecurityRealm完成。但REST API是无状态的,不会存储用户会话信息。

无论是Web UI还是REST API,都依赖SecurityRealm完成核心认证逻辑,支持自定义的安全策略,如LDAP、SSO等。总的来说,Web UI提供了会话式认证体验,而REST API则采用无状态认证方式,适合脚本和自动化访问场景。

CLI(SSH 和本机) 上图主要描述了两种通过命令行接口(CLI)远程访问系统的方法:原生CLI和Jenkins CLI。

原生CLI通常使用SSH协议进行远程通信,并要求用户提供用户名和密码(或API密钥)来验证身份。这种方式虽然直接,但在安全性方面可能存在一定的风险,特别是如果密码或API密钥被泄露。相比之下,Jenkins CLI提供了一个更为安全和灵活的选择。它使用Jenkins特有的身份验证机制,通过用户名和API密钥进行身份验证。此外,Jenkins CLI还支持SSL传输,确保数据传输的安全性。同时,它还可以根据用户的角色来控制访问权限,实现基于角色的身份验证。

此外,上图还提到了登录状态和将认证信息缓存在客户端的选项:

登录状态 表示用户已经成功登录到系统。这意味着用户已经通过提供的凭据(无论是原生CLI的用户名和密码/API密钥,还是Jenkins CLI的用户名和API密钥)成功验证了身份,并可以开始执行远程命令或访问系统资源。将认证信息缓存在客户端 该选项可以将认证信息在后续操作中重复使用,从而提高效率。同时,它也强调了身份验证在远程访问过程中的重要性,确保只有经过验证的用户才能访问系统资源。

总的来说,通过对比原生CLI和Jenkins CLI的远程访问方式,展示了Jenkins CLI在提供更安全、更灵活的远程访问方面的优势。

5.5、流水线

  Jenkins流水线是一套插件,旨在支持Jenkins实现和集成持续交付(CD)流水线。流水线将复杂的软件交付过程建模为一组自动化步骤,从代码提交到测试、部署的各个阶段都被统一管理。以下将从概念、功能、语法及示例四个方面详细展开。

5.5.1、流水线概述 什么是Jenkins流水线? Jenkins流水线是一种将持续交付过程建模为代码的工具。通过“Pipeline as Code”的概念,用户可以在文本文件Jenkinsfile中定义流水线的各个阶段。该文件可存储在源码控制中,方便团队协作、版本化管理与审查。流水线的主要特性 代码化(Code):流水线以代码形式实现,支持版本化。持久性(Durable):可从计划内或意外的Jenkins重启中恢复。可暂停性(Pausable):支持等待人工输入或批准后继续。灵活性(Versatile):满足复杂的CD场景需求,包括分叉、循环和并行执行。可扩展性(Extensible):支持通过插件扩展DSL。 基本概念 Pipeline:流水线定义了整个构建过程,包括构建、测试、部署等阶段。Node:Jenkins执行流水线任务的工作环境。Stage:流水线中划分的逻辑阶段,比如“Build”、“Test”、“Deploy”。Step:执行具体任务的基本单元,比如运行命令、执行测试等。 流水线的优势 代码版本化:流水线代码与项目代码一同存储在版本控制中,支持团队协作。可靠性:支持任务恢复、重启以及持久化。灵活性:满足各种复杂的自动化需求。扩展性:支持通过插件和共享库扩展功能。 5.5.2、流水线语法 5.5.2.1、流水线语法概述

  Jenkinsfile支持两种语法:

声明式语法(Declarative):简单易读,功能丰富,适合多数场景。脚本化语法(Scripted):更灵活、复杂,适用于高级用户。 5.5.2.2、声明式流水线

  声明式语法结构清晰,使用pipeline块来定义工作流。

  其中:

pipeline:定义整个流水线。agent:指定流水线执行的节点。stages:包含多个stage块,每个stage表示流水线的一个逻辑阶段。steps:包含执行步骤,例如运行命令或调用工具。 5.5.2.3、脚本化流水线

  脚本化语法更接近于Groovy脚本,提供更大的灵活性。

  其中:

node:指定流水线执行的节点。stage:定义阶段块,主要用于逻辑划分和可视化。 5.5.3、流水线功能扩展 5.5.3.1、分支和Pull Request支持

  在多分支开发中,通常会有多个活跃的分支或多个提交请求(Pull Request),而Jenkins的Multibranch Pipeline插件可以帮助你为每个分支自动生成独立的流水线,以便针对不同的分支执行不同的 CI/CD 流程。

Multibranch Pipeline插件概述:

该插件使得Jenkins能够自动扫描版本控制系统(如Git)中的每个分支,并为每个分支生成独立的流水线。每当有新的分支被创建或删除时,Jenkins会自动识别,并相应地创建或删除流水线。

如何配置Multibranch Pipeline:

在Jenkins中创建一个Multibranch Pipeline项目。在项目配置中,指定Git仓库URL和认证信息。Jenkins会扫描仓库中所有的分支(或标签),并且为每个分支自动生成流水线。如果某个分支有Jenkinsfile,Jenkins会自动运行该分支上的流水线任务。

Pull Request自动化:

当某个分支通过Pull Request合并到主分支时,Jenkins可以对该Pull Request进行自动化处理(例如进行构建、测试等)。你可以通过集成GitHub或Bitbucket插件,使Jenkins在Pull Request创建、更新或关闭时自动执行流水线。PR流水线示例: 可以通过配置Jenkinsfile以及GitHub Webhook,使得每次Pull Request提交时,Jenkins都会自动拉取代码并执行相应的CI流程。通常包括代码检查、单元测试等操作。

PR Build与主分支的比较: Jenkins可以在PR的基础上执行与主分支的比较,以确定Pull Request是否包含有影响主分支的修改。这有助于确保合并到主分支的代码不会导致任何问题。

5.5.3.2、Docker集成

  Docker集成使得Jenkins流水线能够在Docker容器中运行构建任务,这对于构建和部署环境的一致性和可移植性非常重要。

为什么使用Docker集成?

环境隔离: Docker容器提供了一个隔离的环境,避免了主机环境的依赖冲突。一致性: 容器确保开发、测试、生产等各个环境的一致性,从而避免环境不一致导致的问题。高效性: Docker容器启动快速,适合CI/CD流水线中对快速构建的需求。

如何在Jenkins Pipeline中使用Docker: Jenkins提供了docker代理(agent)来运行流水线中的构建步骤。通过在流水线中指定Docker镜像,Jenkins会在该镜像中运行构建任务。

Docker容器执行多个步骤 在Docker容器内,可以执行多个步骤,依赖的工具和环境都可以通过容器镜像来定义。例如,使用一个包含Maven和JDK的镜像来构建Java项目。

使用Docker Compose进行多容器管理 如果构建需要多个容器协作(例如构建数据库和应用程序),可以使用docker-compose来配置多个服务。

5.5.3.3、共享库

  共享库(Shared Libraries)是Jenkins流水线中一个非常重要的功能,它允许你将常见的构建逻辑抽象出来,并在多个流水线项目中复用。

共享库的概念: 共享库使得在多个项目之间共享通用的流水线代码成为可能。通过使用共享库,你可以将常用的构建、测试、部署步骤封装成库函数,并在不同项目的Jenkinsfile中调用。

共享库的结构: 共享库一般包括以下结构:

vars文件夹:存放共享的全局变量和函数。src文件夹:存放Groovy类,适用于更复杂的功能。resources文件夹:存放用于流水线的资源文件(如模板)。

如何使用共享库

首先,将共享库保存到Git仓库中,并在Jenkins的系统配置中配置该共享库。然后,在Jenkinsfile中通过`@Library``注解来引用共享库。

共享库示例 假设我们将常用的构建步骤封装在共享库中的mySharedStep.groovy中:

5.5.4、流水线开发工具

  Jenkins提供了多种工具和插件,以帮助开发者更高效地编写、调试和管理流水线。以下是一些关键的工具和插件:

Blue Ocean Blue Ocean是Jenkins提供的一个现代化的图形化界面插件,旨在使流水线的创建和管理更加直观和易用。通过Blue Ocean,开发者可以通过可视化的方式创建、配置和监控流水线,提升了用户体验,特别是对于非技术人员来说。其特点如下: 可视化流水线创建:Blue Ocean提供了一个直观的 UI,开发者可以通过图形化界面拖拽来构建流水线,而不需要手动编写复杂的Jenkinsfile。流水线运行状态的可视化:所有的流水线运行过程都会以图形化方式展现,包含每个阶段的执行状态、日志、测试结果等信息,便于快速了解流水线的执行进度和状态。简化的多分支支持:对于多分支流水线,Blue Ocean能自动识别并展示不同分支的状态,提供清晰的视图。错误追踪和调试:错误信息被直观地标出,且支持从UI直接跳转到日志文件中查看详细的执行信息,帮助开发者快速调试和修复流水线中的问题。 Pipeline Syntax Pipeline Syntax是Jenkins提供的一个非常有用的工具,它帮助开发者生成流水线代码,并提供语法提示和示例。特别是在编写复杂的流水线时,Pipeline Syntax提供的代码片段能够显著提高开发效率,减少错误。其特点如下: 自动生成代码:开发者可以通过Jenkins的Web UI使用Pipeline Syntax自动生成流水线代码。例如,可以生成构建步骤、测试步骤、通知步骤等常用操作的代码片段。语法提示:当开发者编写Jenkinsfile时,Pipeline Syntax提供了详细的语法提示和代码示例,帮助开发者快速了解如何编写流水线。多种代码选项:支持多种常用操作,如执行shell命令、构建Docker镜像、发送通知等,开发者可以选择所需的操作,并生成相应的Groovy代码。 Pipeline Shared Libraries Pipeline Shared Libraries是Jenkins中的一种功能,它允许开发者将多个项目中共享的流水线逻辑提取出来,抽象成共享的库。通过使用共享库,开发者能够将通用的构建、测试、部署流程进行复用,从而减少代码重复,提高可维护性。其特点如下: 代码复用:共享库可以封装通用的流水线逻辑,如常见的构建步骤、部署步骤等,避免每个项目中都重复编写相同的逻辑。组织化的结构:共享库通常由vars、src、resources等文件夹组成,支持更复杂的功能。vars文件夹中存放的是可以在流水线中直接调用的变量和方法,src文件夹用于存放Groovy类,resources文件夹用于存放模板文件。集中管理:共享库通过Git仓库集中管理,可以轻松地进行版本控制和更新。在需要更新某个通用功能时,只需修改共享库中的代码,所有使用该共享库的项目都会自动受益。提高可维护性:通过共享库,流水线的逻辑被抽象化,项目中的Jenkinsfile可以保持简洁,易于维护和扩展。 5.5.5、流水线示例

  在本章节,我们将展示声明式语法和脚本化语法的完整流水线示例,涵盖构建、测试和部署阶段,并加入了通知、条件检查和错误处理等功能。

声明式语法示例 声明式语法使流水线配置更加直观,便于理解和管理。以下示例包含构建、测试、部署、环境变量定义、通知和条件检查等功能: pipeline { agent any environment { BUILD_DIR = 'build' // 定义构建目录 TEST_RESULTS = 'results/**/*.xml' // 定义测试结果路径 } options { timeout(time: 30, unit: 'MINUTES') // 设置流水线超时时间 skipStagesAfterUnstable() // 如果阶段不稳定,则跳过后续阶段 } stages { stage('Checkout Code') { steps { checkout scm // 检出源码 echo 'Code checkout complete' // 打印日志 } } stage('Build') { steps { sh 'make clean' // 清理构建目录 sh 'make build' // 执行构建 } } stage('Test') { steps { sh 'make test' // 执行测试 junit "${TEST_RESULTS}" // 收集测试结果 } } stage('Deploy') { when { branch 'main' // 仅在主分支上执行部署 } steps { sh 'make deploy' // 执行部署 echo 'Deployment successful' // 打印日志 } } } post { success { echo 'Pipeline executed successfully!' // 打印成功日志 mail to: 'dev-team@example ', // 发送通知邮件 subject: "Build Successful: ${env.BUILD_NUMBER}", body: "The build and deployment were successful!" } failure { echo 'Pipeline execution failed!' // 打印失败日志 mail to: 'dev-team@example ', // 发送通知邮件 subject: "Build Failed: ${env.BUILD_NUMBER}", body: "The build or deployment failed. Please check the logs." } } } 脚本化语法示例 脚本化语法提供了更大的灵活性,适用于复杂的流水线场景。以下脚本化示例,展示了动态参数配置、并行测试和错误处理的功能。 node { try { stage('Checkout Code') { echo 'Checking out code...' checkout scm // 检出源码 } stage('Build') { echo 'Building the project...' sh 'make clean' sh 'make build' } stage('Test') { echo 'Running tests...' parallel( // 并行运行不同模块的测试 UnitTests: { sh 'make unit-tests' }, IntegrationTests: { sh 'make integration-tests' }, FunctionalTests: { sh 'make functional-tests' } ) junit 'results/**/*.xml' // 收集所有测试结果 } stage('Deploy') { echo 'Deploying the application...' if (env.BRANCH_NAME == 'main') { // 仅在主分支执行 sh 'make deploy' echo 'Deployment to production complete' } else { echo "Skipping deployment for branch: ${env.BRANCH_NAME}" } } } catch (Exception e) { echo "Pipeline failed with error: ${e.message}" // 捕获错误并记录 mail to: 'dev-team@example ', subject: "Pipeline Failed: ${env.BUILD_NUMBER}", body: "Error details: ${e.message}" error "Stopping the pipeline due to failure" // 停止流水线 } finally { echo 'Cleaning up resources...' cleanWs() // 清理工作区 } } 5.6、单/多节点架构 5.6.1、单节点架构

  Jenkins单节点架构是一种简单的部署模式,主节点负责任务调度、执行和管理,适合小型项目,但在任务量增加时易受性能和扩展性限制。

基本概念 Jenkins单节点架构是Jenkins最基本的部署模式。在该架构中,只有一个节点(即Jenkins主服务器,也称为Master)负责完成以下所有职责:

任务调度:接收用户提交的构建任务,并分配到执行器(Executor)。任务执行:直接在主节点的执行器上运行构建任务。用户界面:通过Web界面提供可视化的任务管理和监控。插件管理:主服务器负责管理所有Jenkins插件,为任务提供扩展功能。日志记录与存储:管理构建任务的历史记录、日志以及工作空间。

这种架构适合资源有限的小型项目或开发团队,可以快速搭建CI/CD环境进行测试或开发。

架构组成

主服务器(Master) 负责所有调度任务,是架构的核心。提供 Jenkins 的管理界面,支持插件安装和配置。内置执行器用于运行构建任务。 执行器(Executor) 每个Jenkins主节点默认包含若干个执行器,执行器的数量可以在配置中调整。每个执行器在任何时间只能执行一个任务。 工作空间(Workspace) 每个任务都有独立的工作空间,用于存储构建过程中产生的文件和数据。 5.6.2、多节点架构

  Jenkins的多节点架构通过添加代理节点(Agent),将任务执行分散到多个节点,主节点专注调度,具备更高的性能、弹性和可靠性,适合复杂场景和大型项目。

架构组成

主节点(Master) 主节点是整个Jenkins系统的核心,负责任务调度、代理节点管理和用户交互。其主要功能如下: 任务调度:根据配置和资源状况决定构建任务的执行位置。任务分发:将构建任务分发给代理节点执行。系统管理: 管理Jenkins的配置和插件。提供用户界面,用于创建和管理任务。 监控代理节点:实时监视代理节点的状态和性能。直接执行任务:在所有代理节点都忙碌时,主节点可以作为最后的任务执行者。日志与报告:收集代理节点的任务执行日志,并生成汇总报告。 代理节点(Agent) 代理节点是运行在远程服务器上的Java可执行文件(通常为java -jar agent.jar),它从主节点接收任务并执行具体的构建工作。其主要功能如下: 执行构建任务:代理节点负责实际的代码编译、测试和部署。资源隔离:支持特定任务在特定代理节点上执行,以满足特定环境或资源需求。灵活配置:代理节点可以根据项目需求动态增加或移除。

工作原理

任务调度: 主节点接收用户提交的任务请求,评估当前可用的代理节点资源。根据任务的优先级、资源需求和节点标签等,将任务分发到合适的代理节点。 任务执行: 代理节点接收主节点的构建命令,执行指定的任务。执行结束后,将结果和日志返回主节点。 资源管理: 代理节点可以运行在不同的硬件和操作系统上,满足跨平台需求。主节点动态监控代理的状态(在线/离线)、任务负载和性能,确保系统运行平稳。 6、参考文献 Jenkins 架构详解Jenkins详细教程_jenkins使用教程Jenkins 持续集成综合实战如何在 Ubuntu 20.04 LTS 上安装 Java(JDK 和 JRE)使用 APT 在 Ubuntu 22.04 上安装 Apache Maven_apt mavenUbuntu系统轻松配置Maven环境:一步到位的详细指南JenkinsJenkins 自动化测试(构建)搭建BackgroundManagementSystemBasedOnSpringBootAndVue: 本项目基于SpringBoot搭建后台,使用Vue搭建前端服务。完成了Vue2前端与后端初始框架搭建、集成Mybatis、实现增删改查、实现分页查询、实现代码生成器、实现导入导出、实现用户登录注册与异常处理、实现文件上传与下载、整合ECharts、权限菜单、实现关联查询、集成Redis实现缓存、高德地图集成演示、集成视频播放组件、集成Markdown和多级评论等功能。Jenkins操作手册 - 巨详细,一篇足矣!Jenkins-发送邮件配置jenkinsci/jenkins: Jenkins automation serverLearn Jenkins the hard way (1) - 从源码运行Jenkins开始体系结构用户手册概述Architecture5分钟搞懂Jenkins分布式架构
总结

  以上就是本篇博文的全部内容,可以发现,Jenkins的部署与使用过程并不复杂,我们本篇博客对其进行了详细的介绍并对Jenkins的原理进行了详细的分析。相信读完本篇博客,各位读者一定对Jenkins有了更深的了解。

标签:

Jenkins部署、使用与原理分析由讯客互联手机栏目发布,感谢您对讯客互联的认可,以及对我们原创作品以及文章的青睐,非常欢迎各位朋友分享到个人网站或者朋友圈,但转载请说明文章出处“Jenkins部署、使用与原理分析