JENKINS 是一个用 JAVA 编写的开源的持续集成工具。在与 ORACLE 发生争执后,项目从HUDSON 项目独立出来。 JENKINS 提供了软件开发的持续集成服务。
它运行在 SERVLET 容器中(例如 APACHE TOMCAT)。它支持软件配置管理(SCM)工具(包括 ACCUREV SCM、CVS、SUBVERSION、GIT、PERFORCE、CLEARCASE 和 RTC),可以执行基于 APACHE ANT 和 APACHE MAVEN的项目,以及任意的 SHELL 脚本和 WINDOWS 批处理命令。JENKINS 是在 MIT 许可证下发布的自由软件

二 企业代码上线发展史

代码发布上线是每一个 IT 企业必须要面临的,而且不管是对开发或者是运维来说,代码上线本身就是一个件非常痛苦的事情,很多时候每一次发布都是一次考验。为了提高上线的效率,代码上线的方式,方法,工具也不断的发展,基本上可以分为以下几个阶段:

阶段 1-没有构建服务器
软件在开发者的机器上通过 Ant 或其它脚本手动构建,代码保存在中央源码仓库中,但是开发者不是经常提交本地的修改。每次需要发布的时候,开发者手动合并修改,这个过程是相当痛苦的

阶段 2-晚上进行构建
在这个阶段,团队有构建服务器,自动化的构建在晚上进行。构建过程只是简单的编译代码,没有可靠的和可重复的单元测试。然而,开发人员每天提交代码。如果某个开发人员提的代码和其他人的代码冲突的话,构建服务器会在第二天通过邮件通知团队。所以有一段时间构建是处于失败状态的。

阶段 3-晚上进行构建并进行自动化测试
团队对 CI 和自动化测试越来越重视。无论什么时候版本管理系统中的代码改变了都会触发编译构建过程,团队成员可以看到是代码中的什么改变触发了这个构建。并且,构建脚本会编译应用并且会执行一系列的单元测试或集成测试。除了邮件,构建服务器还可以通过其他方式通知团队成员,如:IM。失败的构建被快速的修复

阶段 4-代码质量度量
自动化的代码质量和测试覆盖率的度量手段有助于评价代码的质量和测试的有效性。代码质量的构建会产生 API 文档

阶段 5-更加认真地对待测试
CI 和测试紧密相关。如今,像测试驱动开发被广泛地使用,使得对自动化的构建更加有信心。应用不仅仅是简单地编译和测试,而是如果测试成功会被自动的部署到一个应用服务器上来进行更多的综合的 end-to-end 测试和性能测试。

阶段 6-验收测试和更加自动化的部署
验收测试驱动的开发被使用,使得我们能够了解项目的状态。这些自动化的测试使用行为驱动的开发和测试驱动的开发工具来作为交流和文档工具,发布非开发人员也能读懂的测试结果报告。
由于测试在开发的早起就已经被自动化的执行了,所以我们能更加清楚地了解到什么已经做了,什么还没有做。每当代码改变或晚上,应用被自动化地部署到测试环境中,以供 QA 团队测试。当测试通过之后,软件的一个版本将被手工部署到生产环境中,团队也可以在出现问题的时候回滚之前的发布

阶段 7-持续部署
对自动化的单元测试,集成测试和验收测试的信心使得我们可以使用自动化的部署技术将软件直接部署到生产环境中。但是测试还是有可能不能真正的反映现实的环境

三 Jenkins的安装

 使用RPM方式安装

 [root@localhost ~]# yum install -y  java-1.8.0-openjdk java-1.8.0-openjdk-devel
 [root@localhost ~]# wget https://mirrors.tuna.tsinghua.edu.cn/jenkins/redhat-stable/jenkins-2.121.1-1.1.noarch.rpm
 [root@localhost ~]# rpm -ivh jenkins-2.121.1-1.1.noarch.rpm 
 [root@localhost ~]# systemctl start jenkins
 [root@localhost ~]# systemctl enable jenkins
 jenkins.service is not a native service, redirecting to /sbin/chkconfig.
 Executing /sbin/chkconfig jenkins on

 Jenkins 默认监听 8080,服务启动后我们可以在浏览器中输入 http://您服务器的 ip地址:8080 访问 jenkins 服务。

 

四 Jenkins的插件管理

 Jenkins 本身是一个引擎、一个框架,只是提供了很简单功能,其强大的功能都是通过插件来实现的,jenkins 有一个庞大的插件生态系统,为 Jenkins 提供丰富的功能扩展。下面我们来介绍常用的几种插件安装方式

1 自动安装插件

在 jenkins 主页面,点击系统管理在右侧选择管理插件:

进入插件管理页面,点击可选插件,选择你需要安装的插件

安装完成后,一般情况下不需要重启 Jenkins,具体根据提示操作

2 手工安装插件

除了上面的插件安装方法,Jenkins 还为我们提供了手工安装插件的方式,特别是在国内,由于网络的原因,有时候我们使用上述方法安装插件会经常不成功,所以我们可以采用下载插件,然后再上传的方式来安装插件

官方的插件下载地址:http://updates.jenkins-ci.org/
国内的源:https://mirrors.tuna.tsinghua.edu.cn/jenkins/plugins/

如果是在官方网站下载插件,最好下载与你 jenkins 版本对应的插件,如果是在清华镜像下载插件,则不存在版本的问题。下载后得到的一个以.hpi 为扩展名的文件
下载 ssh.hpi 后,我们手动安装 ssh 插件,进入到插件管理页面

3 覆盖插件目录

我们可以备份已经安装好插件的 Jenkins 服务器上的/var/lib/jenkins/plugins 目录,然后把备份文件上传到我们需要安装插件的新 Jenkins 服务器的对应目录上,然后重启Jenkins
这种方法其实给我们提供了一种更加快速的安装 Jenkins 插件的方法。建议在初始安装jenkins 时,可以使用此方法,其他时候尽量使用前两种方式。我们本教程使用此方式安装插件。前面我们在初始化 jenkins 的时候,跳过了插件的安装,现在我们的 Jenkins 插件目录为空,因为我们没有安装任何插件:

