Jenkins 功能分析与整理
文前说明
作为码农中的一员,需要不断的学习,我工作之余将一些分析总结和学习笔记写成博客与大家一起交流,也希望采用这种方式记录自己的学习之旅。
本文仅供学习交流使用,侵权必删。
不用于商业目的,转载请注明出处。
分析整理的版本是:Jenkins 2.7.4 版本。
Jenkins 的主要目标是监控软件开发流程,快速显示问题,保证开发人员以及相关人员省时省力提高开发效率。CI 系统在整个开发过程中的主要作用是控制:当系统在代码存储库中探测到修改时,它将运行构建的任务委托给构建过程本身。如果构建失败了,那么 CI 系统将通知相关人员,然后继续监视存储库。它的角色看起来是被动的;但它确能快速反映问题。
Jenkins 特点:
- Jenkins一切配置都可以在 web 界面上完成。有些配置如 MAVEN_HOME 和 Email,只需要配置一次,所有的项目就都能用。当然也可以通过修改 XML 进行配置。
- 支持 Maven 的模块 (Module),Jenkins 对 Maven 做了优化,因此它能自动识别 Module,每个 Module 可以配置成一个 job。相当灵活。
- 测试报告聚合,所有模块的测试报告都被聚合在一起,结果一目了然,使用其他 CI,这几乎是件不可能完成的任务。
- 构件指纹(artifact fingerprint),每次 build 的结果构件都被很好的自动管理,无需任何配置就可以方便的浏览下载。
环境的搭建
安装JDK
yum install java-1.6.0-openjdk-devel*
yum install java-1.7.0-openjdk-devel*
配置Git
- 设置 user.name 与 user.email。
- 生成密钥:ssh-keygen -t rsa -C “email”,Git服务器添加SSH Key。
安装maven
- 放在普通用户可以访问的目录下。
配置环境变量
- JAVA_HOME
- MAVEN_HOME
- CLASSPATH
- PATH
安装 Jenkins
- 官网下载 jenkins-2.7.4-1.1.noarch.rpm 包,进行安装。
rpm -ivh jenkins-2.7.4-1.1.noarch.rpm
- 安装完成后,在 /var/lib/jenkins 目录中可以看见 jenkins.war。执行 java -jar jenkins.war 安装解压,重启服务器。
注意:不重启不能访问首页。可以关闭 HTTP 访问方式,打开 HTTPS 访问方式。
java -jar jenkins.war -httpsPort=8443 -httpPort=-1
- 通过 service jenkins start 启动 Jenkins 服务。
- 修改 /etc/sysconfig/jenkins 配置文件中 JENKINS_USER 为 root。让 Jenkins 以 root 权限运行,如果后续 Jenkins 调用脚本不需要 root 权限可以不用修改。(修改前先停止 Jenkins 服务 service jenkins stop,修改后再启动)
不修改为 root 权限,后续脚本中如果涉及 root 目录或者权限的情况,将提示没有权限。
- 关闭防火墙,或者开放 8080 端口。
注意:不关闭防火墙,无法访问首页。
- 通过 http://localhost:8080 可以看到 Jenkins 首页。
- 登录首页要求输入密码,可以在文件 /var/lib/jenkins/secrets/initialAdminPassword 中查看到。
- 输入后提示创建系统管理员用户,创建后即可登录。
- Configure Global Security → 访问控制 → 安全域
- 可以设置允许用户注册
- 授权策略可以选择
序号 | 授权策略 |
---|---|
1 | 任何用户可以做任何事(没有任何限制),包括为登录的用户也可以做相关操作。 |
2 | 登录用户可以做任何事(登陆后的用户都拥有管理员的权限) |
3 | 遗留模式,登录的用户只有查看的权限(除管理员以外)。 |
4 | 安全矩阵,统一配置授权策略。 |
5 | 项目矩阵授权策略,跟安全矩阵配置完全相同,唯一区别在于可以在Job的配置页面再次配置。(选择Job → General → 启用项目安全) |
Jenkins 实现持续集成相关配置
JDK 相关配置
- Global configure Tools
配置 JDK 安装目录(JAVA_HOME)
JDK 配置成功的情况下,修改 JDK 路径,通过界面修改,重启 Jenkins,可能存在无效的情况。可以直接修改 config.xml 配置文件中的 JDK 路径,再重启 Jenkins 后生效。推荐使用 1.7 版本,因为某些插件需要 JDK1.7 的支持,比如:Monitoring 插件。config.xml 在 /var/lib/jenkins 目录下。JDK 选择自动下载,会出现卡死状态,是因为 Jenkins 在未发现 JDK 的情况下,会自动下载,但是 Oracle 对程序自动下载做了限制,会导致下载失败。
Git 相关配置
- 系统管理 → 管理插件 → 可选插件选择 Git plugin 进行 git 插件安装。
- 系统管理 → 系统设置 → Git plugin(Git plugin插件安装后才有)
配置 Global Config user.name Value 与 Global Config user.email Value。 - 在系统中生成访问 Git 的密钥文件。
- 拷贝生成的密钥文件 id_rsa 和 id_rsa.pub 至 /var/lib/jenkins/.ssh 目录下,并且通过 chown jenkins:jenkins 设置为 jenkins 权限。
注意:不拷贝至 /var/lib/jenkins/.ssh 目录下也可以,但是密钥文件所在目录必须有 jenkins 访问权限。
-
Credentials
- 创建密钥,Scope 选择 Global。
- username 填写 git 登录名称。
- private key 选择 From a file on Jenkins master,填写 /var/lib/jenkins/.ssh/id_rsa。
- passphrase 填写 git 密码。
-
Global configure Tools
配置GIT的执行文件目录(/usr/bin/git)。
Maven 相关配置
- 系统管理 → 系统设置 → 全局属性
- 勾选 Environment variables。
- 添加键:MAVEN_HOME,值 maven 的安装目录。
- 添加键:PATH,值 $PATH:$MAVEN_HOME/bin。
注意:必须配置,否则 Jenkins 运行脚本的环境变量中,无法加载maven目录。进行过以下尝试:
序号 | 描述 |
---|---|
1 | 修改 etc/bashrc 文件,增加环境变量,Jenkins 运行无法获取 MAVEN_HOME。 |
2 | 修改 etc/profile 文件,增加环境变量,Jenkins运行无法获取 MAVEN_HOME。 |
3 | 修改 etc/passwd 文件中 jenkins 用户权限,Jenkins运行无法获取 MAVEN_HOME。 |
4 | Jenkins 以 root 权限运行,Jenkins 运行无法获取 MAVEN_HOME。 |
5 | 将脚本放到 /var/lib/jenkins 目录下,Jenkins运行无法获取 MAVEN_HOME。 |
- Global configure Tools
- Maven Configuraction,配置settings.xml 所在路径。
- 配置 Maven 安装目录(Maven安装目录需要放在 jenkins 可以访问的目录,否则会有警告提示)。
构建项目
- 新建 → 构建一个自由风格的软件项目
- 项目名称填写
- 源码管理 → Git → Repositories,填写 Repository URL,密钥选择之前创建的密钥。
- Branches to build 中填写 Git 下载分支,可添加多个。(例如:*/develop)
- 构建触发器 → Poll SCM,定时轮询(查看 Git 是否有更新内容)。(例如 H/5 * * * *,每 5 分钟)。
- 构建 → Execute shell → Command,可以添加 Git 下载代码后的脚本操作。
- 创建项目完成后,可以在 My Vews 视图中看到。点击表格最后一列的构建图标,可以进行项目构建。
远程登录执行 shell
-
下载安装 Publish over SSH 插件。
-
系统管理 → 系统设置 → publish over ssh。
- 填写 Passphrase:远程登录密码。
- SSH servers→Name:定义一个 SSH 名称。
- SSH servers→Hostname:远程 IP 地址。
- SSH servers→Username:登录名。
- SSH servers→Directory:远程目录(也是远程机的根目录)。
- 填写完成可以通过 Test Configuration 进行连接测试。
-
构建项目中应用
- 勾选构建环境 → Send files or execute commands over SSH after the build runs
- SSH Publishers → SSH Server Name,选择上一步中创建的 SSH 服务名称。
-
SSH Publishers → Transfers
- Transfer Set Source files:发送到远程的文件在本地相对于工作空间的相对路径
(例如:工作空间 /var/lib/jenkins/workspace/foo/,填写target/*.zip,绝对路径就是 /var/lib/jenkins/workspace/foo/target/*.zip),可以多个,默认,号隔开。 - Remove prefix:移除目录,是针对 Transfer Set Source files 中定义的目录,但是却作用于远程目录。填写 target,意思是将 target/*.zip 中的 target 去掉,改为 *.zip。然后作用于上一步的远程目录上,比如远程目录是 /root,那么绝对路径就是 /root/*.zip。
- Remove directory:远程目录,相对于远程目录的相对路径。不填写就与远程目录一致。
- Exec command:远程执行的 shell 命令。
- Jenkins内置环境变量:
- Transfer Set Source files:发送到远程的文件在本地相对于工作空间的相对路径
变量名称 | 含义 | 返回示例 |
---|---|---|
BUILD_NUMBER | 构建任务的编号 | 6 |
BUILD_ID | 构建任务的ID | 6(1.597版本后,与BUILD_NUMBER相同) |
BUILD_DISPLAY_NAME | 构建任务显示名称 | #6 |
JOB_NAME | 构建项目名称 | bar/foo |
JOB_BASE_NAME | 构建最底层项目名称 | foo |
BUILD_TAG | 构建任务标签 | jenkins-${JOB_NAME}-${BUILD_NUMBER} jenkins-bar/foo-6 |
NODE_NAME | 是构建在宿主上,则master,节点上则名称 | master或者节点名称 |
NODE_LABELS | 节点分配表 | master或者节点分配表(空格隔开) |
WORKSPACE | 工作空间 | /var/lib/jenkins/workspace/foot/ |
JENKINS_HOME | Jenkins 安装目录 | /var/lib/jenkins/ |
JENKINS_URL | Jenkins 主页 | http://server:port/ |
BUILD_URL | 构建任务地址 | http://server:port/jenkins/job/foo/6/ |
JOB_URL | 构建项目地址 | http://server:port/jenkins/job/foo/ |
EXECUTOR_NUMBER | 构建状态 | 0:正在执行,1:没有执行 |
这些环境变量可以在 Shell 或 Batch 脚本中被使用,以 JOB_NAME 环境变量为例:
序号 | 说明 |
---|---|
1 | 在 Shell 中:$JOB_NAME。 |
2 | 在 Batch 中:%JOB_NAME%。 |
3 | 在 Ant 插件中:$JOB_NAME。 |
4 | 在 Ant 的 build.xml 中:${JOB_NAME}。 |
5 | 在 Maven 的 pom 中使用:${env.JOB_NAME},Maven 中引入环境变量的值。 引入 pom 中的变量通过 project.*,引入 settings.xml 中的变量,用settings.*。 |
- SSH Publishers → Transfers → 高级
- Exclude files:排除的文件(传输目录的时候排除,可以使用通配符)。
- Pattern separator:分隔符,设置 Transfer Set Source files 的分隔符,设置了上面也需要改。
- No default exclude:禁止默认的排除规则。(默认排除 .svn .git 等等文件)。
- Make empty dirs:创建空的文件夹。(默认当文件存在时,才创建文件夹存放),勾选后,无论存不存在都创建目录文件夹。
- Flatten files:只传递文件,不传递目录(这里指本地,不包含远程服务器端)。
- Remote directory is a date format:远程目录创建带日期的目录。(需要在 Remove directory 中配置格式)。
- Exec timeout(ms):脚本运行超时时间(毫秒)。
- Exec in pty:模拟一个终端执行脚本。
执行 Jenkins CLI 命令
- 系统管理 → Configure Global Security → 启用安全
- TCP port for JNLP agents 选择指定端口,定义一个端口。选择的随机端口,执行命令也会提示端口未设置的错误。
- 具体命令执行方式,可以在系统管理 → jenkins CLI 中查看。
- 每一句执行命令的最后都需要跟 --username 用户名和 --password 密码,参数。
邮件通知配置
-
系统管理 → 系统设置 → 邮件通知
- SMTP 服务器:配置 SMTP 服务器。(不填默认本地运行服务器)
- 用户默认邮件后缀:注册用户邮件只需填写用户名即可,后缀会加该后缀,如果填写,则会覆盖该配置。
- SMTP 端口:填写 SMTP 端口。
- Test configuration:可以进行邮件测试。
-
构建的项目中 → 构建后操作 → E-mail Notification
- Recipients:邮件列表,多人用英文逗号间隔。
监控
- 构建状态
颜色 | 状态 |
---|---|
蓝色 | 完成构建,被认为是稳定构建。 |
黄色 | 完成构建,被认为是不稳定的构建。 |
红色 | 构建失败。 |
灰色 | 禁用了构建。 |
- 构建稳定性
图例可以在:http://localhost:8080/legend 中查看。
插件相关
- Email Extension Plugin
可以扩展邮件功能。比如可以自定义邮件标题或内容的模版。
推荐模版:
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>${ENV, var="JOB_NAME"}-第${BUILD_NUMBER}次构建日志</title>
</head>
<body leftmargin="8" marginwidth="0" topmargin="8" marginheight="4" offset="0">
<table width="95%" cellpadding="0" cellspacing="0" style="font-size: 11pt; font-family: Tahoma, Arial, Helvetica, sans-serif">
<tr>
<td>(本邮件是程序自动下发的,请勿回复!)</td>
</tr>
<tr>
<td><h2><font color="#0000FF">构建结果 - ${BUILD_STATUS}</font></h2></td>
</tr>
<tr>
<td><br /> <b><font color="#0B610B">构建信息</font></b> <hr size="2" width="100%" align="center" /></td>
</tr>
<tr>
<td>
<ul>
<li>项目名称 : ${PROJECT_NAME}</li>
<li>构建编号 : 第${BUILD_NUMBER}次构建</li>
<li>SVN 版本: ${SVN_REVISION}</li>
<li>触发原因: ${CAUSE}</li>
<li>构建日志: <a href="${BUILD_URL}console">${BUILD_URL}console</a></li>
<li>构建 Url : <a href="${BUILD_URL}">${BUILD_URL}</a></li>
<li>工作目录 : <a href="${PROJECT_URL}ws">${PROJECT_URL}ws</a></li>
<li>项目 Url : <a href="${PROJECT_URL}">${PROJECT_URL}</a></li>
</ul>
</td>
</tr>
<tr>
<td>
<b><font color="#0B610B">Changes Since Last Successful Build:</font></b>
<hr size="2" width="100%" align="center" />
</td>
</tr>
<tr>
<td>
<ul>
<li>历史变更记录 : <a href="${PROJECT_URL}changes">${PROJECT_URL}changes</a></li>
</ul> ${CHANGES_SINCE_LAST_SUCCESS,reverse=true, format="Changes for Build #%n:
<br />%c<br />",showPaths=true,changesFormat="<pre>[%a]<br />%m</pre>",pathFormat=" %p"} </td>
</tr>
<tr>
<td>
<b>Failed Test Results</b> <hr size="2" width="100%" align="center" />
</td>
</tr>
<tr>
<td>
<pre style="font-size: 11pt; font-family: Tahoma, Arial, Helvetica, sans-serif">$FAILED_TESTS</pre> <br />
</td>
</tr>
<tr>
<td><b><font color="#0B610B">构建日志 (最后 100行):</font></b> <hr size="2" width="100%" align="center" /></td>
</tr> <!-- <tr> <td>Test Logs (if test has ran): <a href="${PROJECT_URL}ws/TestResult/archive_logs/Log-Build-${BUILD_NUMBER}.zip">${PROJECT_URL}/ws/TestResult/archive_logs/Log-Build-${BUILD_NUMBER}.zip</a> <br /> <br /> </td> </tr> -->
<tr>
<td>
<textarea cols="80" rows="30" readonly="readonly" style="font-family: Courier New">${BUILD_LOG, maxLines=100}</textarea>
</td>
</tr>
</table>
</body>
</html>
-
Parameterized Trigger Plugin
可以根据已经完成构建的结果,触发新Job或者传递参数(参数可以配置成 properties 文件)。具体配置在构建后操作中。 -
Publish Over FTP Plugin 与 FTP publisher Plugin
可以将构建的产物(例如:Jar)发布到 FTP 中去。公用配置在系统设置中,具体配置在构建后操作中。需要配置 IP、用户名、密码、端口、服务器目录、超时时间等。 -
Jenkins Job Configuration History Plugin
可以记录配置更改。(用户、更改时间、更改内容等)。
忘记密码补救
- 修改 JENKINS_HOME/users 目录中 config.xml 文件中 passwordHash 标签中内容为:
#jbcrypt:$2a$10$DdaWzN64JgUtLdvxWIflcuQu2fgrrMSAMabF5TSrGK5nXitqK9ZMS
上面内容是密码:111111 的加密内容。修改后再登录即可。
分布式构建
可以让同一套代码,在不同的环境(Windows,Linux 系统)中,编译与测试等。最终将构建的产物自动拷贝到主节点。
- 系统管理 → 管理节点 → 新建节点
注意:不建议使用标点符号和中文(中文命名没有问题,但 Job 中无法引用)
可以新建节点或从已存在的节点中复制一份配置(如果存在节点才会显示)
节点配置项如下:
- 节点名称。
- 节点描述。
- 最大同时构建数量(必须为数字)。
- 节点目录。
注意:如果目录不存在,会自动创建目录。你必须对该目录有读写权限,不然会报错:
hudson.util.IOException2: Failed to copy xxxx
-
Labels:标记(又叫做标签)用来对多节点分组,标记之间用空格分隔。
-
启动方法。
- Launch agent via Java web Start。
通过 Java Web Start 连接节点 (适用于所有支持Java程序的系统)。 - Launch slave via execution of command on the Master
通过主节点的控制台连接节点,可以执行 shell 脚本,但是脚本需要自己写。(为了方便节点升级而提供的方式)。 - Let Jenkins control this Windows slave as a Windows service
让 Jenkins 节点添加到 Windows 服务中。采用这种运行方式,那么这个系统不能登录任何用户。
- Launch agent via Java web Start。
-
Availability
- Keep this slave on-line as much as possible
尽可能的保持节点在线。 - Take this slave on-line according to a schedule
根据时间表在线。Scheduled Uptime:超过任务时间后延迟多少分钟离线。如果此数值大于在线总时间(单位:分),就会一直保持在线(必须为数字)。 - Take this slave on-line when in demand and off-line when idle
让 Jenkins 根据需求自动连接或者离线。In demand delay:如果有Job需要在此节点构建,需要在任务队列等待多长时间才会进入任务状态进行构建(必须为数字)。Idle delay:多少分钟内如果没有Job需要构建就离线(必须为数字)。
- Keep this slave on-line as much as possible
-
Environment variables
配置节点的环境变量(与主节点相同)。 -
Tool Locations
配置工具,这里是节点特殊配置,会覆盖主节点的工具配置,好处是在不更改Job配置的情况下,不同环境(如:Windows 和 Linux)Job 配置通用。
迁移和备份
只需要迁移或者备份 JENKINS_HOME 中内容即可。