Jenkins 实战

Jenkins 实战

简介

<img align="left" src="./images/logo.svg" width="200">

构建伟大,无所不能

Jenkins 是开源 CI & CD 软件领导者,提供超过 1000 个插件来支持构建、部署、自动化,满足任何项目的需要。

持续集成 & 持续部署

持续集成

持续集成(Continuous Integration,缩写是 CI)是一种软件开发实践,即团队开发成员经常集成他们的工作,通常每个成员每天至少集成一次,也就意味着每天可能会发生多次集成。每次集成都通过自动化的构建(包括编译,发布,自动化测试)来验证,从而尽早地发现集成错误。

<img src="./images/ci.jpg" style="zoom:80%;" />

持续交付

持续交付(Continuous Delivery,缩写为 CD),是一种软件工程手法,让软件产品的产出过程在一个短周期内完成,以保证软件可以稳定、持续的保持在随时可以发布的状况。它的目标在于让软件的构建、测试与发布变得更快以及更频繁。这种方式可以减少软件开发的成本与时间,减少风险。

<img src="./images/cd1.jpg" style="zoom:60%;" />

Jenkins

插件管理

插件镜像加速

Jenkins 默认是从外网的插件仓库下载插件的,速度在国内来说就慢了很多,我们可以通过将插件地址修改为国内镜像仓库,即可提升插件的下载速度

# 在 Jenkins 首页进入插件管理页面,进入 Avaliable 可选产检页面
# 进入 jenkins_home 修改已加载的所有插件下载地址,所有插件数据所在文件 jenkins_home/updates/default.json
# 将该文件中所有插件的地址修改为国内的地址
cd jenkins_home/updates
sed -i 's/http:\/\/updates.jenkins-ci.org\/download/https:\/\/mirrors.tuna.tsinghua.edu.cn\/jenkins/g' default.json && sed -i 's/http:\/\/www.google.com/https:\/\/www.baidu.com/g' default.json

# 最后在 Jenkins 的插件管理页面 Manage Plugins 点击 Advanced,把 Update Site 改为国内插件下载地址
https://mirrors.tuna.tsinghua.edu.cn/jenkins/updates/update-center.json

# 提交后,在浏览器输入:http://jenkins_server_ip:8080/restart 重启 jenkins

凭证管理

在 Jenkins 中经常会涉及到需要访问其他服务的操作,例如 git 仓库、ssh 访问服务等,这些服务通常都是需要进行认证的,因此 Jenkins 为我们提供了凭证管理插件来统一管理所有凭证信息

安装步骤:

  1. 安装 Credentials Binding 插件
  2. 进入插件管理里面搜索该插件,并安装
  3. 安装完成以后,Jenkins 首页右侧多了凭证的菜单栏
  4. 进入凭证菜单栏,管理相关凭证
# 凭证类型
username with password  # 用户名密码凭证
ssh username with private key   # 私钥凭证
secret file   # 密钥文件凭证
secret text # 密钥文本凭证
certificate # 证书凭证
凭证的使用

首先需要安装 git 插件,用于下载 git 仓库的源代码,然后在 Jenkins 首页创建一个自由风格的项目,分别测试使用用户名密码和 ssh 私钥凭证来拉取远程仓库项目代码

用户名密码凭证

首先进入凭证管理页面,选择全局凭证,再找到左侧添加凭证按钮,进入添加页面以后就可以选择不同类型的凭证了。选择用户名密码凭证,并输入用户名与密码既可以创建成功一个用户名密码凭证

进入 Jenkins 首页,并点击左侧的新建任务,创建一个自由风格的项目,进入项目配置页面以后,选择源码管理栏目并选择 git 仓库,接下来就完成 git 仓库相关配置信息,并且在后面的凭证位置选择刚刚创建的用户名密码凭证即可

返回项目详情页,点击立即构建,查看该仓库的代码是否能够被下载到 Jenkins 中

SSH 密钥类型