[root@ci-node2 ~]# cd /var/lib/jenkins/plugins/
[root@ci-node2 plugins]# ll
[root@ci-node2 ~]# ll plugins.tar.gz
-rw-r--r-- 1 root root 164431230 May 31 16:46 plugins.tar.gz
[root@ci-node2 ~]# tar xf plugins.tar.gz
[root@ci-node2 ~]# cd plugins
[root@ci-node2 plugins]# mv * /var/lib/jenkins/plugins/
完成后,重启 jenkins 服务
[root@ci-node2 plugins]# systemctl restart Jenkins

 五 Jenkins 常用目录及文件

学习 Jenkins,首先要明白一点,那就是 jenkins 下一切兼文件,也就是说 jenkins 没有数据库,所有的数据都是以文件的形式存在,所以我要了解 Jenkins 的主要目录及文件,通过命令我们可以查看到所有的 jenkins 目录及文件的位置

[root@ci-node2 ~]# rpm -ql jenkins
/etc/init.d/jenkins
/etc/logrotate.d/jenkins
/etc/sysconfig/jenkins
/usr/lib/jenkins
/usr/lib/jenkins/jenkins.war
/usr/sbin/rcjenkins
/var/cache/jenkins
/var/lib/jenkins
/var/log/Jenkins

1 Jenkins 主配置文件

/etc/sysconfig/jenkins 是 Jenkins 的主配置文件:我们在这里主要配置 Jenkins 的工作目录、启动用户、启动端口。
Jenkins 默认的用户为 jenkins,生产环境建议使用 jenkins 用户,然后使用 sudo 进行授权,我们实验过程为了避免各种权限问题,改为 root 用户。

2 Jenkins 主目录

/var/lib/jenkins 是 Jenkins 默认配置的主工作目录,我们可以在主配置文件进行设置

[root@ci-node2 ~]# cd /var/lib/jenkins/
[root@ci-node2 jenkins]# ll
total 64
-rw-r--r-- 1 jenkins jenkins 788 Aug 4 21:53
com.dabsquared.gitlabjenkins.connection.GitLabConnectionConfig.xml
-rw-r--r-- 1 jenkins jenkins 365 Aug 4 21:53
com.dabsquared.gitlabjenkins.GitLabPushTrigger.xml
-rw-r--r-- 1 jenkins jenkins 1592 Aug 4 21:53 config.xml
-rw-r--r-- 1 jenkins jenkins 159 Aug 4 21:53
hudson.model.UpdateCenter.xml
-rw-r--r-- 1 jenkins jenkins 370 Aug 4 21:53
hudson.plugins.git.GitTool.xml
-rw------- 1 jenkins jenkins 1712 Aug 4 16:05 identity.key.enc
-rw-r--r-- 1 jenkins jenkins 94 Aug 4 16:05 jenkins.CLI.xml
-rw-r--r-- 1 jenkins jenkins 4 Aug 4 21:53
jenkins.install.InstallUtil.lastExecVersion
-rw-r--r-- 1 jenkins jenkins 4 Aug 4 20:18
jenkins.install.UpgradeWizard.state
drwxr-xr-x 2 jenkins jenkins 6 Aug 4 16:05 jobs
drwxr-xr-x 3 jenkins jenkins 19 Aug 4 16:05 logs
-rw-r--r-- 1 jenkins jenkins 907 Aug 4 21:53 nodeMonitors.xml
drwxr-xr-x 2 jenkins jenkins 6 Aug 4 16:05 nodes
drwxr-xr-x 97 jenkins jenkins 8192 Aug 4 21:52 plugins
-rw-r--r-- 1 jenkins jenkins 129 Aug 4 21:53 queue.xml.bak
-rw-r--r-- 1 jenkins jenkins 64 Aug 4 16:05 secret.key
-rw-r--r-- 1 jenkins jenkins 0 Aug 4 16:05 secret.key.not-so-secret
drwx------ 4 jenkins jenkins 4096 Aug 4 16:05 secrets
-rw-r--r-- 1 jenkins jenkins 0 Aug 5 10:16 ThinBackup Worker Thread.log
drwxr-xr-x 2 jenkins jenkins 182 Aug 4 21:53 updates
drwxr-xr-x 2 jenkins jenkins 24 Aug 4 16:05 userContent
drwxr-xr-x 3 jenkins jenkins 19 Aug 4 16:05 users
drwxr-xr-x 2 jenkins jenkins 6 Aug 4 21:53 workflow-libs

其中主要的目录为 jobs 目录:存放 jobs 的配置及每次构建的结果;plugins 目录:Jenkins 插件目录,存放我们已经安装的插件;worksspace:工作区目录,每次 job 执行构建时的工作目录,users 目录,存放与用户相关的配置文件。

3 Jenkins 主程序目录

/usr/lib/jenkins/jenkins.war 是 Jenkins 的主程序

4 其他目录及文件

/var/log/Jenkins Jenkins 日志文件目录
/etc/init.d/Jenkins Jenkins 启动文件

六 Jenkins创建freestyle 项目

构建作业是一个持续集成服务器的基本职能,构建的形式多种多样,可以是编译和单元测试,也可能是打包及部署,或者是其他类似的作业。在 Jenkins 中,构建作业很容易建立,而且根据你的需要你可以安装各种插件,来创建多种形式的构建作业,下面我们先来学习创建自由式构建作业
自由式的构建作业是最灵活和可配置的选项,并且可以用于任何类型的项目,它的配置相对简单,其中很多配置在的选项也会用在其他构建作业中。

在 Jenkins 主页面,点击左侧菜单栏的“新建”或者“New job” 进入创建 job 页面

