微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!
Jenkins : 安装 master 和 slave
目录安装 master安装 slave设置 master 与 slave 的通信方式添加 slave 配置在 salve 上安装 jre安装并配置 Jenkins salveJenkins 是一个可扩展的持续集成引擎。主要用于持续、自动地构建、测试软件项目。本文介绍在 windows 平台上安装 Jenkins master 和 slave。安装 master请从 Jenkins 的官网下载安装包,直接运行,一路 "next" 就可以了。安装包执行完成后会启动你机器上默认的浏览器进行初始化配置和基本插件的安装。第一步是进行安全性验证:需要把安装目录下一个文件中的密码输入到 UI 中,按照 UI 中的说明填入密码,然后继续。第二步是选择插件进行安装:最好安装 Jenkins 建议安装的插件,点击第一个大大的按钮继续。接下来是安装这些插件,这个过程完全是在线安装,一般情况下会比较慢。插件安装完成后进入第三步:设置管理员账号,点击 "Save and Finish"。下个界面会提示 Jenkins 已经完成安装,点击 "Start using Jenkins" 进入 Jenkins 的主界面:OK,master 已经安装完成了!安装 slave设置 master 与 slave 的通信方式进入 Jenkins 的全局安全配置界面(Jenkins->Manage Jenkins->Configure Global Security):选择 "Enable security",TCP 的端口号选择随机就可以了。添加 slave 配置在 Jenkins 上添加 slave 节点的配置(Jenkins->Manage Jenkins->Manage Nodes):点击 "New Node":输入 slave 节点的名称,并选择 "Permanent Agent" 类型,点击 OK 后进入详细信息的设置界面:简单解释一下上面的配置:Name:该节点的名字。Description:说明这个节点的用途。# of executors:允许在这个节点上并发执行任务的数量,一般设置为 cpu 支持的线程数。Remote root directory:节点上 Jenkins 的根目录。Labels:分配给这个节点的标签。Usage:节点的使用策略。Launch method:启动 agent 的方式,对于 windows 平台,最好选择 "Launch agent via Java Web Start"。Availability:Jenkins 控制 slave 是否在线的策略。保存上面的配置,接下来去 salve 上完成安装和配置。在 salve 上安装 jre到 Oracle 官网下载最新的 jre 安装包并在 salve 上安装。安装并配置 Jenkins salve下面的操作默认都是在 salve 上进行。首先在 C 盘根目录下创建目录 jenkinsagent。接着在浏览器中登录前面创建的 Jenkins,并打开刚才创建的节点:点击上图中的 "Launch" 按钮,在浏览器的提示下把一个叫 slave-agent.jnlp 的文件保存到本地。然后以管理员的权限启动命令行, 执行 slave-agent.jnlp 文件,最终会启动一个小程序:上图中的 "Connected" 说明 slave 和 master 已经建立了连接。但是我们希望把 slave-agent 程序安装成 Windows Service,这样以后 slave 机器重新启动后就能自动连接 master。在上面的 File 菜单中点击 "Install as a service",完成安装后上面的小程序会自动关闭,一个 Windows Service 被创建:好了,刷新一下 salve 的页面:至此,一个 master 与一个 slave 组成的 Jenkins 系统已经搭建起来了。
Jenkins: 执行 PowerShell 命令
Jenkins 默认是不支持执行 PowerShell 命令的,需要安装插件才能完成这样的任务。本文将介绍 Jenkins PoserShell 插件的基本用法和常见问题。安装 PowerShell 插件在 Jenkins->Plugin Manager 界面中选择 "Available" 标签页,输入 "powershell" 进行过滤:选则 "PowerShell plugin",然后点击 "Install without restart" 按钮。安装完成后就可添加 PowerShell 类型的 build step 了:在 build step 中执行 PowerShell 命令我们通过 PowerShell 来执行一个简单的任务:检查 agent 的操作系统版本和 PowerShell 版本。先创建一个 Freestyle 类型的 job,然后添加一个 "Windows PowerShell" 类型的 build step,并添加下面的 PowerShell 命令:Write-HostWrite-Host "Windows version info:"[System.Environment]::OSVersion.VersionWrite-HostWrite-Host "PowerShell version info:"$host看起来像这个样子:保存 job,然后运行它。执行成功后查看运行日志:上图中的第一行说明了 Jenkins 是如何执行 PowerShell 命令的,其实就是把我们写的命令打包到一个 PowerShell 脚本文件中,然后在 agent 上调用 powershell.exe 执行这个脚本。第二个和第三个红框中则是输出的系统版本和 PowerShell 版本信息。让 build step 失败接下来我们发现,无论怎么执行 PowerShell 命令,build step 的结束状态都是 "成功"(包括一些命令执行失败的情况)!这是不科学的,因为当命令执行失败或是满足一些条件时,我们希望 build step 的结束状态是 "失败"。后续的 build step 根据前面 step 的结束状态决定是否执行。默认情况下之所以 build step 不会失败,是因为 PowerShell 执行的过程中没有执行 exit 调用!这就导致 Jenkins 无法判断执行的命令是否成功退出,默认就认为都是成功的啦。所以要完善这里的逻辑就要求我们一定要在脚本中实现自己的 exit 逻辑:判断脚本执行成功时调用 exit 0;判断脚本执行失败时调用 exit 1(当然你可以根据自己的需要返回其他整数)。作为 demo,我们编辑上面的 job 并在最后一行添加 exit 1,保存后执行:终于可以让 build step 失败了!Run task as admin在 Windows 类型的 agent 上执行的任务,有些需要 admin 权限。那么如何以 admin 权限执行 PowerShell 的命令呢?其实这是由 Jenkins agent 程序运行的权限决定的。我们在 agent 上启动 Jenkins 程序的时候有大概三种选择,直接运行或者以 run as admin 的方式运行再或者以 Windows Service 方式运行的。如果以后两种方式运行 Jenkins agent 程序,那么所有的 task 也会以 admin 的权限运行。在 pipeline 中执行 PowerShell 命令毫无疑问,pipeline 将会被越来越多的使用。我们当然应当具备在 pipeline 中执行 PowerShell 命令的能力。还好,Jenkins 刚刚支持了这个功能。创建一个 pipeline 类型的 job,输入下面的代码:node {powershell 'Write-Output "Hello, world!";'}然后保存并运行。遗憾的是,这个功能还不完美:在笔者的环境中,输出的日志总带有一点乱码,具体原因不明。猜测是 pipeline 功能对 PowerShell 插件的支持还有小问题。总结到目前为止,Jenkins 已经实现了对 PowerShell 的主流支持。期待 Jenkins 逐步的完善还存在的一些小问题,毕竟 MS 已经开始用 PowerShell 取代 bat 了。
Jenkins: 配置信息变更历史
像 Jenkins 这样的系统,使用的过程就是配置文件变更的过程。如果能够对配置文件的变更进行跟踪管理,将极大的提高系统的可用性。Job Configuration History 插件就是这么一款实用而精巧的组件。很显然,相对于它的功能而言,它的名字实在是太低调了。因为它不仅能处理 Job Configuration 的变更历史,还能够处理系统级别的配置变更历史。安装 Job Configuration History 插件在 Jenkins->Plugin Manager 界面中选择 "Available" 标签页,输入 "Job Configuration History" 进行过滤:点击安装并重启的按钮就可以啦!Overview 视图安装完成后,主页的菜单项中已经添加了 "Job Config History" 菜单:点击该菜单进入插件的 Overview 视图:在这里我们可以总览系统中的配置变更(其实是系统配置和所有根及项目的配置),并且可以通过左上方的菜单项或者是正上方的链接过滤出 "系统配置"、"Job 配置"、"创建 Job 的配置" 以及 "删除 Job 的配置" 的历史记录。并且可以查看历史记录中配置文件的内容。Agent Config History 视图下面我们通过 Agent Config History 视图来介绍该插件对配置文件历史数据的强大处理能力。选择并进入一个 Agent 的信息界面:选择 "Agent Config History":我们可以选择不同的配置版本进行比较,或者是用历史版本覆盖当前的版本。我们选择不同的版本,然后点击 "Show Diffs" 按钮:上图主要是对比不同版本配置文件的差异,但是看到这么多的按钮确实让人有点不知所措。它们的操作为:Prev:左右两个文件都更新为前一个版本(时间上比当前版本更早的一个版本)。Next:左右两个文件都更新为下一个版本(时间上比当前版本更晚的一个版本)。左 Shrink Diff:左边文件更新为时间上比当前版本更晚的一个版本。左 Expand Diff:左边文件更新为时间上比当前版本更早的一个版本。右 Shrink Diff:右边文件更新为时间上比当前版本更早的一个版本。右 Expand Diff:右边文件更新为时间上比当前版本更晚的一个版本。Restore this configuration:用某个历史版本的配置信息覆盖当前的配置信息。乍一看让人倍感凌乱的按钮,在细看之下发现每个按钮的功能都不可替代。它们组合在一起可以让我们方便的对比文件的不同版本。并且可以轻松的把配置回滚到某个历史时刻。Job Config History 视图和 Agent Config History 视图类似,Job Config History 视图提供了 Job 配置的历史版本管理界面。在 Job 的信息界面点击 “Job Config History”即可打开,具体功能和使用方法和 Agent Config History 视图相同,因而不再赘述。对于 Job Config,Job Configuration History 插件提供的另一个有用功能是在 Build 的历史记录中显示配置文件的变化记录:从上图中我们可以清楚的看到具体某次 Build 时配置文件发生了变化,点击小图标还能看到配置文件变化的具体内容:这能够极大的提高我们调试配置文件时的生产力,尤其是当错误发生时,我们可以立即定位是哪些配置的变化导致 Build 失败了。实现原理Job Configuration History 是一款非常实用的插件,我们不禁会好奇,它是如何实现的呢?答案可能会让人有点失望,因为它的思路很简单:当配置发生变化时,就把旧的配置文件复制一份存起来!旧配置文件的存放路径默认就在 Jenkins 安装目录下的 config-history 目录中:不管是系统级别配置的历史记录,还是 Job、Agent 配置的历史记录,全都被按照一定的规则组织放置在这个目录下。总结Job Configuration History 插件兼具低调、实用和设计简单等优点,实为居家、旅行之必备良品!相信每一个 Jenkins 管理员都会对之爱不释手。
Jenkins : 邮件通知
目录全局配置为项目添加邮件通知邮件模板Pipeline 支持总结Jenkins 内置了 Mailer 插件用于发送邮件通知,但是 Mailer 插件的功能比较简单,无法按照用户的需求进行邮件的定制。Email Extension 是 Jenkins 默认推荐安装的一款功能强大的邮件插件,使用它几乎可以定制邮件的任何部分。本文将结合笔者的使用经验介绍 Email Extension 插件的使用方法。全局配置和其它的插件一样,Email Extension 插件的全局配置也是在 Jenkins -> Manage Jenkins -> Configure System 中。具体的配置项非常多,下面介绍几个比较基本且重要的配置项。SMTP server设置 smtp server 的名称或 IP 地址。邮件类型可以选择 HTML 格式的邮件或者是纯文本格式的邮件:默认标题默认的标题为:$PROJECT_NAME - Build # $BUILD_NUMBER - $BUILD_STATUS!显示项目名称,Build 号和 Build 结果。如果没有其它的要求,这个标题也算是简单明了啊!默认的邮件内容默认的邮件内容为:$PROJECT_NAME - Build # $BUILD_NUMBER - $BUILD_STATUS:Check console output at $BUILD_URL to view the results.一般我们会通过邮件模板等功能实现一个完整的邮件内容,所以可以忽略这个默认的内容。默认的触发条件作为一种通知方式,在什么条件下触发邮件通知是极为重要的。Email Extension 插件支持的触发器类型是很丰富的:个人觉得这里的默认设置没那么重要,因为每个项目的情况都是不一样的,所以最终都需要在项目上进行设置。而项目上的设置会覆盖这里的默认设置。为项目添加邮件通知在项目的配置项中添加 Post-build Actions,选择 "Editable Email Notification":然后就可以进行详细的设置了:下面介绍一下比较重要的配置项。关闭邮件通知这个选项在维护项目时非常有用,可以临时关闭邮件通知,避免把不必要的邮件发送给用户。收件人列表收件人邮件地址,多于一个时需要使用逗号分隔。邮件类型和全局设置中的邮件类型一样,没有特殊要求的话保留默认类型即可。此时会应用全局设置中的类型。默认标题标题的默认内容为:$DEFAULT_SUBJECT,也就是在全局配置中设置的内容。如果觉着不爽可以进行深度定制,也就是使用系统提供的变量进行拼凑。至于能拿到什么变量,可以参考 Conten Token Reference 的内容:点击问号图标就会列出所有可用的变量,实在是太多了,就不贴出来占篇幅了!默认内容默认内容为:$DEFAULT_CONTENT,也是在全局配置中设置的内容。和默认标题一样,你也可以自行定义。但多数情况下都会使用后面介绍的邮件模板,这里就不啰嗦了。附件有时把一些 Build 产物作为通知邮件的附件是很有用的。这里我们也可以轻松实现:我们可以指定文件的名称,也可以使用通配符。除了 Build 的产物,Build 的日志也是极其重要的信息。它可以帮助我们快速的调查 Build 过程中的各种问题,所以也应该把 Build 日志添加为邮件的附件:测试一下,收到的邮件带了两个附件:邮件模板邮件的内容可以包含大量的信息,如果每个项目中都自己组织这些信息会费时费力。使用邮件的模板功能可以极大的提高生产力!Email Extension 插件支持两种类型的邮件模板,分别是 Jelly 模板和 Groovy 模板。当前的现状是 Groovy 模板正在逐步的取代 Jelly 模板。但是两种模板的设置和使用方式基本一样,我们以 Groovy 模板为例进行介绍。在 Email Extension 插件的官方文档中可以找到模板的下载地址。笔者以下载的 groovy-html.template 文件为例进行说明。首先是安装邮件模板,其实就是把模板文件复制到 Jenkins 安装目录下的 email-templates 目录中,如果该目录不存在就先创建它。接着我们可以测试一下安装的模板是否能正常工作。打开一个添加了 "Editable Email Notification" 的项目,你会发现在左边的菜单中多了一项 "Email Template Testing":选择这个菜单项并且输入刚才安装的模板名称:点击 "Go" 按钮,一个预览的邮件内容就会出现在下面的空白处。最后我们需要在邮件通知的配置中应用这个模板。其实就是设置 Default Content 为:${SCRIPT, template="groovy-html.template"}好了,邮件的模板设置已经完成,赶快触发个 Build 看看结果吧!Pipeline 支持Email Extension 插件支持 pipeline, 下面的代码可以很好的工作:stage('test') {steps {echo 'hello'// error 'build failed'}post {success {emailext (subject: "SUCCESSFUL: Job '${env.JOB_NAME} [${env.BUILD_NUMBER}]'",to: "[email protected]",body: """<p>SUCCESSFUL: Job '${env.JOB_NAME} [${env.BUILD_NUMBER}]':</p><p>Check console output at &QUOT;<a href='${env.BUILD_URL}'>${env.JOB_NAME} [${env.BUILD_NUMBER}]</a>&QUOT;</p>""",recipientProviders: [[$class: 'DevelopersRecipientProvider']])}failure {emailext (subject: "FAILED: Job '${env.JOB_NAME} [${env.BUILD_NUMBER}]'",to: "[email protected]",body: """<p>FAILED: Job '${env.JOB_NAME} [${env.BUILD_NUMBER}]':</p><p>Check console output at &QUOT;<a href='${env.BUILD_URL}'>${env.JOB_NAME} [${env.BUILD_NUMBER}]</a>&QUOT;</p>""",recipientProviders: [[$class: 'DevelopersRecipientProvider']])}}}上面的代码在 stage 执行成功或者失败的情况下发送邮件。但邮件的内容只是简单的纯文本或这是 HTML 格式的文本。笔者尝试在 pipeline 代码中使用邮件模板的功能,但不管是 Jelly 模板还是 Groovy 模板都不能正常工作,所以这里还有待完善的功能。总结Email Extension 是一款可定制性强、功能全面的 Jenkins 邮件通知插件。随着 pipeline 日渐成为主流的持续集成方式,希望能 Email Extension 也能紧跟趋势提供对 pipeline 更好的支持。
Jenkins 在声明式 pipeline 中并行执行任务
在持续集成的过程中,并行的执行那些没有依赖关系的任务可以缩短整个执行过程。Jenkins 的 pipeline 功能支持我们用代码来配置持续集成的过程。本文将介绍在 Jenkins 中使用声明式 pipeline 语法完成任务的并行执行。Stage 内的并行执行在声明式 pipeline 版本 1.2 之前,这是唯一的并行方式,我们看一下代码的写法:stage('run-parallel') {steps {parallel(a: {echo "task 1"},b: {echo "task 2"})}}在同一个 stage 内部,我们可以并行的执行多个 step。代码中的 step a 和 b 会在同一台 agent 上并行执行。但是我们可以看到,这种并行执行的方式具有很大的局限性。首先因为 agent 只能在 stage 上设置,所以这种方式不能在不同的 agent 上执行并行的任务。其次并行执行的粒度为 step 级别,执行点小任务还行,但这样的粒度对设计持续集成的流程来说明显过小。所以,我们急需的是 stage 级别的并行执行能力。Stage 级别的并行执行在刚刚发布的声明式 pipeline 版本 1.2中,Jenkins 终于开始支持 stage 级别的并行执行:稍微有一点要求是你的 Jenkins 的版本要大于 2.7:下面的实例代码描述了如何执行 stage 级别的并行任务:pipeline {agent anystages {stage('Stage1') {agent { label "test1" }steps {timestamps {echo '这是第一个被执行的 stage.'sleep 5}}}stage('并行执行的 Stage') {parallel {stage('Stage2.1') {agent { label "test2" }steps {timestamps {echo "在 agent test2 上执行的并行任务 1."sleep 5echo "在 agent test2 上执行的并行任务 1 结束."}}}stage('Stage2.2') {agent { label "test3" }steps {timestamps {echo "在 agent test3 上执行的并行任务 2."sleep 10echo "在 agent test3 上执行的并行任务 2 结束."}}}}}stage('Stage3') {agent { label "test1" }steps {timestamps {echo '这是最后一个被执行的 stage.'}}}}}上面的代码描述的执行顺序是 Stage1, 并行执行的 Stage 和 Stage3。其中并行执行的 Stage 包含两个并行执行的子 Stage,分别是 Stage2.1 和 Stage2.2,并且这两个 Stage 被指定到了不同的 agent。为了能够在日志中显示步骤执行的时间,我们使用了 Timestamper 插件。所有在 timestamps {} 块中的命令都会在日志中显示执行时间。好了,现在执行上面的配置,然后查看执行日志:从日志中可看到,Stage.21 和 Stage2.2 中的任务在执行时间上是重叠的,并且运行它们的 agent 也不一样。总结Stage 级别的并行任务处理是非常有用的功能,尤其是在我们设计持续集成的流程时。让一些可以并行的任务(比如不同平台上的自动测试)同时执行可以明显缩短整个过程耗费的时间,从而提升持续执行的效能。
Jenkins pipeline 并行执行任务流
笔者在《Jenkins 在声明式 pipeline 中并行执行任务》一文中介绍了如何在声明式 pipeline 中执行并行的任务。前一段时间,Jenkins 发布了 1.3 版的声明式 pipeline(declarative pipeline),这个版本继续增强了并行执行任务的能力:并行执行的任务可以是个任务流。官方称这一功能为 "sequential stages",本文将解释 "sequential stages",并通过 demo 演示其用法。之前的任务并行方式就是笔者在《Jenkins 在声明式 pipeline 中并行执行任务》一文中介绍的方式,我们在一个 stage 中设置多个子 stage 并行执行:stages {stage('Stage1') {...}stage('并行执行的 Stage') {parallel {stage('Stage2.1') {agent { label "test1" }steps {echo "在 agent test1 上执行的并行任务 1."}}stage('Stage2.2') {agent { label "test2" }steps {echo "在 agent test2 上执行的并行任务 2."}}}}stage('Stage3') {...}}上面代码中任务的执行过程如下图所示:任务 2.1 和任务 2.2 并行执行。并行执行任务流过去并行执行的任务都是单个的,但实际情况中我们还需要任务流级别的并行能力,如下图所示:上图中显示有两条任务流在并行的执行,我们可以通过下面的代码来实现:pipeline {agent nonestages {stage('Stage1') {agent { label "master" }steps {timestamps {echo '这是第一个被执行的 stage.'sleep 5}}}stage("build, deploy and test on Windows and Linux") {parallel {stage("windows") {agent {label "master"}stages {stage("build") {steps {timestamps {echo "build on windows."}}}stage("deploy") {steps {timestamps {echo "deploy on windows."}}}stage("test") {steps {timestamps {echo "test on windows."sleep 5}}}}}stage("linux") {agent {label "worker1"}stages {stage("build") {steps {timestamps {echo "build on linux."}}}stage("deploy") {steps {timestamps {echo "deploy on linux."}}}stage("test") {steps {timestamps {echo "test on linux."sleep 5}}}}}}}stage('Stage3') {agent { label "worker1" }steps {timestamps {echo '这是最后一个被执行的 stage.'}}}}}为了显示任务的执行时间,笔者使用了 timestamper 插件。下图显示了笔者精简后的运行日志:红框中的内容说明我们的两个任务流是完全并行执行的。这就是 1.3 版的声明式 pipeline 中增加的 "sequential stages" 功能。总结如今 jenkins 对声明式 pipeline 中并行任务的执行支持的非常给力(虽然经历了一个稍显漫长的过程)。笔者在 2017 年初调研时发现声明式 pipeline 无法支持并行的任务,后来开始支持比较初级的并行任务,笔者在《Jenkins 在声明式 pipeline 中并行执行任务》一文中进行了介绍。到今年(2018) 7 月份声明式 pipeline 发布了版本 1.3,这个版本中开始支持本文介绍的任务流级别的并行。至此笔者认为 jenkins 声明式 pipeline 中任务的并行执行功能已经比较完善了。参考:Sequential Stages (declarative pipeline 1.3 的新功能)
通过 Ansible 创建 Jenkins Server
创建 CI 流程的第一件事应该是安装 CI 工具,本文以最常见的 Jenkins 为例,介绍如何使用 Ansible 自动安装 Jenkins Server。说明:本文的演示环境为 ubuntu 16.04。Ansible roles(角色)Ansible 中除了 playbook,还有更高层级的抽象,称为 role(角色)。所谓的 role 其实就是把一些 playbook 组织成为一个更简洁、清晰的可重用对象。比如把安装 Jenkins Server 的 playbook 组织成为一个 role。感谢开源社区,当我们需要安装 Jenkins Server 的时候并不需要自己写一个对应的 role,直接使用大神们写好的就可以了。Ansible GalaxyAnsible Galaxy 是社区和分享 Ansible role 的地方。直接搜索 jenkins,由 geerlingguy 贡献的 jenkins role 是目前最受欢迎的:ansible-galaxy 命令通过 ansible-galaxy 命令可以把上面搜索到的 role 安装到本地:$ ansible-galaxy install geerlingguy.jenkins由于 geerlingguy.jenkins role 依赖 geerlingguy.java role,所以在安装 geerlingguy.jenkins role 的同时也安装了 geerlingguy.java role。默认的安装目录在当前用户家目录下的 .ansible/roles同时会安装其依赖的 geerlingguy.java role(能够自行处理依赖关系):了解 jenkins role 的基本配置我们安装的 geerlingguy.jenkins role 的主要配置文件为:~/.ansible/roles/geerlingguy.jenkins/defaults/main.yml。下面介绍一下其中的一些比较重要的配置项。jenkins_package_state: present安装的 jenkins 版本,present 表示仅安装系统默认包中的版本,如果需要最新版本的 jenkins,需要把 jenkins_package_state 设置为 latest。jenkins_hostname: localhost通过 http 协议访问 Jenkins 时使用的域名或主机名称,作为演示,设置为 localhost 就可以了。jenkins_home: /var/lib/jenkinsJenkins 的主目录。jenkins_http_port: 8080Jenkins 服务器监听的端口号。jenkins_url_prefix: ""如果不想通过域名或主机名称直接访问 Jenkins,可以设置 jenkins_url_prefix 变量。比如设置为 /jenkins,这样我们就需要通过下面的 URL 来访问 Jenkins server 了:http://localhost:8080/jenkinsjenkins_jar_location: /opt/jenkins-cli.jarJenkins CLI 程序的位置,该程序主要用来以命令行的方式与 Jenkins server 交互。jenkins_plugins: []指定在安装 Jenkins server 的同时安装的插件,默认是一个插件都不装的:如果需要安装插件,使用逗号分隔插件名称并写入到中括号中就可以了,下面是一个小 demo:[junit,greenballs,git]jenkins_plugins_state: present指定插件的版本,如果设置为 latest,就会保证所有的插件都是最新版本。jenkins_plugin_timeout: 30安装插件时的连接超时时间。需要注意安装插件时的超时问题,国内安装插件非常耗时,最好把 jenkins_plugin_timeout 设置的大些,不然经常会碰到 timeout 错误:jenkins_plugins_install_dependencies: true安装插件时是否安装其所依赖的插件。jenkins_admin_username: adminjenkins_admin_password: admin安装 Jenkins 时创建的管理员账号和密码。jenkins_java_options: "-Djenkins.install.runSetupWizard=false"可以通过 jenkins_java_options 来设置额外的 java 命令行参数。比如我们可以通过下面的配置来设置 Jenkings server 的时区为纽约:jenkins_java_options: "-Dorg.apache.commons.jelly.tags.fmt.timeZone=America/New_York"jenkins_version: "1.644"jenkins_pkg_url: "http://www.example.com"这两个配置是可选的,通过 jenkins_version 变量我们可以指定安装的 Jenkins 版本,这样每次都会安装相同的版本,当然必须是出现在 http://pkg.jenkins-ci.org/debian/ (Ubuntu)中的版本。如果你不想使用官方的包,可以通过 jenkins_pkg_url 指定自己的包。默认这两个选项是被注释掉的,也就是说会安装官方的包。jenkins_connection_delay: 5jenkins_connection_retries: 60启动后连接到 Jenkins 时需要等待的时间和次数,以验证 Jenkins 是否正在运行。等待的总时间=延迟*重试,因此默认情况下,这个角色在超时前将等待 300 秒。jenkins_init_changes:  - option: "JENKINS_ARGS"    value: "--prefix={{ jenkins_url_prefix }}"  - option: "JENKINS_JAVA_OPTIONS"    value: "{{ jenkins_java_options }}"修改 Jenkings 的初始脚本,默认的更改设置了配置的 URL 前缀,并为 Jenkins 的启动添加了配置的 Java 选项。如果要为 Jenkins 的初始化脚本设置其他选项,添加其他的 选项/值 就可以了。下面的配置与平台相关,所以 Ubuntu 相关的配置放在配置文件 ~/.ansible/roles/geerlingguy.jenkins/vars/Debian.yml 中:# For Debian (role default):__jenkins_repo_url: deb https://pkg.jenkins.io/debian binary/__jenkins_repo_key_url: https://pkg.jenkins.io/debian/jenkins.io.key默认安装的是 Jenkins 的最新版本,如果要安装稳定版本请设置为下面的配置:# For Debian/Ubuntu LTS:__jenkins_repo_url: deb http://pkg.jenkins-ci.org/debian-stable binary/__jenkins_repo_key_url: http://pkg.jenkins-ci.org/debian-stable/jenkins-ci.org.key先在目标机器上安装 curl由于在安装 Jenkins 的时候需要用到 curl 工具,所以有必要先安装该工具。具体的做法我们可以写一个简单 playbook 来实现,把下面的内容保存到文件 pb_curl.yml 文件中:---- hosts: jenkinsserversbecome: truebecome_user: roottasks:- name: install curl on Ubuntuapt:name: curlstate: 'latest'update_cache: no然后在 /etc/ansible/hosts 文件中添加一个组 jenkinsservers 来保存目标主机:[jenkinsservers]192.168.21.145最后执行命令在目标机器上安装 curl:$ ansible-playbook -u nick pb_curl.yml如果你还不熟悉 Ansible 及其 playbook,请参考笔者的《Ansible 简介》一文。安装 Jenkins下面我们创建一个非常简单的 playbook 文件 pb_jenkins.yml,其中引用已经安装好的 role 来完成 jenkins 的安装:---- hosts: jenkinsserversvars:jenkins_hostname: localhostroles:- role: geerlingguy.javabecome: yes- role: geerlingguy.jenkinsbecome: yes注意,playbook 中先配置了 geerlingguy.java 来安装 Jenkins 依赖的 java。执行下面的命令进行安装:$ ansible-playbook -u nick pb_jenkins.yml安装成功后,到目标机器上检查一下:Jenkins 服务器已经可以正常运行了,但此时只能通过 localhost 在本机访问。如果需要在局域网内访问,在配置文件中把 localhost 换成主机的 IP 就可以了。注意,Ansible 的命令是可以重复执行的,如果因为网络等原因造成的失败问题,可以调整相关的超时参数然后重新执行一遍就行了。总结对于自动化来说,其本质是件一直在路上的工作。明确目标,然后找对工具进行持续的改进。笔者认为   Ansible 就是这么一款值得信赖的自动化利器,并且它能够通过 playbook 和 role 等概念把我们的使用经验积淀下来进行分享。参考:Integrating Ansible with Jenkins in a CI/CD processansible-role-jenkinsgalaxy role jenkins(geerlingguy)
通过 CLI 管理 Jenkins Server
Jenkins 内置的命令行接口允许管理员通过命令行工具访问并管理 Jenkins。这让我们可以通过脚本自动化的创建配置或执行任务,也就是把 Jenkins 中的配置代码化了。Jenkins 同时支持通过 SSH 和客户端命令行工具 jenkins-cli.jar 进行访问。本文主要介绍如何通过这两种方式用命令行操作 Jenkins。说明:本文的演示环境为 ubuntu 16.04。通过 SSH 执行命令在 Jenkins Server 的默认安装中,内置的 SSH service 是没有启用的:我们可以通过下面的配置让 Jenkins 启用 SSH service,Jenkins ->Configure Global Security:笔者选择让 Jenkins 的 SSH Server 监听 8090 端口,如果你选择的是 Random,那么监听的端口是随机产生的,无论如何,我们都可以用下面的命令来获得  Jenkins SSH Server 监听的端口号:$ curl -Lv http://192.168.21.145:8080/login 2>&1 | grep 'X-SSH-Endpoint'说明:笔者的 Jenkins Server 部署在主机 192.168.21.145 上,监听的端口号为 8080。用户至少要有 Overall/Read 权限才能访问命令行接口,但是根据执行的命令的不同还需要更高的权限。本文主要演示如何配置远程执行命令,所以演示用的用户具有全部权限。为用户添加身份验证的秘钥使用 SSH 的最佳方式是通过秘钥进行身份验证,这里我们把远程机器上用户的公钥添加到 Jenkins 用户 jack 的 Public Keys 列表中(Jenkins -> jack):现在就可以远程调用 Jenkins Server 提供的命令了,先来问一下 "我是谁?":$ ssh -l jack -p 8090 192.168.21.145 who-am-ihelp 命令我们可以通过 help 命令来查看所有的可用命令:$ ssh -l jack -p 8090 192.168.21.145 helphelp 命令的输出很长,上图仅截取了一部分,我们还可以通过 help 命令查看其它命令的详细用法,笔者会在后面的文章中详细介绍常用命令,这里先一笔带过。build 命令为了演示方便,我们先来简单了解一下 build 命令,它用来触发 job 和 pipeline 的执行。下面的是用它来触发一个名称为 test 的 job,这个 job 非常简单,仅仅输出字符串 "hello":$ ssh -l jack -p 8090 192.168.21.145 build test -f -v还不赖,任务被成功的执行了!到此为止,我们已经可以组织自动化脚本远程操作 Jenkins Server 了。下面我们一起看看 Jenkins 提供的另外一种方式:客户端命令行工具。客户端命令行工具虽然基于 SSH 的 CLI 非常便捷,并且能够满足大多数需求,但是在某些情况下,与 Jenkins 一起发布的客户端 CLI 工具可能更合适。例如,客户端 CLI 工具的默认传输方式是 HTTP,这意味着不需要在防火墙中打开额外的端口来就可以使用。通常不需要进行特殊的系统配置来启用基于 HTTP 的命令行连接。如果是在 HTTP(S) 反向代理后面运行 Jenkins,一定要确保请求和响应不会被缓存。下载客户端命令行工具Jenkins 自带的命令行工具是一个 java 程序,可以通过下面的 url 下载到远程主机上:JENKINS_URL/jnlpJars/jenkins-cli.jar比如:$ wget http://192.168.21.145:8080/jnlpJars/jenkins-cli.jar注意,这是个 java 程序,要运行它需要确保你的主机上安装了 jre。通过用户名和密码认证用户身份下面我们用客户端工具来触发 test job,先通过用户名和密码的方式进行认证:$ java -jar jenkins-cli.jar -s http://192.168.21.145:8080 -auth jack:123456 build test -f -v虽然命令成功执行了,但使用密码毕竟太不安全。使用 API Token安全起见还是应该使用 API Token,先为用户 jack 生成 API Token:把上面命令中的密码换成 API Token 就可以了:$ java -jar jenkins-cli.jar -s http://192.168.21.145:8080 -auth jack:11d5ca0f9ee2dac8c47492b3e6b71c82cd build test -f -v结果和上面是一样的。还可以把用户名和 API Token 保存到文件中,这样能进一步提高安全性:$ echo jack:11d5ca0f9ee2dac8c47492b3e6b71c82cd > .jenkins-token然后可以使用 @ 符以下面的方式引用:$ java -jar jenkins-cli.jar -s http://192.168.21.145:8080 -auth @/home/nick/.jenkins-token build test -f -v执行的结果也是一样的。注意要在 @ 后面不要用 ~ 号代替用户的家目录。除此之外还可以通过环境变量来指定用户名和 API Token:$ export JENKINS_USER_ID=jack$ export JENKINS_API_TOKEN=11d5ca0f9ee2dac8c47492b3e6b71c82cd$ java -jar jenkins-cli.jar -s http://192.168.21.145:8080 build test -f -v效果也是一样的。通过 SSH 进行连接好吧,客户端命令行工具也支持通过 SSH 进行连接。同时指定 -ssh 和 -user 选项就可以了:$ java -jar jenkins-cli.jar -s http://192.168.21.145:8080 -ssh -user jack build test -f -v总结通过 Ansible 等工具自动化的创建 Jenkins Server(参考前文《通过 Ansible 创建 Jenkins Server》),然后再通过 Jenkins 提供的 CLI 自动化的操作 Jenkins 中的配置。这样我们就打通了整个 Jenkins Server 的自动化过程(当然,笔者还会介绍如何自动化的创建运行 Jenkins Server 的宿主机)。好吧,这都只是些简单的 demo,在生产环境中要做的事情可要多的多!参考:Jenkins CLI
Jenkins CLI 命令详解
笔者在前文《通过 CLI 管理 Jenkins Server》中介绍了如何通过 SSH 或客户端命令行的方式管理 Jenkins Server,限于篇幅,前文主要的目的是介绍连接 Jenkins Server 的方式。本文主要介绍 Jenkins Server 提供的常用命令。本文主要演示以 SSH 的方式执行常见的 Jenkins CLI 命令,关于通过 SSH 连接 Jenkins Server 的内容,请参考前文。说明:本文的演示环境为 ubuntu 16.04。从 who-am-i 开始$ ssh -l jack -p 8090 192.168.21.145 who-am-i获取 Jenkins Server 的版本$ ssh -l jack -p 8090 192.168.21.145 version添加 agentcreate-node 命令需要指定一个 xml 文件作为参数,这个 xml 文件中保存着新建 node 的配置信息。方便起见我们可以先使用 get-node 命令获得一个现有 node 的配置文件,然后修改其中的配置,并最终用来创建新的 node。比如我们当前有一个名为 testagent 的 node:用下面的命令获得其配置信息:$ ssh -l jack -p 8090 192.168.21.145 get-node testagent > testagent.xml接下来复制一份 testagent.xml 文件,创建 myagent.xml 文件,并修改 myagent.xml 文件中的相关配置。比如把 agent 名称改为 myagent,host 修改为新 agent 的 IP 地址,credentialsId 改为具有适当权限的新 ID。最后用新的 myagent.xml 文件创建 node:$ ssh -l jack -p 8090 192.168.21.145 create-node < myagent.xml这样新的 node 就创建好了。当然,我们也可以使用 delete-node 命令删除一个 node。安装 pluginJenkins 默认提供的操作 plugin 的 CLI 只有  list-plugins 和 install-plugin。list-plugins 用来罗列所有已安装的 plugins:$ ssh -l jack -p 8090 192.168.21.145 list-plugins如果为 list-plugins 指定参数(插件的名称),则只显示该插件的信息,该插件不存在就报错:install-plugin 命令用来安装插件:install-plugin SOURCE ... [-deploy] [-name VAL] [-restart]根据指定的 source 选项,分别可以从 URL、本地文件和 update center 安装插件。默认从 update center 安装插件,只用指定插件的短名称(ID)就可以了:$ ssh -l jack -p 8090 192.168.21.145 install-plugin greenballs -deploy-deploy 表示立即部署插件而不必等到下次重启 Jenkins。如果指定的插件已经存在并且需要升级到新的版本,同样执行 install-plugin 命令就可以了:$ ssh -l jack -p 8090 192.168.21.145 install-plugin pipeline-graph-analysis -restart-restart 选项表示安装完成后重启 Jenkins。等 Jenkins 重启完成后,发现插件已经被更新到了最新的版本:注意:update center 安装插件时,会自动安装当前插件所依赖的插件。通过本地的文件安装插件下载 greenballs 插件到当前的目录中,然后执行命令:$ ssh -l jack -p 8090 192.168.21.145 install-plugin = -deploy < greenballs.hpi -name greenballs注意,此时需要通过 -name 选项指定插件的名称。job 操作Jenkins CLI 提供了丰富的命令来操作 job:list-jobs:默认列出所有的 jobget-job:获得指定 job 的配置文件copy-job:以现存的 job 为模板创建一个新的 jobcreate-job:创建一个新的 job,以标准输入中的内容作为配置信息update-job:以配置文件中的内容更新 jobdelete-job:删除 jobenable-job:enable jobdisable-job:disable job虽然 job 操作涉及的命令比较多,但是都相对的简单,这里不再一一演示。触发 jobbuild 命令用来触发一个 job 任务,我们可以通过 help 命令来查看一下 build 命令的帮助文档:$ ssh -l jack -p 8090 192.168.21.145 help build由上面的文档可知,可以通过 -f 和 -v 选项同步的执行 job 并获得控制台输出:$ ssh -l jack -p 8090 192.168.21.145 build test -f -v总结Jenkins CLI 默认支持的命令很多,这里只是简单介绍了其中的几个,主要目的是帮助理解 Jenkins CLI 命令的基本用法。更多命令的详细用法请参考官方文档。参考:Jenkins CLI