操作基本上与添加用户名密码凭证类似,不过需要先使用 ssh-keygen -t rsa 提前生成公钥私钥,并将公钥文件配置到 git 仓库平台的用户 ssh 或仓库 deploy ssh 处

配置完成后同样创建一个普通项目,并配置源码管理等信息,检测 ssh 秘钥配置是否成功

构建项目

在 Jenkins 有许多的构建项目类型,在这里我们主要用到以下三种:

  • 自由风格项目(FreeStyle Project):可以构建各种类型的项目

  • Maven项目(Maven Project):专门针对 Java 的 Maven 项目

  • 流水线项目(Pipeline Project):灵活度高,可调整空间大,代码控制CICD流程,可以构建较为复杂的项目

PS:公司中更常用流水线类型,因为灵活度更到,且CICD流程较为清晰

灵活度高,可调整空间大,代码控制CICD流程,可以构建较为复杂的项目

自由风格项目

项目构建流程:拉取代码 > 编译 > 打包 > 部署

在 Jenkins 首页创建一个项目,在项目类型选择处选择自由风格项目

拉取源码

在项目配置页面选中源码管理,再选择 git 管理并配置凭证即可拉取项目代码

编译打包配置

找到项目配置的 构建 -> 添加构建步骤 -> Execute Shell

echo "开始进行编译构建"
mvn clean package -Dmaven.skip.test=true
echo "编译构建结束"
Tomcat 远程部署配置

默认情况下 Tomcat 是关闭了远程部署功能的,我们需要修改一些 Tomcat 的配置信息来支持远程部署

首先访问 Tomcat 的 webapps/manager 目录(检查默认没有开启)

查看 /META-INF/context.xml 文件并将以下配置注释即可

<!-- <Valve className="org.apache.catalina.valves.RemoteAddrValve" allow="127\.\d+\.\d+|::1|0:0:0:0:0:0:0:1"> -->

还需要再进入 tomcat/conf 目录开启远程部署权限,以及配置用户信息。先找到 tomcat-users.xml 配置如下:

配置如下

<tomcat-users>
  <role rolename="tomcat"/>
  <role rolename="role1"/>
  <role rolename="manager-script"/>
  <role rolename="manager-gui"/>
  <role rolename="manager-status"/>
  <role rolename="admin-gui"/>
  <role rolename="admin-script"/>
  <user username="tomcat" password="tomcat" roles="manager-gui,manager-script,tomcat,admin-gui,admin-script"/>
</tomcat-users>

重启 tomcat 即可进行远程访问

部署到 Tomcat

想在项目构建完成后直接将项目部署到 Tomcat,需要先将安装 deploy to container 插件用于部署到容器

然后在项目配置的构建后操作中选择 deploy war/ear to a container