注:1、job 名称需要有规划,以便于后面的权限管理;2、创建 job 后不要轻易更改名称,因为 jenkins 一切皆文件,很多关于 job 的文件,都是以该名称命名,当你改名后,一般不会删除旧文件,而是会再重新创建一份新的文件。
输入 job 名称,选择类型后,点击 OK 后创建 job,进入 job 配置页面,此时在 Jenkins的主目录下的 jobs 目录已经生成了以你 Job 名称命名的文件夹

Job 配置页面,主要包括通用配置、源码管理、构建触发器、构建环境、构建、构建后操作等几个部分,根据你选择的构建类型不同,可能配置项会有一些小的差别。我们通过几个示例来学习具体的配置。

1 执行linux命令和脚本

首先我们来看通用配置选项

勾选“丢弃旧的构建”,这是我们必须提前考虑的重要方面,就是我们如何处理构建历史,构建作业会消耗大理的磁盘空间,尤其是你存储的构建产物(比如执行 java 构建时会生成的 JAR、WAR 等)

该选项允许你限制在构建历史记录的作业数。你可以告诉 Jenkins 只保留最近的几次构建,或者只保留指定数量的构建,此外,Jenkins 永远不会删除最后一个稳定和成功的构建。具体数据的指定要根据你项目的实际情况而定,我一般设置为 5、5,

下拉至“构建”部分

添加构建操作,选择“execute shell”

保存设置后,回到 job 主页面

点击“立即构建”执行 job 的构建任务,我们的 job 就是执行一条 linux 命令

点击下拉菜单的“console output”

在上面的控制台输出内容中,我们可以看到 job 执行时的当前工作目录为 Jenkins 主目录+workspaces+以 job 名称命名的文件夹,知道这一点对于我们后面写脚本执行部署任务时非常重要。我们也可以通过命令行进行确认。

[root@localhost jobs]# pwd
/var/lib/jenkins/jobs
[root@localhost jobs]# cd /var/lib/jenkins/workspace/My-freestyle-Job/
[root@localhost My-freestyle-Job]# ll
total 0
-rw-r--r--. 1 jenkins jenkins 0 May 15 23:03 a

而且我们进一步也可以看到 job 主页面,工作空间所对应的位置也是此目录。通过这个例子,我们可以联想到,我们可以使用 Jenkins 执行任何 linux 命令,这也就是我们前面讲的要注意 Jenkins 启动用户的配置,如果是 root 用户启动的Jenknis,那Jenkins的安全及权限配置一定要做好控制。我们在学习初期,为了节省时间,可以使用 root 用户启动jenkins。

 2 连接 gitlab 获取仓库代码 

我们使用上面的 job 进行配置,在“源码管理”部分配置拉取 Gitlab 上的 monitor 仓库,该仓库是一个纯 html 代码项目,首先在 Gitlab 上复制仓库地址

然后回到 Jenkins 上 My-freestyle-job 配置页面,下拉到“源码管理”部分,勾选 git选项

根据提示信息显示为 key 认证失败,因为我们使用的 SSH 方式连接仓库,所以需要配置SSH 认证
而我们在 Gitlab上配置的 root用户的公钥,现在我们有两种方式解决认证失败的问题,

1在 jenkins 上配置使用 root 用户的私钥连接 Gitlab,2配置使用 root 用户启动 jenkins。

下面我们来看第一种方式

保存配置后,回到 job 主页面,点击“立即构建”,构建完成后,我们在工作空间内可以看到从 Gitlab 仓库拉到的代码

同时我们在“console output”页面可以看到整个控制台输出内容

在“源码管理”配置部分,我们可以配置从分支获取代码,也可以配置从标签获取代码、还可以配置从某一次 commit 获取代码,如下图所示

3 利用 linux 脚本实现部署

在上面的示例中,我们已经将代码获取至我们 Jenkins 服务器上,由于我们的项目是使用html编写的,不需要编译,直接可以打包发布(实际工作中,可能需要更换配置文件)

(1) 安装httpd

我们在 ci-node1 机子上安装 httpd 服务,并配置服务端口为 10001

Httpd 服务的默认网站放在/var/www/html 目录下,为了简单我们可以将我们的网站发布该目录,实现我们的代码发布,当然在实际工作中我们需要重新配置发布目录

(2) 配置 ssh 免密登录

因为我们要使用脚本将 ci-node1 上的程序代码推送到 ci-node2 上,所以需要配置ci-node1 到 ci-node2 的 ssh 免密码登录

[root@ci-node2 ~]# ssh-copy-id -i /root/.ssh/id_rsa.pub root@10.0.0.11
/usr/bin/ssh-copy-id: INFO: Source of key(s) to be installed:
"/root/.ssh/id_rsa.pub"
/usr/bin/ssh-copy-id: INFO: attempting to log in with the new key(s), to filter
out any that are already installed
/usr/bin/ssh-copy-id: INFO: 1 key(s) remain to be installed -- if you are
prompted now it is to install the new keys
root@10.0.0.11's password:
Number of key(s) added: 1
Now try logging into the machine, with: "ssh 'root@10.0.0.11'"
and check to make sure that only the key(s) you wanted were added

(3) 编写部署脚本(deploy.sh)

