JENKINS 是一个用 JAVA 编写的开源的持续集成工具。在与 ORACLE 发生争执后,项目从HUDSON 项目独立出来。 ? JENKINS 提供了软件开发的持续集成服务。它运行在 SERVLET 容器中(例如APACHE TOMCAT)。它支持软件配置管理(SCM)工具(包括 ACCUREV SCM、CVS、 SUBVERSION、GIT、PERFORCE、CLEARCASE 和 RTC),可以执行基于 APACHE ANT 和 APACHE MAVEN
的项目,以及任意的 SHELL 脚本和 WINDOWS 批处理命令。JENKINS 的主要开发者是川口耕介。JENKINS 是在 MIT 许可证下发布的自由软件。
官方网站:https://jenkins.io/
清华镜像地址:https://mirrors.tuna.tsinghua.edu.cn/jenkins/
最小硬件需求:256M 内存、1G 磁盘空间,通常根据需要 Jenkins 服务器至少 1G 内存, 50G+磁盘空间。
软件需求:由于 jenkins 是使用 java 语言编写的,所以需要安装 java 运行时环境(jdk)
可以从Jenkins 官方网站及清华镜像站下载jenkins 安装包,也可以通过本教程配套的百度网盘下载对应的安装包。本采用jenkins-2.72-1 版本,jdk-8u121-linux-x64。
可以使用 YUM 方式安装安装open JDK1.8 版本,也可以使用我提供的 rpm 安装,我们课程使用RPM 方式安装
[root@ci-node2 src]# rpm -ivh jdk-8u121-linux-x64.rpm
[root@ci-node2 src]# java -version
java version "1.8.0_121"
Java(TM) SE Runtime Environment (build 1.8.0_121-b13)
Java HotSpot(TM) 64-Bit Server VM (build 25.121-b13, mixed mode)
[root@ci-node2 src]# rpm -ivh jenkins-2.72-1.1.noarch.rpm
[root@ci-node2 src]# systemctl start jenkins
[root@ci-node2 src]# systemctl status jenkins
Jenkins 默认监听 8080,服务启动后我们可以在浏览器中输入http://您服务器的 ip 地址:8080 访问 jenkins 服务。
Jenkins 本身是一个引擎、一个框架,只是提供了很简单功能,其强大的功能都是通过插件来实现的,jenkins 有一个庞大的插件生态系统,为 Jenkins 提供丰富的功能扩展。下面我们来介绍常用的几种插件安装方式。
安装完成后,一般情况下不需要重启Jenkins,具体根据提示操作。
除了上面的插件安装方法,Jenkins 还为我们提供了手工安装插件的方式,特别是在国内,由于网络的原因,有时候我们使用上述方法安装插件会经常不成功,所以我们可以采用下载插件,然后再上传的方式来安装插件。
官方的插件下载地址:http://updates.jenkins-ci.org/
国内的源:https://mirrors.tuna.tsinghua.edu.cn/jenkins/plugins/
如果是在官方网站下载插件,最好下载与你 jenkins 版本对应的插件,如果是在清华镜像下载插件,则不存在版本的问题。下载后得到的一个以.hpi 为扩展名的文件
我们可以备份已经安装好插件的 Jenkins 服务器上的/var/lib/jenkins/plugins 目录, 然后把备份文件上传到我们需要安装插件的新 Jenkins 服务器的对应目录上,然后重启Jenkins。
这种方法其实给我们提供了一种更加快速的安装 Jenkins 插件的方法。建议在初始安装jenkins 时,可以使用此方法,其他时候尽量使用前两种方式。
我们本教程使用此方式安装插件。前面我们在初始化 jenkins 的时候,跳过了插件的安装,现在我们的 Jenkins 插件目录为空,因为我们没有安装任何插件:
[root@ci-node2 ~]# cd /var/lib/jenkins/plugins/
[root@ci-node2 plugins]# ll
total 0
从本教程配套的百度网盘下载 plugins.tar.gz 包,该文件包提供了我们所涉及的所有插件,上传该压缩包至 jenkins 服务器,解压后将所有文件都移动到 jenkins的插件目录,
[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 目录及文件的位置
[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
Jenkins 默认的用户为 jenkins,生产环境建议使用 jenkins 用户,然后使用 sudo 进行授权,我们为了避免各种权限问题,改为root 用户。
/var/lib/jenkins 是 Jenkins 默认配置的主工作目录,我们可以在主配置文件进行设置,
[root@ci-node2 ~]# cd /var/lib/jenkins/
[root@node2 jenkins]# ll
total 176
drwxr-xr-x 4 root root 98 Mar 25 14:34 caches
-rw-r--r-- 1 root root 848 Mar 28 09:46 com.dabsquared.gitlabjenkins.connection.GitLabConnectionConfig.xml
-rw-r--r-- 1 jenkins jenkins 365 Mar 25 09:59 com.dabsquared.gitlabjenkins.GitLabPushTrigger.xml
-rw-r--r-- 1 root root 1673 Mar 28 09:46 config.xml
-rw-r--r-- 1 root root 3750 Mar 25 12:27 credentials.xml
-rw-r--r-- 1 root root 278 Mar 25 12:27 envInject.xml
-rw-r--r-- 1 root root 29 Mar 28 21:25 failed-boot-attempts.txt
drwxr-xr-x 7 root root 56 Mar 25 13:48 fingerprints
-rw-r--r-- 1 root root 214 Mar 25 12:27 github-plugin-configuration.xml
-rw-r--r-- 1 root root 807 Mar 25 12:27 hudson.maven.MavenModuleSet.xml
-rw-r--r-- 1 root root 156 Mar 28 09:46 hudson.model.UpdateCenter.xml
-rw-r--r-- 1 root root 250 Mar 25 12:27 hudson.plugins.build_timeout.operations.BuildStepOperation.xml
-rw-r--r-- 1 root root 1192 Mar 25 12:27 hudson.plugins.emailext.ExtendedEmailPublisher.xml
-rw-r--r-- 1 root root 321 Mar 25 12:27 hudson.plugins.git.GitSCM.xml
-rw-r--r-- 1 root root 370 Mar 25 13:40 hudson.plugins.git.GitTool.xml
-rw-r--r-- 1 root root 173 Mar 25 13:40 hudson.plugins.gradle.Gradle.xml
-rw-r--r-- 1 root root 184 Mar 25 12:27 hudson.plugins.jira.JiraProjectProperty.xml
-rw-r--r-- 1 root root 346 Mar 25 12:27 hudson.plugins.timestamper.TimestamperConfig.xml
-rw-r--r-- 1 root root 388 Mar 25 12:27 hudson.scm.SubversionSCM.xml
-rw-r--r-- 1 root root 145 Mar 25 13:40 hudson.tasks.Ant.xml
-rw-r--r-- 1 root root 188 Mar 25 12:27 hudson.tasks.Mailer.xml
-rw-r--r-- 1 root root 320 Mar 25 13:40 hudson.tasks.Maven.xml
-rw-r--r-- 1 root root 76 Mar 25 12:27 hudson.tasks.Shell.xml
-rw-r--r-- 1 root root 216 Mar 25 12:27 hudson.triggers.SCMTrigger.xml
-rw------- 1 jenkins jenkins 1712 Mar 25 09:32 identity.key.enc
-rw-r--r-- 1 jenkins jenkins 5 Mar 25 09:37 jenkins.install.InstallUtil.lastExecVersion
-rw-r--r-- 1 jenkins jenkins 5 Mar 25 09:37 jenkins.install.UpgradeWizard.state
-rw-r--r-- 1 root root 159 Mar 25 12:27 jenkins.model.ArtifactManagerConfiguration.xml
-rw-r--r-- 1 root root 258 Mar 25 12:27 jenkins.model.JenkinsLocationConfiguration.xml
-rw-r--r-- 1 root root 247 Mar 25 13:40 jenkins.mvn.GlobalMavenConfig.xml
-rw-r--r-- 1 jenkins jenkins 171 Mar 25 09:32 jenkins.telemetry.Correlator.xml
drwxr-xr-x 6 jenkins jenkins 86 Mar 25 14:31 jobs
drwxr-xr-x 3 jenkins jenkins 19 Mar 25 09:32 logs
-rw-r--r-- 1 root root 907 Mar 28 09:46 nodeMonitors.xml
drwxr-xr-x 2 jenkins jenkins 6 Mar 25 09:32 nodes
-rw-r--r-- 1 root root 298 Mar 25 13:40 org.jenkinsci.plugins.docker.commons.tools.DockerTool.xml
-rw-r--r-- 1 root root 255 Mar 25 13:40 org.jenkinsci.plugins.gitclient.JGitApacheTool.xml
-rw-r--r-- 1 root root 243 Mar 25 13:40 org.jenkinsci.plugins.gitclient.JGitTool.xml
-rw-r--r-- 1 root root 290 Mar 25 12:27 org.jenkinsci.plugins.pipeline.modeldefinition.config.GlobalConfig.xml
-rw-r--r-- 1 root root 46 Mar 25 14:54 org.jenkinsci.plugins.workflow.flow.FlowExecutionList.xml
-rw-r--r-- 1 root root 218 Mar 25 12:27 org.jenkinsci.plugins.workflow.libs.GlobalLibraries.xml
-rw-r--r-- 1 root root 185 Mar 25 12:27 org.jvnet.hudson.plugins.SSHBuildWrapper.xml
drwxr-xr-x 97 jenkins jenkins 8192 Mar 25 09:53 plugins
-rw-r--r-- 1 root root 130 Mar 25 15:02 queue.xml.bak
-rw-r--r-- 1 root root 369 Mar 25 12:27 scriptApproval.xml
-rw-r--r-- 1 jenkins jenkins 64 Mar 25 09:31 secret.key
-rw-r--r-- 1 jenkins jenkins 0 Mar 25 09:31 secret.key.not-so-secret
drwx------ 4 jenkins jenkins 4096 Mar 25 11:26 secrets
-rw-r--r-- 1 jenkins jenkins 0 Mar 28 10:27 ThinBackup Worker Thread.log
drwxr-xr-x 2 jenkins jenkins 149 Mar 28 09:47 updates
drwxr-xr-x 2 jenkins jenkins 24 Mar 25 09:32 userContent
drwxr-xr-x 4 jenkins jenkins 94 Mar 25 12:29 users
drwxr-xr-x 2 jenkins jenkins 6 Mar 25 09:59 workflow-libs
drwxr-xr-x 8 jenkins jenkins 148 Mar 25 14:34 workspace
[root@node2 jenkins]#
其中主要的目录为 jobs 目录:存放 jobs 的配置及每次构建的结果;plugins 目录: Jenkins 插件目录,存放我们已经安装的插件;worksspace:工作区目录,每次 job 执行构建时的工作目录,users 目录,存放与用户相关的配置文件。
/usr/lib/jenkins/jenkins.war 是 Jenkins 的主程序
/var/log/Jenkins Jenkins 日志文件目录
/etc/init.d/Jenkins Jenkins 启动文件
构建作业是一个持续集成服务器的基本职能,构建叙利亚的形式多种多样,可以是编译和单元测试,也可能是打包及部署,或者是其他类似的作业。
在 Jenkins 中,构建作业很容易建立,而且根据你的需要你可以安装各种插件,来创建多种形式的构建作业,下面我们先来学习创建自由式构建作业。
自由式的构建作业是最灵活和可配置的选项,并且可以用于任何类型的项目,它的配置相对简单,其中很多配置在的选项也会用在其他构建作业中。
在Jenkins 主页面,点击左侧菜单栏的“新建”或者“New job”
注:
1、job 名称需要有规划,以便于后面的权限管理;
2、创建 job 后不要轻易更改名称,因为 jenkins 一切皆文件,很多关于 job 的文件,都是以该名称命名,当你改名后,一般不会删除旧文件,而是会再重新创建一份新的文件。
输入job 名称,选择类型后,点击 OK 后创建 job,进入 job 配置页面,此时在 Jenkins 的主目录下的jobs 目录已经生成了以你Job 名称命名的文件夹
Job 配置页面,主要包括通用配置、源码管理、构建触发器、构建环境、构建、构建后操作等几个部分,根据你选择的构建类型不同,可能配置项会有一些小的差别。我们通过几个示例来学习具体的配置。
在上面的控制台输出内容中,我们可以看到 job 执行时的当前工作目录为 Jenkins 主目录+workspaces+以job 名称命名的文件夹,知道这一点对于我们后面写脚本执行部署任务时非常重要。我们也可以通过命令行进行确认。
[root@ci-node2 ~]# cd /var/lib/jenkins/workspace/
[root@ci-node2 workspace]# pwd
/var/lib/jenkins/workspace
[root@ci-node2 workspace]# ll
total 0
drwxr-xr-x 2 jenkins jenkins 15 Aug 5 12:43 My-freestyle-job
[root@ci-node2 workspace]# cd My-freestyle-job/
[root@ci-node2 My-freestyle-job]# ll
total 0
-rw-r--r-- 1 jenkins jenkins 0 Aug 5 12:45 a
[root@ci-node2 My-freestyle-job]#
而且我们进一步也可以看到job 主页面,工作空间所对应的位置也是此目录。
通过这个例子,我们可以联想到,我们可以使用 Jenkins 执行任何 linux 命令,这也就是我们前面讲的要注意 Jenkins 启动用户的配置,如果是 root 用户启动的 Jenknis,那 Jenkins 的安全及权限配置一定要做好控制。
我们在初期,为了节省时间,可以使用 root 用户启动jenkins。
我们使用上面的 job 进行配置,在“源码管理”部分配置拉取 Gitlab 上的 monitor 仓库,该仓库是一个纯html 代码项目,首先在Gitlab 上复制仓库地址,
然后回到 Jenkins 上 My-freestyle-job 配置页面,下拉到“源码管理”部分,勾选 git 选项
粘贴完仓库地址后,出现如下图所示错误提示
首先要安装git
yum install -y git
根据提示信息显示为 key 认证失败,因为我们使用的 SSH 方式连接仓库,所以需要配置SSH 认证。
实际上在前面我们学习Gitlab 的时候,我们已经配置了ci-node2 这台机子的root 用户的公钥在 Gitlab 上的 dev 用户。
为什么我们这里还需要认证?下面我们来查看一下Jenkins 服务的启动用户,
而我们在Gitlab 上配置的root 用户的公钥,现在我们有两种方式解决认证失败的问题,
1、在 jenkins 上配置使用root 用户的私钥连接Gitlab,
2、配置使用 root 用户启动 jenkins。下面我们先来看第一种方式
在上面的示例中,我们已经将代码获取至我们 Jenkins 服务器上,由于我们的项目是使用html 编写的,不需要编译,直接可以打包发布(实际工作中,可能需要更换配置文件)。
因为我们要使用脚本将 ci-node2 上的程序代码推送到 ci-node1 上,所以需要配置ci-node2 到 ci-node1 的 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.
[root@ci-node2 ~]# ssh 10.0.0.11
Last login: Sun Aug 5 15:49:42 2018 from 10.0.0.1
[root@ci-node1 ~]# ip add
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN qlen 1
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
inet 127.0.0.1/8 scope host lo
valid_lft forever preferred_lft forever
inet6 ::1/128 scope host
valid_lft forever preferred_lft forever
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP qlen 1000
link/ether 00:0c:29:d1:39:d9 brd ff:ff:ff:ff:ff:ff
inet 10.0.0.11/24 brd 10.0.0.255 scope global eth0 valid_lft forever preferred_lft forever
[root@node2 my-freestyle-job]# cat /server/scripts/deploy.sh
#!/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"
在上面的 job 中,我们已经成功实现了将 Gitlab 中 monitor 仓库的代码部署到 httpd 服务中,但是每次部署需要我们手动去点击“立即构建”,下面我们将实现当 Gitlab 收到 push 请求后,就触发 Jenkins 构建,将仓库的变化部署到 httpd 服务中。
接着我们将仓库克隆到客户端,在客户端测试触发push 操作
//克隆 monitor 仓库到 ci-node1 本地
[root@ci-node1 ~]# git clone git@10.0.0.11:oldboy/monitor.git
Cloning into ‘monitor‘...
remote: Counting objects: 437, done.
remote: Compressing objects: 100% (374/374), done. remote: Total 437 (delta 53), reused 435 (delta 53)
Receiving objects: 100% (437/437), 8.78 MiB | 0 bytes/s, done. Resolving deltas: 100% (53/53), done.
//更改index.html 文件,push 至 Gitlab
[root@ci-node1 ~]# cd monitor/
[root@ci-node1 monitor]# vim index.html
[root@ci-node1 monitor]# git add .
[root@ci-node1 monitor]# git commit -m "modify index.html on ci-node1"
[master 7ed09e1] modify index.html on ci-node1
1 file changed, 1 insertion(+), 1 deletion(-)
[root@ci-node1 monitor]# git push -u origin master
Counting objects: 5, done.
Delta compression using up to 2 threads. Compressing objects: 100% (3/3), done.
Writing objects: 100% (3/3), 326 bytes | 0 bytes/s, done. Total 3 (delta 2), reused 0 (delta 0)
To git@10.0.0.11:oldboy/monitor.git
f6070e1..7ed09e1 master -> master
Branch master set up to track remote branch master from origin.
Gitlab 收到本次推送的内容,
每次执行完构建任务后,我们都可以通过邮件来通知相关人员构建的执行情况,具体配置如下:
全局配置
在jenkins 系统管理—>系统设置,在系统设置中找到 Jenkins Locaction 填好 JenkinsURL 跟系统管理员的邮件地址,注意必填
Maven 是一个项目管理和综合工具。Maven 提供了开发人员构建一个完整的生命周期框架。开发团队可以自动完成项目的基础工具建设,Maven 使用标准的目录结构和默认构建生命周期。
Maven 简化和标准化项目建设过程。处理编译,分配,文档,团队协作和其他任务的无缝连接。 Maven 增加可重用性并负责建立相关的任务。
Maven 项目的结构和内容在一个XML 文件中声明,pom.xml 项目对象模型(POM),这是整个Maven 系统的基本单元。用来管理项目的构建,相关性和文档。最强大的功能就是能够自动下载项目依赖库。
可以使用 YUM 方式安装安装open JDK1.8 版本,也可以使用我提供的 rpm 安装,我们课程使用RPM 方式安装
[root@ci-node2 src]# rpm -ivh jdk-8u121-linux-x64.rpm
[root@ci-node2 src]# java -version java version "1.8.0_121"
Java(TM) SE Runtime Environment (build 1.8.0_121-b13)
Java HotSpot(TM) 64-Bit Server VM (build 25.121-b13, mixed mode)
官网:http://maven.apache.org/download.cgi
清华镜像:https://mirrors.tuna.tsinghua.edu.cn/apache/maven/
[root@ci-node2 src]# wget https://mirrors.tuna.tsinghua.edu.cn/apache/maven/maven-3/3.3.9/binaries/apache-maven-3.3.9-bin.tar.gz
[root@ci-node2 src]# tar xf apache-maven-3.3.9-bin.tar.gz
[root@ci-node2 src]# mv apache-maven-3.3.9 /usr/local/
[root@ci-node2 src]# cd /usr/local/
[root@ci-node2 local]# ln -s /usr/local/apache-maven-3.3.9/ /usr/local/maven
[root@ci-node2 local]# /usr/local/maven/bin/mvn -v
Apache Maven 3.3.9 (bb52d8502b132ec0a5a3f4c09453c07478323dc5; 2015-11-11T00:41:47+08:00)
Maven home: /usr/local/maven
Java version: 1.8.0_121, vendor: Oracle Corporation Java home: /usr/java/jdk1.8.0_121/jre
Default locale: en_US, platform encoding: UTF-8
OS name: "linux", version: "3.10.0-693.el7.x86_64", arch: "amd64", family: "unix"
编辑/etc/profile文件,在末尾添加export PATH=/usr/local/apache-maven-3.3.9/bin/:$PATH ,将 maven 命令加入系统环境变量。
[root@ci-node2 local]# source /etc/profile
[root@ci-node2 local]# mvn -v
Apache Maven 3.3.9 (bb52d8502b132ec0a5a3f4c09453c07478323dc5; 2015-11-11T00:41:47+08:00)
Maven home: /usr/local/apache-maven-3.3.9
Java version: 1.8.0_121, vendor: Oracle Corporation Java home: /usr/java/jdk1.8.0_121/jre
Default locale: en_US, platform encoding: UTF-8
OS name: "linux", version: "3.10.0-693.el7.x86_64", arch: "amd64", family: "unix"
安装完成后,maven 的安装目录结构如下:
bin:该目录包含了 mvn 运行的脚本,这些脚本用来配置 java 命令,准备好 classpath 和相关的 Java 系统属性,然后执行 Java 命令。其中 mvn 是基于 UNIX 平台的脚本,mvn.bat 是基于Windows 平台的脚本。
boot:该目录只包含一个文件,该文件是一个类加载器框架,Maven 使用该框架加载自己的类库。
conf:该目录包含了一个非常重要的文件 settings.xml。用于全局定义 Maven 的行为。也可以将该文件复制到~/.m2/目录下,在用户范围内定制Maven 行为。
Lib:该目录包含了所有Maven 运行时需要的Java 类库。
我们在此项目的基本上测试常用的maven 命令
mvn clean 命令用于清理项目生产的临时文件,一般是模块下的 target 目录
[root@ci-node2 hello-world]# mvn clean
mvn package 命令用于项目打包,会在模块下的 target 目录生成 jar 或者 war 等文件
[root@ci-node2 hello-world]# mvn package
mvn test 命 令用 于测 试 , 用于 执行 src/test/java/ 下的 测 试用例,使 用-Dmaven.test.skip=true参数可以跳过测试。
[root@ci-node2 hello-world]# mvn test
mvn install 命令用于模块安装,将打包好的jar/war 文件复制到你的本地仓库中,供其他模块使用
[root@ci-node2 hello-world]# mvn install
在Maven 中,任何一个依赖、插件或者项目构建的输出,都可以称之为构件。Maven 在某个统一的位置存储所有项目的共享的构件,这个统一的位置,我们就称之为仓库。
(仓库就是存放依赖和插件的地方)任何的构件都有唯一的坐标,Maven 根据这个坐标定义了构件在仓库中的唯一存储路径。
Maven 仓库分为两类:本地仓库和远程仓库。
远程仓库又可以大致分为以下三类:
中央仓库,这是 Maven 核心自带的远程仓库,它包含了绝大部分开源的构件;
私服是一种特殊的远程仓库,一般是为了节省带宽和时间,在企业局域网内架设的一个私有仓库服务器(如nexus)用其代理所有外部的远程仓库,内部的项目还可以部署到私服上供其他项目使用;
还有就是其他的公开的远程仓库,常见的有Java.net Maven 库、JBoss Maven 库等。
默认配置下,Maven 根据坐标寻找构件的时候,首先他会查看本地仓库,如果本地仓库存在,则直接使用;
如果本地仓库不存在,则 Maven 就会去远程仓库查找,存在则先下载到本地仓库使用,不存在Maven 就会报错。
顾名思义,就是 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>
通过我们建议修改.m2 目录下的 setting.xml 文件,修改只针对用户。
说到远程仓库先从最核心的中央仓库开始,中央仓库是默认的远程仓库,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 中央仓库被请求的数量是巨大的,配置私服也可以大大降低中央仓库的压力
当前主流的maven 私服:1.Apache 的Archiva、2.JFrog 的 Artifactory、3.Sonatype 的Nexus
在平时的开发中,我们往往不会使用默认的中央仓库,默认的中央仓库访问的速度比较慢,访问的人或许很多,有时候也无法满足我们项目的需求,可能项目需要的某些构件中央仓库中是没有的,而在其他远程仓库中有,如 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,就会覆盖中央仓库的配置。
name:仓库的名称,让我们直观方便的知道仓库是哪个,暂时没发现其他太大的含义。url:指向了仓库的地址,一般来说,该地址都基于 http 协议,Maven 用户都可以在浏览器中打开仓库地址浏览构件。
releases 和 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 完全忽略校验和错误
Nexus 是一个强大的 Maven 仓库管理器,它极大地简化了本地内部仓库的维护和外部仓库的访问。
Nexus 在代理远程仓库的同时维护本地仓库,以降低中央仓库的负荷,节省外网带宽和时间。
Nexus 是一套“开箱即用”的系统不需要数据库,它使用文件系统加 Lucene 来组织数据。
Nexus 使用 ExtJS 来开发界面,利用 Restlet 来提供完整的 REST APIs,通过 m2eclipse 与Eclipse 集成使用。
Nexus 支持 WebDAV 与 LDAP 安全身份认证。
Nexus 还提供了强大的仓库管理功能,构件搜索功能,它基于 REST,友好的 UI 是一个extjs 的 REST 客户端,它占用较少的内存,基于简单文件系统而非数据库。
运行 Nexus 需要 Java 8 的运行时环境支持,可以使用 YUM 方式安装安装 open JDK1.8 版本,也可以使用我提供的rpm 安装,我们课程使用RPM 方式安装
[root@ci-node2 src]# rpm -ivh jdk-8u121-linux-x64.rpm
[root@ci-node2 src]# java -version
java version "1.8.0_121"
Java(TM) SE Runtime Environment (build 1.8.0_121-b13)
Java HotSpot(TM) 64-Bit Server VM (build 25.121-b13, mixed mode)
下载地址:https://www.sonatype.com/download-oss-sonatype
[root@ci-node3 src]# wget https://www.sonatype.com/oss-thank-you-tar.gz
[root@ci-node3 src]# ll
total 68
-rw-r--r-- 1 root root 66566 Aug 7 01:19 oss-thank-you-tar.gz
[root@ci-node3 src]# tar xf nexus-3.13.0-01-unix.tar.gz
[root@ci-node3 src]# mv nexus-3.13.0-01 /usr/local/
[root@ci-node3 src]# ln -s /usr/local/nexus-3.13.0-01/ /usr/local/nexus
[root@ci-node3 nexus]# /usr/local/nexus/bin/nexus start
上面启动成功后会警告不要使用root 用户启动,这里可以新建一个用户,也可以指定root 用户启动,使他不出现警告,下面配置指定 root 用户启动,编辑 bin 目录下的nexus.rc 文件,修改内容为:
run_as_user="root"
在maven 的setting.xml 文件中配置私服配置,这种方式配置后所有本地使用该配置的maven 项目的 pom 文件都无需配置私服下载相关配置
<?xml version="1.0" encoding="UTF-8"?>
<settings xmlns="http://maven.apache.org/SETTINGS/1.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/SETTINGS/1.0.0 http://maven.apache.org/xsd/settings-1.0.0.xsd">
<pluginGroups>
</pluginGroups>
<proxies>
</proxies>
<servers>
</servers>
<mirrors>
<!-- 新加-->
<mirror>
<id>nexus-myself</id>
<!--指的是访问任何仓库都使用我们的私服-->
<mirrorOf></mirrorOf>
<name>Nexus myself</name>
<url>http://10.0.0.12:8081/repository/maven-public/</url>
</mirror>
<!-- 新加-->
</mirrors>
<profiles>
<!-- 新加-->
<profile>
<id>my-nexus</id>
<repositories>
<!-- 私有库地址-->
<repository>
<id>nexus</id>
<name>nexus</name>
<url>http://10.0.0.12:8081/repository/maven-public/</url>
<snapshots>
<enabled>true</enabled>
</snapshots>
<releases>
<enabled>true</enabled>
</releases>
</repository>
</repositories>
<pluginRepositories>
<!--插件库地址-->
<pluginRepository>
<id>nexus</id>
<url>http://10.0.0.12:8081/repository/maven-public/</url>
<releases>
<enabled>true</enabled>
</releases>
<snapshots>
<enabled>true</enabled>
</snapshots>
</pluginRepository>
</pluginRepositories>
</profile>
<!-- 新加-->
</profiles>
<!-- 激活上面的配置-->
<activeProfiles>
<activeProfile>my-neuxs</activeProfile>
</activeProfiles>
<!-- 激活上面的配置-->
</settings>
配置完成后,当我们再次执行mvn 命令时,下载构件的地址变为我们的私服地址
cd /jenkins/java-demo
1、在 Gitlab 创建一个 java 的代码仓库,我们把前面在命令使用的 helloword 项目初始化为一个git 仓库,然后push 到我们的Gitlab 上(具体方法请参考前面相关内容)。
[root@node2 java-demo]# git config --global user.email 123@qq.com
[root@node2 java-demo]# git config --global user.name vita
[root@node2 java-demo]# git init
Initialized empty Git repository in /jenkins/java-demo/.git/
[root@node2 java-demo]# git remote add origin git@10.0.0.11:oldboy/hello-word.git
[root@node2 java-demo]# git add .
[root@node2 java-demo]# git commit -m "hello word"
[master (root-commit) f3450a4] hello word
3 files changed, 67 insertions(+)
create mode 100644 pom.xml
create mode 100644 src/main/java/com/zlcook/studymvn/helloword/HelloWord.java
create mode 100644 src/test/java/com/zlcook/studymvn/helloword/HelloWordTest.java
[root@node2 java-demo]# git push -u origin master
Counting objects: 18, done.
Compressing objects: 100% (6/6), done.
Writing objects: 100% (18/18), 1.83 KiB | 0 bytes/s, done.
Total 18 (delta 0), reused 0 (delta 0)
To git@10.0.0.11:oldboy/hello-word.git
*[new branch] master -> master
Branch master set up to track remote branch master from origin.
2、在jenkins 配置 maven
打开系统管理—>全局工具配置页面,下拉新增一个maven 配置
Jenkins pipeline 是Jenkins 2.0 的精髓,,是帮助 Jenkins 实现 CI 到 CD 转变的重要角色。
简单来说,就是一套运行于 Jenkins 上的工作流框架,将原本独立运行于单个或者多个节点的任务连接起来,实现单个任务难以完成的复杂发布流程。
Pipeline 的实现方式是一套Groovy DSL,任何发布流程都可以表述为一段 Groovy 脚本,并且 Jenkins 支持从代码库直接读取脚本,从而实现了Pipeline as Code 的理念。
Node:一个 Node 就是一个 Jenkins 节点,可以是 Master,也可以是 Slave,是 Pipeline 中具体Step 的运行环境。
Stage:一个 Pipeline 有多个 Stage 组成,每个 Stage 包含一组 Step。注意一个 Stage 可以跨多个Node 执行,即Stage 实际上是Step 的逻辑分组。
Step:是最基本的运行单元,可以是创建一个目录、从代码库中 checkout 代码、执行一个 shell 命令、构建 Docker 镜像、将服务发布到 Kubernetes 集群中。Step 由 Jenkins和Jenkins 各种插件提供。
Jenkins Pipeline 支持两种语法,一种 Declarative Pipeline(声明式),一种 Scripted Pipeline(脚本式)。
声明式的 Pipeline 限制用户使用严格的预选定义的结构,是一种声明式的编程模型,对比脚本式的 Pipeline 学习起来更加简单;
脚本式的 Pipeline 限制比较少, 结构和语法的限制由 Groovy 本身决定,是一种命令式的编程模型。
所以我们学习使用声明式的方式编写jenkinsfile。一般来说 jenkinsfile 会被放在代码库的根目录下。
当然也可以在Web 页面定义。
下面是两种不同方式的jenkinsfile 示例
1.Jenkinsfile (声明式)
声明式的Pipeline 有严格的预定义格式结构,最外层必须是 pipeline{},
紧接着是 agent 指示 Jenkins 分配一个执行器和工作空间来执行下面的 Pipeline,
stages 和steps 是申明式Jenkinsfile 必须的,
所有的stage 必须要定义在stages 里,
每一个stage 下的step 要定义在一个steps 里
pipeline {
agent any
stages {
stage(‘Build‘) {
steps {
echo ‘Building..‘
}
}
stage(‘Test‘) {
steps {
echo ‘Testing..‘
}
}
stage(‘Deploy‘) {
steps {
echo ‘Deploying. ‘
}
}
}
}
2.Jenkinsfile (脚本式)
在脚本式 jenkinsfile 里,你可以定义一个 node 或者多个 node 块,
然后在 node 块里定义你的stage
,在 stage 里定义你的 step 即可。
node {
stage(‘Build‘) {
//
}
stage(‘Test‘) {
//
}
stage(‘Deploy‘) {
//
}
}
3、打开 Pipeline 配置页面,点 Pipeline 选项卡,下拉到 pipeline 部分,选择 pipeline
script,在页面定义jenkinsfile 的方式,在脚本框输入下面的内容
pipeline {
agent any
stages {
stage(‘Stage 1‘) {
steps {
echo ‘Hello world!‘
}
}
}
}
首先我们在 gitlab 上的 monitor 仓库的根目录下创建一个 Jenkins 文件,文件的内容为:
pipeline {
agent any
stages {
stage(‘Stage 1‘) {
steps {
echo ‘Hello world!‘
}
}
}
}
随着 Pipeline 一起发布的内建的文档,使得创建复杂的 Pipelines 更加容易。内建的文档可以根据安装在Jenkins 实例中的插件,被自动生成和更新。
内建的文档可以通过链接被找到: localhost:8080/pipeline-syntax/。假设你已经有了一个正运行在本地 8080 端口上的实例。同样的文档可以连接到这里,通过任何项目的左边菜单”Pipeline Syntax”。
1、在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 10.0.0.11 "cd /var/www && mkdir web-${BUILD_ID}"‘
sh ‘scp /opt/web-${BUILD_ID}.tar.gz 10.0.0.11:/var/www/web-${BUILD_ID}‘
sh ‘ssh 10.0.0.11 "cd /var/www/web-${BUILD_ID} && tar xf web-${BUILD_ID}.tar.gz &&rm -f web-${BUILD_ID}.tar.gz"‘
sh ‘ssh 10.0.0.11 "cd /var/www && rm -rf html && ln -s /var/www/web-${BUILD_ID}" /var/www/html‘
}
}
}
}
此 jenkinsfile 包括五个 stage,分为 replace file、test、package、deploy,对于非编译项目,我们一般包括这五个阶段。
Jenkins 本身自带安全管理的功能,但是一般情况下很少去使用,更多是使用插件的方式进行更加灵活的处理。
Jenkins 的权限管理需要依赖 Jenkins 的权限管理插件。通过配置插件 role-base,可以很方便给不同用户不同job 的管理和执行权限。
在系统管理、插件管理中搜索 role-base 插件,可以进行安装,具体安装过程我们就不再叙述,大家可以查看我们插件管理部分的内容。
插件安装完成之后,我们需要在“配置全局安全”中启用插件,打开“系统管理->全局安全配置”页面,
下载新版Jenkins.war 文件,替换旧版本war 文件,重启即可。Jenkins.war 文件的位置一般为/usr/lib/jenkins/Jenkins.war。
Jenkins 的所有的数据都是以文件的形式存放在 JENKINS_HOME 目录中。所以不管是迁移还是备份,只需要操作 JENKINS_HOME 就行。
建议将 JENKINS_HOME 打包后在拷贝,windows 上可以用zip,rar 等,Linux 上有 zip,tar 等。然后将打包的文件解压到新的 JENKINS_HOME 目录就行了。
[root@node3 FULL-2017-12-08_15-48]# cd ..
[root@node3 jenkins]# ll /data/jenkins/
total 4
drwxr-xr-x 5 root root 4096 Dec 8 15:48 FULL-2017-12-08_15-48
[root@node3 jenkins]# ll /data/jenkins/FULL-2017-12-08_15-48/
total 172
-rw-r--r-- 1 root root 858 Dec 8 14:27com.dabsquared.gitlabjenkins.connection.GitLabConnectionConfig.xml
-rw-r--r-- 1 root root 365 Dec 6 17:25com.dabsquared.gitlabjenkins.GitLabPushTrigger.xml
-rw-r--r-- 1 root root 4529 Dec 8 14:27 config.xml
-rw-r--r-- 1 root root 1809 Dec 8 15:05 credentials.xml
-rw-r--r-- 1 root root 341 Dec 8 13:33 envinject-plugin-configuration.xml
-rw-r--r-- 1 root root 278 Dec 7 20:33 envInject.xml
-rw-r--r-- 1 root root 214 Dec 7 20:33 github-plugin-configuration.xml
-rw-r--r-- 1 root root 807 Dec 7 20:33 hudson.maven.MavenModuleSet.xml
-rw-r--r-- 1 root root 159 Dec 8 14:27 hudson.model.UpdateCenter.xml
-rw-r--r-- 1 root root 250 Dec 7 20:33hudson.plugins.build_timeout.operations.BuildStepOperation.xml
-rw-r--r-- 1 root root 1228 Dec 7 20:33hudson.plugins.emailext.ExtendedEmailPublisher.xml
-rw-r--r-- 1 root root 321 Dec 7 20:33 hudson.plugins.git.GitSCM.xml
-rw-r--r-- 1 root root 370 Dec 8 10:05 hudson.plugins.git.GitTool.xml
-rw-r--r-- 1 root root 173 Dec 8 10:05 hudson.plugins.gradle.Gradle.xml
-rw-r--r-- 1 root root 184 Dec 7 20:33hudson.plugins.jira.JiraProjectProperty.xml
-rw-r--r-- 1 root root 346 Dec 7 20:33hudson.plugins.timestamper.TimestamperConfig.xml
-rw-r--r-- 1 root root 388 Dec 7 20:33 hudson.scm.SubversionSCM.xml
-rw-r--r-- 1 root root 145 Dec 8 10:05 hudson.tasks.Ant.xml
-rw-r--r-- 1 root root 188 Dec 7 20:33 hudson.tasks.Mailer.xml
-rw-r--r-- 1 root root 320 Dec 8 10:05 hudson.tasks.Maven.xml
-rw-r--r-- 1 root root 76 Dec 7 20:33 hudson.tasks.Shell.xml
-rw-r--r-- 1 root root 215 Dec 7 20:33 hudson.triggers.SCMTrigger.xml
-rw-r--r-- 1 root root 8990 Dec 8 15:48 installedPlugins.xml
-rw-r--r-- 1 root root 94 Dec 8 13:33 jenkins.CLI.xml
-rw-r--r-- 1 root root 159 Dec 7 20:33jenkins.model.ArtifactManagerConfiguration.xml
-rw-r--r-- 1 root root 138 Dec 8 13:33 jenkins.model.DownloadSettings.xml
-rw-r--r-- 1 root root 264 Dec 7 20:33jenkins.model.JenkinsLocationConfiguration.xml
-rw-r--r-- 1 root root 247 Dec 8 10:05 jenkins.mvn.GlobalMavenConfig.xml
-rw-r--r-- 1 root root 169 Dec 8 13:33jenkins.security.QueueItemAuthenticatorConfiguration.xml
-rw-r--r-- 1 root root 162 Dec 8 13:33jenkins.security.UpdateSiteWarningsConfiguration.xml
drwxr-xr-x 6 root root 94 Dec 8 15:48 jobs
-rw-r--r-- 1 root root 907 Dec 8 14:27 nodeMonitors.xml
drwxr-xr-x 4 root root 60 Dec 8 15:04 nodes
-rw-r--r-- 1 root root 298 Dec 8 10:05org.jenkinsci.plugins.docker.commons.tools.DockerTool.xml
-rw-r--r-- 1 root root 255 Dec 8 10:05org.jenkinsci.plugins.gitclient.JGitApacheTool.xml
-rw-r--r-- 1 root root 243 Dec 8 10:05org.jenkinsci.plugins.gitclient.JGitTool.xml
-rw-r--r-- 1 root root 290 Dec 7 20:33org.jenkinsci.plugins.pipeline.modeldefinition.config.GlobalConfig.xml
-rw-r--r-- 1 root root 46 Dec 8 00:14org.jenkinsci.plugins.workflow.flow.FlowExecutionList.xml
-rw-r--r-- 1 root root 218 Dec 7 20:33org.jenkinsci.plugins.workflow.libs.GlobalLibraries.xml
-rw-r--r-- 1 root root 185 Dec 7 20:33org.jvnet.hudson.plugins.SSHBuildWrapper.xml
-rw-r--r-- 1 root root 369 Dec 6 22:46 scriptApproval.xml
-rw-r--r-- 1 root root 1010 Dec 8 15:47 thinBackup.xml drwxr-xr-x 4 root root 31 Dec 8 13:35 users
4)测试从备份恢复
我们删除/var/lib/jenkins/job 目录下的 my‐freestyle‐job 目录,
[root@node3 jobs]# rm my-freestyle-job -rf
[root@node3 jobs]# ll
total 0
drwxr-xr-x 3 root root 38 Dec 8 15:48 accout-maven-job
drwxr-xr-x 3 root root 101 Dec 8 15:48 frontend-job
drwxr-xr-x 3 root root 101 Dec 8 15:48 pipline-demo
[root@node3 jobs]#
然后我们使用刚才的备份恢复:
恢复完成后,我发现刚才删除的目录又回来了:
[root@node3 jobs]# ll total 0
drwxr-xr-x 3 root root 38 Dec 8 15:48 accout-maven-job
drwxr-xr-x 3 root root 101 Dec 8 15:48 frontend-job
drwxr-xr-x 3 root root 38 Dec 8 15:48 my-freestyle-job
drwxr-xr-x 3 root root 101 Dec 8 15:48 pipline-demo
[root@node3 jobs]#
原文:https://blog.51cto.com/10983441/2426240