操作步骤:
1. 设置 war 包目录:target/*.war
2. 设置容器类型
3. tomcat 版本选择:设置对应 tomcat 版本即可
4. 添加 tomcat 用户名密码凭证:Tomcat 远程部署处添加的用户名密码
5. 配置远程 tomcat 地址:提示地址修改为对应的 tomcat 所在地址即可

远程部署配置完成,点击部署即可进行构建

Maven 项目

Jenkins 专门为 Maven 类型项目提供了一种构建方式,不过需要先下载一个 maven integration 的插件,即可在创建构建项目时选择 Maven 项目,可以比较快捷的完成项目的构建操作,具体操作如下

操作步骤:
1. 在 Jenkins 首页点击创建项目,并选择 Maven 项目
2. 在项目配置中 "源码管理" 完成 git 仓库相关配置
3. 在 "构建" 栏目中配置以下两个参数
    root pom:pom.xml
    goals and options:clean package -Dmaven.skip.test=true
4. 添加构建后操作,将war包发布到远程tomcat

Pipeline 流水线项目

基本概念

pipeline 是一套运行在 Jenkins 上的工作流框架,将原来独立运行于单个或多个节点的任务连接起来,实现单个任务难以完成的复杂流程编排和可视化的工作。

Pipeline 的好处

代码:以代码的形式实现,通常被检入源代码控制,使团队能够编辑,审查和迭代其传送流程。

持久:无论是计划内还是计划外的服务器重启,Pipeline都是可恢复的

可停止:Pipeline可接收交互式输入,以确定是否继续执行Pipeline

多功能:Pipeline支持现实世界中复杂的持续交付要求,他支持fork/join,循环执行,并执行任务的功能。

可拓展:Pipeline插件支持其DSL的自定义拓展,以及与其他插件集成的多个选项

如何创建 Pipeline

Pipeline 是基于Groovy 语言实现的,但是我们没必要单独去学习 Groovy,只需要能够大概看懂意思就足够了,并且 Jenkins 为我们几乎所有的相关操作都提供了 pipeline 脚本生成器,可以自动生成对应的脚本

Pipeline 支持两种语法:

  • Declarative(声明式)
  • Scripted Pipeline(脚本式)语法

Pipeline 也有两种创建方法:

  • 可以直接在 Jenkins 的 Web UI 界面中输入脚本

  • 也可以通过创建一个Jenkinsfile 脚本文件放入项目源码库中(一般我们推荐在Jenkins中直接从源代码控制(SCM)中直接载入 Jenkinsfile Pipeline 这种方法)

安装 Pipeline 插件

首先我们需要进入插件管理中安装 Pipeline 插件,安装插件完成后,创建一个流水线项目

安装插件后,创建一个流水线项目

直接往下找到 "流水线" 栏目,并在脚本输入框的右边下拉框找到 hello world 选择不同的类型查看效果

2.0 以前大部分使用的都是脚本式的,Jenkins2.0 以后推荐使用声明式的

# Hello World 声明式语法演示
pipeline {
    
    agent any
    
  stages {
    stage('pull code') {
        steps {
        echo 'pull code'
      }
    }
    stage('build project') {
        steps {
            echo 'build project'
        }
    }
    stage('publish project') {
        steps {
            echo 'publish project'
        }
    }
  }
}
Pipeline 拉取代码

点击 pipeline 脚本下方的流水线语法,进入页面点击片段生成器可以辅助生成代码

/**
 * 操作步骤:
 * 1. 在 "流水线" 配置栏的输入框下面点击流水线语法,进入片段生成器页面
 * 2. 在右边 "示例步骤" 的下拉框处选择 git:Git
 * 3. 填写仓库地址、分支名以及访问仓库的凭证
 * 4. 点击下方的生成流水线脚本按钮即可生成对应的脚本内容
 */
pipeline {
    agent any
    
    stages {
        stage('拉取代码') {
            steps {
                checkout([$class: 'GitSCM', branches: [[name: '*/master']], doGenerateSubmoduleConfigurations: false, extensions: [], submoduleCfg: [], userRemoteConfigs: [[credentialsId: 'gitlab-ssh-auth', url: 'git@gitee.com:wolfcodeliug/shop-cloud43.git']]])
            }
        }
    
        stage('编译构建') {
            steps {
                sh label: '', script: 'mvn clean package'
            }
        }
    }
}
Pipeline 部署项目

进入流水线脚本生成页面,在 "示例步骤" 下拉框中选择 deploy: Deploy war/ear to a container,完成 tomcat 相关配置信息后,点击生成流水线脚本按钮即可

pipeline {
    agent any
    
    stages {
        stage('拉取代码') {
            steps {
                checkout([$class: 'GitSCM', branches: [[name: '*/master']], doGenerateSubmoduleConfigurations: false, extensions: [], submoduleCfg: [], userRemoteConfigs: [[credentialsId: 'gitlab-ssh-auth', url: 'git@gitee.com:wolfcodeliug/shop-cloud43.git']]])
            }
        }
    
        stage('编译构建') {
            steps {
                sh label: '', script: 'mvn clean package'
            }
        }
        
        stage('部署项目') {
            steps {
                deploy adapters: [tomcat7(credentialsId: 'tomcat-auth', path: '', url: 'http://tomcat.my-company.com:8080')], contextPath: '/', war: 'target/*.war'
            }
        }
    }
}
Jenkinsfile