[root@localhost My-freestyle-Job]# mkdir /server/scripts -p
[root@localhost My-freestyle-Job]# cd /server/scripts/
#!/bin/bash
#目标服务器 IP 地址
host=$1
#job 名称
job_name=$2
#包名
name=web-$(date +%F)-$(($RANDOM+10000))
#打包
cd /var/lib/jenkins/workspace/${job_name} && tar czf /opt/${name}.tar.gz ./*
#发送包到目标服务器
ssh ${host} "cd /var/www/ && mkdir ${name}"
scp /opt/${name}.tar.gz $host:/var/www/${name}
#解包
ssh ${host} "cd /var/www/${name} && tar xf ${name}.tar.gz && rm -f ${name}.tar.gz"
#使用软链接方式部署服务
ssh ${host} "cd /var/www && rm -rf html && ln -s /var/www/${name} /var/www/html"

(4 )Jenkins 配置构建 

接下来我们在 Jenkins 上配置构建执行我们编写的部署脚本,回到 My-freestyle-job配置页面,配置构建

点击页面上的链接可以查看所有可用的 jenkins 环境变量保存配置
回到 job 主页面,点击“立即构建”后,访问 httpd 服务的主页面,我们发现服务已经部署成功。

 

4 Git push 触发自动构建

在上面的job 中我们已经成功实现了将Gitlab中monitor仓库的代码部署到httpd服务中,但是每次部署需要我们手动去点击“立即构建”,下面我们将实现当 Gitlab 收到push 请求后,就触发 Jenkins 构建,将仓库的变化部署到 httpd 服务中。

(1) Jenkins job 配置构建触发器

回到 My-freestyle-job 的配置页面,下拉到构建触发器部分

勾选 gitlab 触发选项,进入具体配置页面

(2) Gitlab 仓库配置 webhooks

进入 Gitlab 中 monitor 仓库的设置页面

进入集成配置页面,复制 jenkins 触发器配置页面的 url 及 Token

配置完成后,在页面下面测试触发设置我们在 jenkins job 主页面看到构建任务被触发

接着我们将仓库克隆到客户端,在客户端测试触发 push 操作

root@localhost ~]# git clone git@192.168.15.128:backend/monitor.git
Cloning into 'monitor'...
remote: Counting objects: 435, done.
remote: Compressing objects: 100% (372/372), done.
remote: Total 435 (delta 53), reused 435 (delta 53)
Receiving objects: 100% (435/435), 8.78 MiB | 0 bytes/s, done.
Resolving deltas: 100% (53/53), done.
Checking connectivity... done.
#PUSH操作
[root@localhost monitor]# vim index.html 
[root@localhost monitor]# git status
On branch master
Your branch is up-to-date with 'origin/master'.
Changes not staged for commit:
(use "git add <file>..." to update what will be committed)
(use "git checkout -- <file>..." to discard changes in working directory)

 modified:   index.html

no changes added to commit (use "git add" and/or "git commit -a")
[root@localhost monitor]# git add .
[root@localhost monitor]# git commit -m 'modify index'
[master 429055f] modify index
1 file changed, 1 insertion(+), 1 deletion(-)
[root@localhost monitor]# git push -u origin master
Counting objects: 3, done.
Delta compression using up to 2 threads.
Compressing objects: 100% (3/3), done.
Writing objects: 100% (3/3), 311 bytes | 0 bytes/s, done.
Total 3 (delta 2), reused 0 (delta 0)
To 192.168.15.128:backend/monitor.git
    f6070e1..429055f  master -> master
Branch master set up to track remote branch master from origin.

Gitlab 收到本次推送的内容

 

Jenkins 对应的 job 已经触发构建

网站 index.html 内容被更新:

同时我们在 jenkins 中 job 主页面的“最新修改记录”部分可以看到我们的修改日志。

5 配置构建后通知 Gitlab

构建完成后,jenkins 可以把构建的结果反馈给 Gitlab,这样在 Gitlab 上就可以查看每一次 push 后构建的执行结果
首先在 Jenkins上配置,可以访问 Gitlab,打开 jenkins 系统管理—>系统设置页面,下拉找到 Gitlab 部分,

添加认证 注意:TOken为gitlab用户生成的token

在 Gitlab 中 root 用户设置页面,选择左侧 Access Tokens,进入 Access Token 管理页面,

认证添加成功后,回到系统设置页面,为 Gitlab 选择认证并测试,成功后保存退出系统设置。

其次,在 job 配置页面添加构建后操作

保存 job 配置,回到 job 主页面,执行“立即构建”。构建成功后,在 Gitlab 仓库,commits列表页面

 

点击进入后,我们可以看到更多的信息

6 配置构建发送邮件

每次执行完构建任务后,我们都可以通过邮件来通知相关人员构建的执行情况,具体配置如下:

在 jenkins 系统管理—>系统设置,

在系统设置中找到 Jenkins Locaction 填好JenkinsURL跟系统管理员的邮件地址,注意必填

下拉到最下面“邮件通知”部分

注 1、邮箱跟最开始设置的管理员邮箱是一致的,2、密码根据您使用的邮箱进行设置,163、QQ 邮箱,都使用授权码,而不是您的邮件密码

进入 job 配置页面,下拉至构建后操作部分,

E-mail Notification 选项配置比较简单

附加 Editable Email Notification 配置

 七 Jenkins创建maven项目

1 什么是Maven?

Maven 是一个项目管理和综合工具。Maven 提供了开发人员构建一个完整的生命周期框架。开发团队可以自动完成项目的基础工具建设,Maven 使用标准的目录结构和默认构建生命周期
Maven 简化和标准化项目建设过程。处理编译,分配,文档,团队协作和其他任务的无缝连接。 Maven增加可重用性并负责建立相关的任务。
Maven 项目的结构和内容在一个 XML 文件中声明,pom.xml 项目对象模型(POM),这是整个 Maven 系统的基本单元。用来管理项目的构建,相关性和文档。最强大的功能就是能够自动下载项目依赖库

2 Centos 7 下安装 Maven

(1) 安装JDK
可以使用 YUM 方式安装安装 open JDK1.8 版本,也可以使用rpm 安装,这里我们使用 RPM 方式安装

[root@ci-node2 src]# rpm -ivh jdk-8u121-linux-x64.rpm
[root@localhost monitor]# java -version
openjdk version "1.8.0_212"
OpenJDK Runtime Environment (build 1.8.0_212-b04)
OpenJDK 64-Bit Server VM (build 25.212-b04, mixed mode)

(2) 安装Maven

官网:http://maven.apache.org/download.cgi
清华镜像:https://mirrors.tuna.tsinghua.edu.cn/apache/maven/

[root@localhost monitor]# wget https://mirrors.tuna.tsinghua.edu.cn/apache/maven/maven-3/3.3.9/binaries/apache-maven-3.3.9-bin.tar.gz
[root@localhost monitor]# tar xf apache-maven-3.3.9-bin.tar.gz 
[root@localhost monitor]# mv apache-maven-3.3.9 /usr/local/
[root@localhost monitor]# cd /usr/local/
[root@localhost local]# ln -s /usr/local/apache-maven-3.3.9/ /usr/local/maven
[root@localhost local]# /usr/local/maven/bin/mvn -v
Apache Maven 3.3.9 (bb52d8502b132ec0a5a3f4c09453c07478323dc5; 2015-11-10T11:41:47-05:00)
Maven home: /usr/local/maven
Java version: 1.8.0_212, vendor: Oracle Corporation
Java home: /usr/lib/jvm/java-1.8.0-openjdk-1.8.0.212.b04-0.el7_6.x86_64/jre
Default locale: en_US, platform encoding: UTF-8
OS name: "linux", version: "3.10.0-957.el7.x86_64", arch: "amd64", family: "unix"

(3) 配置 Maven

编辑/etc/profile文件,在末尾添加export PATH=/usr/local/apache-maven-3.3.9/bin/:$PATH ,将maven命令加入系统环境变量。

[root@localhost local]# source /etc/profile
[root@localhost local]# mv
mv        mvn       mvnDebug  mvnyjp    mvxattr   
[root@localhost local]# mvn -v
Apache Maven 3.3.9 (bb52d8502b132ec0a5a3f4c09453c07478323dc5; 2015-11-10T11:41:47-05:00)
Maven home: /usr/local/apache-maven-3.3.9

3 认识 Maven 安装目录

安装完成后,maven 的安装目录结构如下:

[root@localhost apache-maven-3.3.9]# ll
total 32
drwxr-xr-x. 2 root root 97 May 16 23:25 bin
drwxr-xr-x. 2 root root 42 May 16 23:25 boot
drwxr-xr-x. 3 root root 63 Nov 10 2015 conf
drwxr-xr-x. 3 root root 4096 May 16 23:25 lib
-rw-r--r--. 1 root root 19335 Nov 10 2015 LICENSE
-rw-r--r--. 1 root root 182 Nov 10 2015 NOTICE
-rw-r--r--. 1 root root 2541 Nov 10 2015 README.txt

bin:该目录包含了mvn运行的脚本,这些脚本用来配置java命令,准备好classpath和相关的Java系统属性,然后执行Java命令。其中mvn是基于UNIX平台的脚本,mvn.bat是基于 Windows 平台的脚本。
boot:该目录只包含一个文件,该文件是一个类加载器框架,Maven 使用该框架加载自己的类库。
conf:该目录包含了一个非常重要的文件 settings.xml。用于全局定义 Maven 的行为。也可以将该文件复制到~/.m2/目录下,在用户范围内定制 Maven 行为。
Lib:该目录包含了所有 Maven 运行时需要的 Java 类库。

4 常用 maven 命令

首先我们创建一个名为 hello-world 的 Maven 项目,项目的目录结构如下:

我们在此项目的基本上测试常用的 maven 命令
mvn clean 命令用于清理项目生产的临时文件,一般是模块下的 target 目录

[root@ci-node2 hello-world]# mvn clean
[INFO] Scanning for projects...
[WARNING]
[WARNING] Some problems were encountered while building the effective

mvn package 命令用于项目打包,会在模块下的 target 目录生成 jar 或者 war 等文件

[root@ci-node2 hello-world]# mvn package
[INFO] Scanning for projects...
[WARNING]
[WARNING] Some problems were encountered while building the effective

mvn test命令用于测试 , 用于执行 src/test/java/下的测试用例,使用 -Dmaven.test.skip=true参数可以跳过测试。

mvn install 命令用于模块安装,将打包好的 jar/war 文件复制到你的本地仓库中,供其他模块使用

[root@ci-node2 hello-world]# mvn install
[INFO] Scanning for projects...
[WARNING]

 5 Maven仓库

在Maven中,任何一个依赖、插件或者项目构建的输出,都可以称之为构件。Maven在某个统一的位置存储所有项目的共享的构件,这个统一的位置,我们就称之为仓库。(仓库就是存放依赖和插件的地方)任何的构件都有唯一的坐标,Maven 根据这个坐标定义了构件在仓库中的唯一存储路径
Maven 仓库分为两类:本地仓库和远程仓库。

远程仓库又可以大致分为以下三类:

  • 中央仓库,这是 Maven 核心自带的远程仓库,它包含了绝大部分开源的构件;
  • 私服是一种特殊的远程仓库,一般是为了节省带宽和时间,在企业局域网内架设的一个私有仓库服务器(如nexus)用其代理所有外部的远程仓库,内部的项目还可以部署到私服上供其他项目使用;
  • 还有就是其他的公开的远程仓库,常见的有 Java.net Maven 库、JBoss Maven 库等。

默认配置下,Maven 根据坐标寻找构件的时候,首先他会查看本地仓库,如果本地仓库存在,则直接使用;如果本地仓库不存在,则 Maven 就会去远程仓库查找,存在则先下载到本地仓库使用,不存在 Maven 就会报错

(1) 本地仓库

顾名思义,就是 Maven 在本地存储构件的地方。maven 的本地仓库,在安装 maven 后并不会创建,它是在第一次执行 maven 命令的时候才被创建。maven 本地仓库的默认位置:无论是 Windows 还是 Linux,在用户的目录下都有一个.m2/repository/的仓库目录,这就是Maven 仓库的默认位置。这个可以通过修改.m2/settings.xml 文件(不存在可以创建)或者maven 安装目录/conf/settings.xml 进行配置。
在 settings.xml 文件中,设置 localRepository 元素的值为想的仓库地址即可

<settings>
    <localRepository>/opt/maven_repository</localRepository>
</settings>

(2) 远程仓库

说到远程仓库先从最核心的中央仓库开始,中央仓库是默认的远程仓库,maven 在安装的时候,自带的就是中央仓库的配置,所有的 maven 项目都会继承超级 pom,具体的说,包含了下面配置的 pom 我们就称之为超级 pom

<repositories>
    <repository>
        <id>central</id>
        <name>Central Repository</name>
        <url>http://repo.maven.apache.org/maven2</url>
        <layout>default</layout>
        <snapshots>
            <enabled>false</enabled>
        </snapshots>
    </repository>
</repositories>

中央仓库包含了绝大多数流行的开源 Java 构件,以及源码、作者信息、SCM、信息、许可证信息等。一般来说,简单的 Java 项目依赖的构件都可以在这里下载得到。
私服是一种特殊的远程仓库,它是架设在局域网内的仓库服务,私服代理广域网上的远程仓库,供局域网内的 Maven 用户使用。
当 Maven 需要下载构件的时候,它从私服请求,如果私服上不存在该构件,则从外部的远程仓库下载,缓存在私服上之后,再为 Maven 的下载请求提供服务。我们还可以把一些无法从外部仓库下载到的构件上传到私服上

Maven 私服的 个特性:

  1. 节省自己的外网带宽:减少重复请求造成的外网带宽消耗
  2. 加速 Maven 构件:如果项目配置了很多外部远程仓库的时候,构建速度就会大大降低
  3. 部署第三方构件:有些构件无法从外部仓库获得的时候,我们可以把这些构件部署到内部仓库(私服)中,供内部 maven 项目使用
  4. 提高稳定性,增强控制:Internet 不稳定的时候,maven 构建也会变的不稳定,一些私服软件还提供了其他的功能
  5. 降低中央仓库的负荷:maven 中央仓库被请求的数量是巨大的,配置私服也可以大大降低中央仓库的压力

(3) 配置使用远程仓库

在平时的开发中,我们往往不会使用默认的中央仓库,默认的中央仓库访问的速度比较慢,访问的人或许很多,有时候也无法满足我们项目的需求,可能项目需要的某些构件中央仓库中是没有的,而在其他远程仓库中有,如 JBoss Maven 仓库。这时,可以在 pom.xml中配置该仓库,代码如下:

<!-- 配置远程仓库 -->
<repositories>
    <repository>
        <id>jboss</id>
        <name>JBoss Repository</name>
        <url>http://repository.jboss.com/maven2/</url>
        <releases>
            <enabled>true</enabled>
            <updatePolicy>daily</updatePolicy>
        </releases>
        <snapshots>
            <enabled>false</enabled>
            <checksumPolicy>warn</checksumPolicy>
        </snapshots>
        <layout>default</layout>
    </repository>
</repositories>

repository:在 repositories 元素下,可以使用 repository 子元素声明一个或者多个远程仓库。
id:仓库声明的唯一 id,尤其需要注意的是,Maven 自带的中央仓库使用的 id 为 central,如果其他仓库声明也使用该 id,就会覆盖中央仓库的配置。
url:指向了仓库的地址,一般来说,该地址都基于 http 协议,Maven 用户都可以在浏览器中打开仓库地址浏览构件
eleases 和 snapshots:用来控制 Maven 对于发布版构件和快照版构件的下载权限。需要注意的是 enabled 子元素,该例中 releases 的 enabled 值为 true,表示开启 JBoss 仓库的发布版本下载支持,而 snapshots 的 enabled 值为 false,表示关闭 JBoss 仓库的快照版本的下载支持。根据该配置,Maven 只会从 JBoss 仓库下载发布版的构件,而不会下载快照版的构件
layout:元素值 default表示仓库的布局是 Maven2及 Maven3的默认布局,而不是 Maven1的布局。基本不会用到 Maven1 的布局。
其他:对于 releases 和 snapshots 来说,除了 enabled,它们还包含另外两个子元素updatePolicy 和 checksumPolicy。
元素 updatePolicy 用来配置 Maven 从远处仓库检查更新的频率,默认值是 daily,表示 Maven 每天检查一次。其他可用的值包括:never-从不检查更新;always-每次构建都检查更新;interval:X-每隔 X 分钟检查一次更新(X 为任意整数)。
元素 checksumPolicy 用来配置 Maven 检查校验和文件的策略。当构建被部署到 Maven仓库中时,会同时部署对应的检验和文件。在下载构件的时候,Maven 会验证校验和文件,如果校验和验证失败,当 checksumPolicy 的值为默认的 warn 时,Maven 会在执行构建时输出警告信息,其他可用的值包括:fail-Maven遇到校验和错误就让构建失败;ignore-使Maven完全忽略校验和错误

6 利用Nexus搭建私有Maven库

Nexus 是一个强大的 Maven 仓库管理器,它极大地简化了本地内部仓库的维护和外部仓库的访问。
Nexus 在代理远程仓库的同时维护本地仓库,以降低中央仓库的负荷,节省外网带宽和时间。
Nexus 是一套“开箱即用”的系统不需要数据库,它使用文件系统加 Lucene 来组织数据。
Nexus 使用 ExtJS 来开发界面,利用 Restlet 来提供完整的 REST APIs,通过 m2eclipse与 Eclipse 集成使用
NExus 支持 WebDAV 与 LDAP 安全身份认证。
Nexus 还提供了强大的仓库管理功能,构件搜索功能,它基于 REST,友好的 UI 是一个extjs 的 REST 客户端,它占用较少的内存,基于简单文件系统而非数据库。

安装并启动Nexus

下载地址:https://www.sonatype.com/download-oss-sonatype

[root@localhost ~]# wget https://sonatype-download.global.ssl.fastly.net/repository/repositoryManager/3/nexus-3.16.1-02-unix.tar.gz
[root@localhost ~]# tar xf nexus-3.16.1-02-unix.tar.gz.1 
[root@localhost ~]# mv nexus-3.16.1-02/ /usr/local/
[root@localhost ~]# ln -s /usr/local/nexus-3.16.1-02/ /usr/local/nexus
[root@localhost ~]# /usr/local/nexus/bin/nexus start
WARNING: ************************************************************
WARNING: Detected execution as "root" user.  This is NOT recommended!
WARNING: ************************************************************
Starting nexus

上面启动成功后会警告不要使用 root 用户启动,这里可以新建一个用户,也可以指定root 用户启动,使他不出现警告,下面配置指定 root 用户启动,编辑 bin 目录下的 nexus.rc文件,修改内容为:
run_as_user="root"

配置Maven 项目使用 Nexus 仓库
在 maven的setting.xml文件中配置私服配置,这种方式配置后所有本地使用该配置的maven项目的pom文件都无需配置私服下载相关配置
在<profiles></profiles>之间加入下面的配置

<profile>
        <id>my-nexus</id>
<repositories>
<!-- 私有库地址-->
    <repository>
        <id>nexus</id>
        <name>nexus</name>
        <url>http://10.0.0.13:8081/repository/maven-public/</url>
        <snapshots>
            <enabled>true</enabled>
        </snapshots>
        <releases>
            <enabled>true</enabled>
        </releases>
    </repository>
</repositories>
<pluginRepositories>
<!--插件库地址-->
    <pluginRepository>
        <id>nexus</id>
        <url>http://192.168.15.128:8081/repository/maven-public/</url>
        <releases>
            <enabled>true</enabled>
        </releases>
        <snapshots>
            <enabled>true</enabled>
        </snapshots>
    </pluginRepository>
</pluginRepositories>

</profile><settings></settings>之间加入下面的配置,激活使用上面的配置
<activeProfiles>
    <activeProfile>my-neuxs</activeProfile>
</activeProfiles>

注:profile 名字要对应
在<mirros></mirros>之间加入如下配置

<mirror>
    <id>nexus-myself</id>
    <!--*指的是访问任何仓库都使用我们的私服-->
    <mirrorOf>*</mirrorOf>
    <name>Nexus myself</name>
    <url>http://192.168.15.128:8081/repository/maven-public/</url>
</mirror>
配置完成后,当我们再次执行 mvn 命令时,下载构件的地址变为我们的私服地址

7 创建Maven Job

1 在 Gitlab 创建一个 java 的代码仓库,我们把前面在命令使用的 helloword 项目初始化为一个 git 仓库,然后 push 到我们的 Gitlab 上(具体方法请参考前面相关内容)。
2 在 jenkins 配置 maven打开系统管理—>全局工具配置页面,下拉新增一个 maven 配置
3 回到 Jenkins 主页面,点击“新建 Item”进入创建 Job 页面
4 输入 Job 名称,选择 maven 类型,点击确认按钮,创建 job,进入 job 配置页面, 通用部分配置“丢弃旧的构建” 配置要执行的 maven 命令,保存配置,返回 job 主页面,执行构建。在“工作空间”我们可以看到构建后的产物

八 Jenkins创建Pipeline项目

1 Jenkins Pipeline简介

Jenkins pipeline是Jenkins 2.0的精髓,是帮助Jenkins实现CI到CD转变的重要角色。
简单来说,就是一套运行于Jenkins上的工作流框架,将原本独立运行于单个或者多个节点的任务连接起来,实现单个任务难以完成的复杂发布流程。
Pipeline的实现方式是一套 Groovy DSL,任何发布流程都可以表述为一段 Groovy 脚本,并且 Jenkins 支持从代码库直接读取脚本,从而实现了Pipeline as Code 的理念。

2 Pipeline 的基本概念和 Jenkinsfile

(1) Pipeline 的几个基本概念

  • Node:一个Node 就是一个Jenkins节点,可以是 Master,也可以是 Slave,是 Pipeline中具体 Step 的运行环境。
  • Stage:一个Pipeline 有多个Stage组成,每个Stage包含一组 Step。注意一个Stage可以跨多个Node执行,即Stage实际上是Step的逻辑分组。
  • Step:是最基本的运行单元,可以是创建一个目录、从代码库中 checkout 代码、执行一个 shell 命令、构建 Docker 镜像、将服务发布到 Kubernetes 集群中。Step由Jenkins和Jenkins各种插件提供。

(2) Jenkinsfile 语法

Jenkins Pipeline 支持两种语法,一种 Declarative Pipeline(声明式),一种 ScriptedPipeline(脚本式)。
声明式的 Pipeline 限制用户使用严格的预选定义的结构,是一种声明式的编程模型,对比脚本式的 Pipeline 学习起来更加简单;
脚本式的 Pipeline 限制比较少,结构和语法的限制由 Groovy 本身决定,是一种命令式的编程模型。所以我们学习使用声明式的方式编写 jenkinsfile。
一般来说 jenkinsfile 会被放在代码库的根目录下。当然也可以在 Web 页面定义。下面是两种不同方式的 jenkinsfile 示例

Jenkinsfile (声明式)

pipeline {
    agent any
    stages {
        stage('Build') {
            steps {
                echo 'Building..'
            }
        }
        stage('Test') {
           steps {
                echo 'Testing..'
            }
        }
        stage('Deploy') {
            steps {
            echo 'Deploying....'
            }
        }
    }
}

前面我们说过,声明式的Pipeline有严格的预定义格式结构,最外层必须是pipeline{},紧接着是agent指示Jenkins分配一个执行器和工作空间来执行下面的Pipeline,stages和steps是申明式Jenkinsfile必须的,所有的stage必须要定义在stages 里,每一个stage下的step要定义在一个steps里

3 PipelineJob示例

(1) 通过Web页面创建jenkinsfile

登录到 jenkins 主页面,点击左侧菜单栏的 New Item

进入到新建Job页面,输入 job 名称,在下面选择 Pipeline 类型,然后点击OK。

打开 Pipeline 配置页面,点 Pipeline 选项卡,下拉到 pipeline 部分,选择 pipeline script,在页面定义 jenkinsfile 的方式,在脚本框输入下面的内容

pipeline {
    agent any
    stages {
        stage('Stage 1') {
            steps {
                echo 'Hello world!'
            }
        }
    }
}

 

保存后回到 Job 主页面,点击“立即构建”,
构建执行完成后,在页面的右侧以图形的形式显示 pipeline 的结构,点击对应的位置可以查看构建执行的情况,

在构建历史处,点击#1查看这次构建的运行情况,点击“console output”可以看到Pipeline的详细运行情况

(2) 通过 scm 获取 Jenkinsfile

首先我们在 gitlab 上的 monitor 仓库的根目录下创建一个 Jenkins 文件,文件的内容为:

pipeline {
    agent any
    stages {
        stage('Stage 1') {
            steps {
                echo 'Hello world!'
            }
        }
    }
}

进入到 scm 配置页面,选择从 git 仓库获取

进入到 git 仓库配置页面,输入仓库地址,配置认证,选择分支等,然后点击保存。

保存配置后,回到Job主页面,执行“立即构件”,在”console output”中,我们可以看到,首先从 gitlab仓库获取了所有的代码文件,然后识别到 Jenkins 文件,执行文件中定义的构建任务

(3) Pipeline 语法生成器

随着Pipeline一起发布的内建的文档,使得创建复杂的 Pipelines更加容易。内建的文档可以根据安装在Jenkins实例中的插件,被自动生成和更新。
内建的文档可以通过链接被找到: localhost:8080/pipeline-syntax/。假设你已经有了一个正运行在本地 8080 端口上的实例。同样的文档可以连接到这里,通过任何项目的左边菜单”Pipeline Syntax”。

语法生成器是动态填充的,其中列出了可供 jenkins 使用的步骤,可用的步骤取决于安装的插件
打开 Pipeline Syntax。

在“示例步骤”下拉菜单中,选择需要的步骤(根据需求选择)

输入所选择步骤需要的参数信息,点击“生成流水线脚本”生成脚本 生成出pipline脚本语句

(4) 使用 pipeline 实现 monitor 仓库代码的发布)

在 Gitlab 在 monitor 仓库的根目录上添加 Jenkinsfile 文件,文件内容如下:

pipeline {
    agent any
    stages {
        stage('replace file') {
            steps {
                echo "replace config file use cp "
            }
        }
        stage('test') {
            steps {
                echo "unit test "
            }
        }
        stage('package') {
                steps {
                    sh 'tar czf /opt/web-${BUILD_ID}.tar.gz ./* --exclude=./git --exclude=Jenkinsfile'
                }
            }
        stage('deploy') {
                steps {
                    sh 'ssh 192.168.15.129 "cd /var/www && mkdir web-${BUILD_ID}"'
                    sh 'scp /opt/web-${BUILD_ID}.tar.gz 192.168.15.129:/var/www/web-${BUILD_ID}'
                    sh 'ssh 192.168.15.129 "cd /var/www/web-${BUILD_ID} && tar xf web-${BUILD_ID}.tar.gz &&rm -f web-${BUILD_ID}.tar.gz"'
                    sh 'ssh 192.168.15.129 "cd /var/www && rm -rf html && ln -s /var/www/web-${BUILD_ID}" /var/www/html'
                }
            }
        stage('test') {
                steps {
                    echo "deploy after test "
                }
            }
    }
}

此 jenkinsfile 包括五个 stage,分为 replace file、test、package、deploy,对于非编译项目,我们一般包括这五个阶段。
在 jenkins 上创建一新的 Job,job 名称为 monitor-web,类型为 pipeline 配置 gitlab 自动触发构建(具体请参与前面部分相关内容)。

配置从 scm 获取 jenkins

保存配置,返回 job 主页面,执行构建即可

九 Jenkins 备份、升级、迁移

1 升级

下载新版 Jenkins.war 文件,替换旧版本 war 文件,重启即可。
Jenkins.war 文件的位置一般为/usr/lib/jenkins/Jenkins.war。

2 迁移、备份

Jenkins 的所有的数据都是以文件的形式存放在 JENKINS_HOME 目录中。
所以不管是迁移还是备份,只需要操作JENKINS_HOME就行。建议将 JENKINS_HOME 打包后在拷贝,windows上可以用 zip,rar 等,Linux 上有 zip,tar 等。然后将打包的文件解压到新的 JENKINS_HOME目录就行了。

3 使用 thinbackup 插件备份

1)安装插件:
安装 ThinBackup 插件,可能 参考前面插件管理部分。

2)配置插件:

3)手动备份

我们到备份目录查看:

[root@localhost conf]# cd /data/jenkins/
[root@localhost jenkins]# ll
total 4
drwxr-xr-x. 4 root root 4096 May 20 02:58 FULL-2019-05-20_02-58

4)测试从备份恢复

我们删除/var/lib/jenkins/job 目录下的 my‐freestyle‐job 目录

[root@localhost jenkins]# rm -rf /var/lib/jenkins/jobs/My-freestyle-Job/
[root@localhost jobs]# ll
total 0
drwxr-xr-x. 3 root root 101 May 20 02:47 monitor-web
drwxr-xr-x. 3 root root 101 May 19 23:59 My-pipeline-job
drwxr-xr-x. 3 root root 101 May 20 02:00 My-pipeline-job01

然后我们使用刚才的备份恢复:

恢复完成后,我发现刚才删除的目录又回来了

[root@localhost jobs]# ll
total 0
drwxr-xr-x. 3 root root 101 May 20 02:58 monitor-web
drwxr-xr-x. 3 root root  38 May 20 02:58 My-freestyle-Job
drwxr-xr-x. 3 root root 101 May 20 02:58 My-pipeline-job
drwxr-xr-x. 3 root root 101 May 20 02:58 My-pipeline-job01

 

posted on 2019-05-16 10:14  cs_1993  阅读(417)  评论(0编辑  收藏  举报