平时工作中更多的时候是以 Jenkinsfile 的方式来存放 pipeline 脚本的,因此我们再使用 Jenkinsfile 的方式来重新完成一遍项目持续交付的配置,在 "流水线" 配置的地方直接选择 Pipeline script from SCM 的方式,并在 SCM 处选择 git,且配置好 git 仓库的相关信息即可

此时只需要在项目根目录创建一个 Jenkinsfile 文件,并且将上面的 pipeline 脚本拷贝到该文件中就可以了

构建触发器

顾名思义,构建触发器就是可以配置一些规则,当这些规则被触发时则自动的进行项目的构建操作,Jenkins 中默认有以下4种构建触发器:

触发远程构建

其他工程构建后触发(Build after other projects are build)

定时构建(Build periodically)

轮询SCM(Poll SCM)

触发远程构建

实际上就是通过 url + token 的方式来进行远程触发构建,你可以在构建触发器处选择 "触发远程构建",并且设置对应的 token 即完成配置了,然后通过提示的 url 地址再加上刚刚配置的 token 请求一次,即触发一次构建

其他工程构建后触发

这个也很好理解了,有些项目之间可能存在着一些依赖关系,需要先启动依赖项目再启动自身,那么此时就可以在项目中配置其他项目构建后触发,当依赖项目构建完成后会立即构建该项目

定时构建

通过配置定时任务,可以指定项目在指定的时间周期性的进行部署,定时表达式案例如下

在构建触发器中选择定时构建,并在日程表中配置定时规则:分 时 日 月 周

表达式例子:
每30分钟构建一次:H代表形参
H/30 * * * *

每2小时构建一次:
H H/2 * * *

每天的8点,12点,22点各构建一次
0 8,12,22 * * *

每天中午12点定时构建一次
H 12 * * *

每天下午18点定时构建一次
H 18 * * *

每个小时的前半个小时内的每10分钟各构建一次
H(0-29)/10 * * * *

每两小时一次,每个工作日上午9点到下午5点(也许是上午10:38,下午12:38,下午4:38)
H H(9-16)/2 * * 1-5

轮询 SCM

定时的检查代码仓库是否有新的提交,如果有就立刻进行构建。直接在构建触发器中选择 "轮询 SCM" 并在日程表中设置定时规则,定时任务表达式与定时构建表达式语法一致

Git hook 自动触发构建

这是我们平常在开发环境中比较常用的一种方式,利用代码管理平台(Github、Gitee、Gitlab)的 webhook 实现代码 push 到仓库,项目自动触发构建

由于 Jenkins 在内网环境,因此我们采用内网的 Gitlab 来完成该功能,操作前需要先下载 Gitlab HookGitLab 两个插件

配置步骤:
Gitlab 平台配置:
一、开启 WebHook 功能,需要用到管理员用户
1. 使用 root 用户登录 Gitlab,进入 Admin Area 配置中,选择 Settings
2. 点击左侧的 Network 菜单栏,展开 Outbound requests 栏目
3. 勾选 Allow requests to the local network from web hooks and services 开启 webhook
二、代码仓库配置 WebHook
1. 进入仓库配置的 Integrations 中
2. 将 Jenkins GitLab 构建触发器的 URL 粘贴到 Integrations 的 URL 中
3. 在 Trigger 中仅勾选 Push events 即可
4. 点击下方已经添加的 Webhook 测试
PS: 如果此时会出现请求被禁用的问题,需要去 Jenkins 开启允许外部请求

项目构建配置:
1. 进入项目工程配置,勾选构建触发器新出现的 GitLab 变更推送配置
2. 复制提示的构建 url 并在高级设置中生成 token

Jenkins 配置:
1. 在 Jenkins 主页的系统管理中,选择系统配置
2. 找到下方的 Gitlab 选项,并将 Enable authentication for '/project' end-point 取消勾选

SonarQube 代码审查

叩丁狼内网 SonarQube Server

在持续集成的流程中,除了基于 Maven 的基础 JUnit 测试外,还需要验证代码是否有明显的 bug 或编码质量底下等问题,因此我们可以借助 SonarQube 服务来对代码进行自动化的审查,检测一些常见的 bug 以及低质量代码

环境准备

首先需要安装 SonarQube Scanner 插件,并在 Jenkins 中完成 SonarQube 的相关配置

SonarQube Scanner 配置
1. 找到 Jenkins 配置下的全局工具配置,并在其中找到 SonarQube Scanner 配置栏
2. 配置 SonarQube Scanner 名称,后续使用时会用上
3. 勾选自动安装的方式,并且在 Install from Maven Centeral 处选择 SonarQube scanner 最新版本即可

SonarQube 环境配置
1. 进入 Jenkins 的系统配置页面,并找到 SonarQube Servers 配置项
2. 填写 SonarQube 服务名称,后续扫描实会用到
3. 配置 SonarQube Server URL,Jenkins 会将扫描报告发送至 SonarQube Server 并获得分析结果
4. 在凭证管理器中添加密钥文本类型的凭证,并使用 root 用户登录 SonarQube Server 拿到认证 token 信息填写到 Jenkins 的认证凭证当中
5. 在 Server authentication token 处选择刚刚添加的 token 凭证即可

项目配置

为需要进行代码审查的项目添加如下的扫描模板,通常会在项目中创建一个 sonar-project.properties 文件

# 扫描模板
# 项目的唯一标识,每一个 SonarQube 扫描的实例都必须是不一样的
sonar.projectKey=ci-demo
# 项目的名称和版本号,会显示在 SonarQube Server 中
sonar.projectName=ci-demo
sonar.projectVersion=1.0.0
# 以下路径是相对于 sonar-project.properties 文件的. 在 Windows 下使用 "\" 替代 "/"
# 如果 sonar.modules 设置了的话,这些属性是可选的
sonar.sources=.
sonar.exclusions=**/test/**,**/target/**
sonar.java.source=1.8
sonar.java.target=1.8
# 源码的编码格式,默认使用系统编码
sonar.sourceEncoding=UTF-8
非流水线项目

非流水线项目中需要在项目构建配置的 "构建" 栏目中添加一个 Execute SonarQube Scanner 配置项,并配置以下相关参数信息

配置如下:
# 任务运行的指令
Task to run: scan
# 在全局工具配置中配置的jdk
JDK: jdk1.8
# 项目中的 sonar-project.properties 路径,该路径是相对于项目根目录的
Path to project properties: sonar-project.properties
# 分析项目的属性配置,其实就是 sonar-project.properties 中配置的那些内容,该配置与 Path to project properties 二者配置一个就可以了
Analysis properties: 
# 附加参数配置,可选配置
Additional arguments: 
# JVM 配置项,可选配置
JVM Options: 
流水线项目

流水线类型的项目只需要修改 Jenkinsfile 配置文件,在构建流程中加入代码审查步骤即可,具体配置方式如下

stage('code checking') {
    steps {
        script {
            // 引入扫描工具,此处配置的名称需要与 "全局工具配置 > SonarQube Scanner" 中配置的名称一致
            scannerHome = tool 'sonarqube-scanner'
        }
        // 引入sonarqube服务器环境,此配置名称需要与 "系统配置 > SonarQube Server" 中配置的名称一致
        withSonarQubeEnv('sonarqube-server') {
            sh "${scannerHome}/bin/sonar-scanner"
        }
  }
}
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 160,026评论 4 364
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 67,655评论 1 296
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 109,726评论 0 244
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 44,204评论 0 213
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,558评论 3 287
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,731评论 1 222
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,944评论 2 314
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,698评论 0 203
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,438评论 1 246
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,633评论 2 247
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,125评论 1 260
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,444评论 3 255
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,137评论 3 238
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,103评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,888评论 0 197
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,772评论 2 276
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,669评论 2 271

推荐阅读更多精彩内容