一、基本概念解释
1、持续集成
Continuous integration (CI)
持续集成是一种软件开发实践,即团队开发成员经常集成他们的工作,通常每个成员每天至少集成一次,也就意味着每天可能会发生多次集成。
每次集成都通过自动化的构建(包括编译,发布,自动化测试)来验证,从而尽快地发现集成错误。
许多团队发现这个过程可以大大减少集成的问题,让团队能够更快的开发内聚的软件。
持续集成强调开发人员提交了新代码之后,立刻进行构建、(单元)测试。根据测试结果,我们可以确定新代码和原有代码能否正确地集成在一起。
持续集成的好处主要有两个:
快速发现错误:每完成一点更新,就集成到主干,可以快速发现错误,定位错误也比较容易。
防止分支大幅偏离主干:如果不是经常集成,主干又在不断更新,会导致以后集成的难度变大,甚至难以集成。
持续集成的目的,就是让产品可以快速迭代,同时还能保持高质量。
它的核心措施是,代码集成到主干之前,必须通过自动化测试。只要有一个测试用例失败,就不能集成。
2、持续交付
持续交付在持续集成的基础上,将集成后的代码部署到更贴近真实运行环境的「类生产环境/公测环境」(production-like environments)中。比如,我们完成单元测试后,可以把代码部署到连接数据库的 Staging 环境中更多的测试。如果代码没有问题,可以继续手动部署到生产环境中。
3、持续部署
持续部署则是在持续交付的基础上,把部署到生产环境的过程自动化。
二、Jenkins简介
1、简介
Jenkins是一个开源软件项目,是基于Java开发的一种持续集成工具,用于监控持续重复的工作,旨在提供一个开放易用的软件平台,使软件的持续集成变成可能。
2、YUM安装(不推荐)
安装依赖
yum install java-1.8.0-openjdk java-1.8.0-openjdk-devel
安装yum源
wget -O /etc/yum.repos.d/jenkins.repo http://pkg.jenkins.io/redhat-stable/jenkins.repo
rpm --import http://pkg.jenkins.io/redhat/jenkins.io.key
or
rpm --import http://pkg.jenkins-ci.org/redhat/jenkins-ci.org.key
安装Jenkins
yum –y install Jenkins
systemctl start jenkins
systemctl enable jenkins
3、RPM安装
下载地址
https://mirrors.tuna.tsinghua.edu.cn/jenkins/redhat-stable/
RPM安装
rpm –ivh jenkins-2.32.3-1.1.noarch.rpm
systemctl start jenkins
systemctl enable jenkins
三、Jenkins插件管理
我们前面讲了,Jenkins是一个引擎,他本身的功能很简单,是通过各种不同的插件实现编译部署项目。
1、自动插件安装:
登录web页面,点击系统管理:
点击管理插件:
点击可选插件,选择你需要安装的插件
安装完成后,一般情况下不需要重启Jenkins,
具体根据提示。
2、手工安装插件
除了上面的插件安装方法,Jenkins还为我们提供了手工安装插件的方式,特别是在国内,由于网络的原因,有时候我们使用上述方法安装插件会经常不成功,所以我们可以采用下载插件,然后再上传的方式来安装插件。
官方的插件下载地址:http://updates.jenkins-ci.org/
国内的源:https://mirrors.tuna.tsinghua.edu.cn/jenkins/plugins/
需要注意的是选择下载对应版本的版本,否则有时候会出现兼容性错误。
Jenkins的版本可以通过:系统管理—about Jenkins
看到:
下面选择下载对应版本的SSH插件:
3、覆盖插件目录
我们可以在已经安装好Jenkins的一台机子上备份/var/lib/jenkins/plugins
目录,然后把备份文件上传到我们需要覆盖的Jenkins的对应目录上,然后重启Jenkins。
这种方法其他也给我们提供了一种更加快速的安装Jenkins的方法。我们可以在安装安装初始插件的时候,先跳过,
再采用这种方式安装插件。
四、Jenkins程序目录
我们通过命令查看一下Jenkins安装后的文件和目录:
[root@node3 jenkins]# 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、主配置文件
/etc/sysconfig/jenkins是Jenkins的主配置文件:我们在这里主要配置Jenkins的工作目录、启动用户、启动端口。
Jenkins默认的用户为jenkins,强烈建议生产环境使用jenkins用户,然后使用sudo进行授权,
教学过程为了避免各种权限问题,改为root用户。
2、主目录:
/var/lib/jenkins:Jenkins配置的主工作目录
[root@node3 jenkins]# ll /var/lib/jenkins/
total 64
-rw-r--r-- 1 jenkins jenkins 788 Dec 6 17:25 com.dabsquared.gitlabjenkins.connection.GitLabConnectionConfig.xml
-rw-r--r-- 1 jenkins jenkins 365 Dec 6 17:25 com.dabsquared.gitlabjenkins.GitLabPushTrigger.xml
-rw-r--r-- 1 jenkins jenkins 1592 Dec 6 17:25 config.xml
-rw-r--r-- 1 jenkins jenkins 159 Dec 6 17:25 hudson.model.UpdateCenter.xml
-rw-r--r-- 1 jenkins jenkins 370 Dec 6 17:25 hudson.plugins.git.GitTool.xml
-rw------- 1 jenkins jenkins 1712 Dec 6 17:22 identity.key.enc
-rw-r--r-- 1 jenkins jenkins 94 Dec 6 17:22 jenkins.CLI.xml
-rw-r--r-- 1 jenkins jenkins 6 Dec 6 17:25 jenkins.install.InstallUtil.lastExecVersion
-rw-r--r-- 1 jenkins jenkins 6 Dec 6 17:23 jenkins.install.UpgradeWizard.state
drwxr-xr-x 2 jenkins jenkins 6 Dec 6 17:26 jobs
drwxr-xr-x 3 jenkins jenkins 19 Dec 6 17:22 logs
-rw-r--r-- 1 jenkins jenkins 907 Dec 6 17:25 nodeMonitors.xml
drwxr-xr-x 2 jenkins jenkins 6 Dec 6 17:22 nodes
drwxr-xr-x 84 jenkins jenkins 8192 Dec 6 20:06 plugins
-rw-r--r-- 1 jenkins jenkins 129 Dec 6 17:25 queue.xml.bak
-rw-r--r-- 1 jenkins jenkins 64 Dec 6 17:22 secret.key
-rw-r--r-- 1 jenkins jenkins 0 Dec 6 17:22 secret.key.not-so-secret
drwxr-xr-x 4 jenkins jenkins 4096 Dec 6 17:26 secrets
drwxr-xr-x 2 jenkins jenkins 182 Dec 6 17:25 updates
drwxr-xr-x 2 jenkins jenkins 24 Dec 6 17:22 userContent
drwxr-xr-x 3 jenkins jenkins 19 Dec 6 17:22 users
drwxr-xr-x 2 jenkins jenkins 6 Dec 6 17:25 workflow-libs
drwxr-xr-x 3 jenkins jenkins 18 Dec 6 17:26 workspace
其中主要的目录为jobs目录:存放jobs的配置及每次构建的结果;
plugins目录:Jenkins插件目录,存放我们已经安装的插件;
worksspace:工作区目录。
3、程序目录
/var/cache/Jenkins Jenkins程序文件目录
[root@node3 jenkins]# ll /var/cache/jenkins/war/
total 2140
-rw-r--r-- 1 jenkins jenkins 1948 Dec 6 17:22 ColorFormatter.class
drwxr-xr-x 5 jenkins jenkins 147 Dec 6 17:22 css
-rw-r--r-- 1 jenkins jenkins 1544 Dec 6 17:22 dc-license.txt
drwxr-xr-x 2 jenkins jenkins 30 Dec 6 17:22 executable
-rw-r--r-- 1 jenkins jenkins 17542 Dec 6 17:22 favicon.ico
drwxr-xr-x 12 jenkins jenkins 180 Dec 6 17:22 help
drwxr-xr-x 6 jenkins jenkins 4096 Dec 6 17:22 images
-rw-r--r-- 1 jenkins jenkins 1919 Dec 6 17:22 JNLPMain.class
drwxr-xr-x 2 jenkins jenkins 250 Dec 6 17:22 jsbundles
-rw-r--r-- 1 jenkins jenkins 855 Dec 6 17:22 LogFileOutputStream$1.class
-rw-r--r-- 1 jenkins jenkins 639 Dec 6 17:22 LogFileOutputStream$2.class
-rw-r--r-- 1 jenkins jenkins 2243 Dec 6 17:22 LogFileOutputStream.class
-rw-r--r-- 1 jenkins jenkins 16644 Dec 6 17:22 Main.class
-rw-r--r-- 1 jenkins jenkins 1041 Dec 6 17:22 MainDialog$1$1.class
-rw-r--r-- 1 jenkins jenkins 1060 Dec 6 17:22 MainDialog$1.class
-rw-r--r-- 1 jenkins jenkins 2400 Dec 6 17:22 MainDialog.class
-rw-r--r-- 1 jenkins jenkins 512 Dec 6 17:22 Main$FileAndDescription.class
drwxr-xr-x 3 jenkins jenkins 75 Dec 6 17:22 META-INF
-rw-r--r-- 1 jenkins jenkins 71 Dec 6 17:22 robots.txt
drwxr-xr-x 3 jenkins jenkins 200 Dec 6 17:22 scripts
drwxr-xr-x 7 jenkins jenkins 237 Dec 6 17:22 WEB-INF
-rw-r--r-- 1 jenkins jenkins 2098273 Dec 6 17:22 winstone.jar
4、其他文件
/var/log/Jenkins Jenkins日志文件目录
/etc/init.d/Jenkins 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@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:27 com.dabsquared.gitlabjenkins.connection.GitLabConnectionConfig.xml
-rw-r--r-- 1 root root 365 Dec 6 17:25 com.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:33 hudson.plugins.build_timeout.operations.BuildStepOperation.xml
-rw-r--r-- 1 root root 1228 Dec 7 20:33 hudson.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:33 hudson.plugins.jira.JiraProjectProperty.xml
-rw-r--r-- 1 root root 346 Dec 7 20:33 hudson.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:33 jenkins.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:33 jenkins.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:33 jenkins.security.QueueItemAuthenticatorConfiguration.xml
-rw-r--r-- 1 root root 162 Dec 8 13:33 jenkins.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:05 org.jenkinsci.plugins.docker.commons.tools.DockerTool.xml
-rw-r--r-- 1 root root 255 Dec 8 10:05 org.jenkinsci.plugins.gitclient.JGitApacheTool.xml
-rw-r--r-- 1 root root 243 Dec 8 10:05 org.jenkinsci.plugins.gitclient.JGitTool.xml
-rw-r--r-- 1 root root 290 Dec 7 20:33 org.jenkinsci.plugins.pipeline.modeldefinition.config.GlobalConfig.xml
-rw-r--r-- 1 root root 46 Dec 8 00:14 org.jenkinsci.plugins.workflow.flow.FlowExecutionList.xml
-rw-r--r-- 1 root root 218 Dec 7 20:33 org.jenkinsci.plugins.workflow.libs.GlobalLibraries.xml
-rw-r--r-- 1 root root 185 Dec 7 20:33 org.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]#
七、创建一个freestyle的Job
1、执行简单命令或脚本
job配置页面:
勾选丢弃旧的构建:
由于每次构建都会生成很多构建产物,如果频繁构建会占用很多的空间,我们可以通过这几个选项控制构建产物的保留。一般建议选择保留最近5-10的构建为适宜。
其他参数我们在后面再讲。
保存后,我们就创建了一个简单的freestyle job,点击意即构建执行一下,看看结果:
通过使用pwd命令,我们可以看到执行命令的当前目录是/var/lib/jenkins/workspace/jobname
通过这个小例子,我们可以总结如下几点:
1、可以使用Jenkins在页面执行任何需要在linux命令行的操作;
2、就是我们前面讲到的,一定不要在生产环境中用root用户启动jenkins。
2、配置使用Gitlab
我们还是使用前面的my-freestyle Job,配置Job从Gitlab拉取frontend的代码到jenkins。
此处的错误是我们现在还没有配置jenkins连接到Gitlab,由于Jenkins只是拉取Gitlab的代码,所以我们可以使用Gitlab的Deploy Key。
1、在Jenkins本地生成SSH Key:
[root@node3 ~]# ssh-keygen -t rsa
Generating public/private rsa key pair.
Enter file in which to save the key (/root/.ssh/id_rsa):
Created directory '/root/.ssh'.
Enter passphrase (empty for no passphrase):
Enter same passphrase again:
Your identification has been saved in /root/.ssh/id_rsa.
Your public key has been saved in /root/.ssh/id_rsa.pub.
The key fingerprint is:
SHA256:R4I1NWcI//trqY6fvAdZZB0v8GMFkkBbwcDH/CAxtkA root@node3
The key's randomart image is:
+---[RSA 2048]----+
| .E=XOBo.+o|
| o =+OB+o.o|
| . . =o == .|
| o . .oo |
| S . .o |
| . o. |
| .. . |
| o o+ |
| .oB=o. |
+----[SHA256]-----+
2、配置Gitlab Deploy Key
然后切换到frontend 仓库:
3、安装git并本地测试
[root@node3 ~]# yum install git –y
[root@node3 ~]# git clone git@192.168.56.12:web-site/frontend.git
Cloning into 'frontend'...
The authenticity of host '192.168.56.12 (192.168.56.12)' can't be established.
ECDSA key fingerprint is SHA256:SjPoetHYvGBI08VxTdzYOys+QpjR5vLNbU9Obs2Lx9Q.
ECDSA key fingerprint is MD5:39:3e:52:a1:45:9b:3e:23:72:e6:0d:0e:76:00:17:55.
Are you sure you want to continue connecting (yes/no)? yes
Warning: Permanently added '192.168.56.12' (ECDSA) to the list of known hosts.
remote: Counting objects: 34, done.
remote: Compressing objects: 100% (23/23), done.
remote: Total 34 (delta 6), reused 18 (delta 0)
Receiving objects: 100% (34/34), done.
Resolving deltas: 100% (6/6), done.
我们再次打开my-freestyle Job配置页面,
执行构建后,我们现在我们已经把代码拉到了我们Job的工作区
3、代码发布
上面的示例我们已经实现Gitlab拉取地Jenkins本地,下面接下上面的示例,我们实现将代码发布到我们的服务器:
1)配置免密登录
要实现无交互式的传输文件,执行命令,我们首先要保证Jenkins本机可以免密登录到目标主机。
[root@node3 ~]# ssh-copy-id -i .ssh/id_rsa.pub 192.168.56.11
/usr/bin/ssh-copy-id: INFO: Source of key(s) to be installed: ".ssh/id_rsa.pub"
The authenticity of host '192.168.56.11 (192.168.56.11)' can't be established.
ECDSA key fingerprint is SHA256:lHsG8JxgHwQ3/xdLN/q+h8JtvlWKhtIJn0Zw2t99gb8.
ECDSA key fingerprint is MD5:cf:dd:3e:ba:5e:75:24:ce:d4:cf:4f:db:63:3d:8d:6e.
Are you sure you want to continue connecting (yes/no)? yes
/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@192.168.56.11's password:
Number of key(s) added: 1
Now try logging into the machine, with: "ssh '192.168.56.11'"
and check to make sure that only the key(s) you wanted were added.
[root@node3 ~]# ssh 192.168.56.11
Last login: Thu Dec 7 08:50:52 2017 from 192.168.56.1
[root@node1 ~]# exit
logout
Connection to 192.168.56.11 closed.
2)编写发布脚本
我们实现将从Git拉到的代码打包,然后发布到node1的/data/web目录下。编辑我们的Job,在构建处输入如下代码
构建执行成功后:
我们在Jenkins的工作区my-freestyle目录中生成web-11.tar.gz包,并且已经传送到了node1要求的目录下。
在这里我们作以下两点解释:
1、构建过程中命令执行的当前目录为:Jenkins主目录下workspace目录下Jobname目录;
2、我们可以在脚本中使用Jenkins的各种环境变量,调用方式和我们在linux中调用系统变更方式相同,我们可以使用如下方式查看Jenkins的所有环境变量:
4、参数化构建
上一节中我们介绍了如何使用Jenkins的环境变量,那么我们是不是可以在构建过程中,自定义变量,答案是肯定的,下面我们介绍Jenkins的参数化构建:
配置项目,点击参数化构建过程:
我们看到有多好种类型的参数,我们常用的choice和string
。
1)choice Parameter
choice给出多个选项,构建时可以手动选择参数,默认是第一行数据。
2)string Parameter:
string提供一个文本输入框,使用字符串值的参数变量。
我们添加两个参数:
然后在我们脚本中调用:
保存后,我们发现:
点击Build with parameters:
点击开始构建,查看构建结果如下:
还有很多其他的可用参数:Boolean Parameter提供一个布尔选择,password Parameter参数提供一个类似密码的输入框,Git Parameter可以选择需要签出代码的分支、标签等。
5、Git commit触发Jenkins 构建
本次实验,我们新建一个freestyle Job,实现开发在本地向frontend 仓库dev 分支push 代码,Jenkins自动拉取dev分支的代码,然后进行构建后将代码发布到指定的服务器。
1)安装插件
实现Jenkins与Gitlab的联动需要安装:Gitlab Authentication plugin、GitLab Plugin这两个插件。
2)配置Jenkins连接Gitlab
系统管理—系统设置
我们转到GitLab上生成一个token:
我们复制生成的token,添加到jenkins:
选择刚才生成的认证
3)新建frontend Job:
我们使用复制的方式创建新的Job,
我们发现新生成的frontend-job配置与my-freestyle一样,我们可以在此基础做改动。
源码管理部分:我们选择从dev分支拉取代码
构建触发器部分:
此选项主要配置Gitlab如何触发Jenkins Job构建,这里我们配置只有dev分支的push操作会触发构建,并生成一个token,在前面我们配置了Jenkins可以访问Gitlab,但是Gitlab并不能访问Jenkins,此的token用于配置Gitlab访问Jenkins(我们后面介绍)。
构建部分我们设置如下:
4)配置Gitlab仓库连接Jenkins
在Gitlab中选择frontend仓库,点击settings下的Integrations:
URL与Secret Token的值来自刚才我们在Jenkins配置构建触发器部分,见下图。
完成配置后,我们进行测试,
[root@node1 frontend]# git checkout dev
Already on 'dev'
Your branch is up-to-date with 'origin/dev'.
[root@node1 frontend]# git branch
1-index
2-news
* dev
master
[root@node1 frontend]# vim index.html
[root@node1 frontend]# git add .
[root@node1 frontend]# git commit -m "modify index.html"
[dev 17365f9] modify index.html
1 file changed, 1 insertion(+)
[root@node1 frontend]# git push origin dev
Counting objects: 3, done.
Delta compression using up to 2 threads.
Compressing objects: 100% (3/3), done.
Writing objects: 100% (3/3), 291 bytes | 0 bytes/s, done.
Total 3 (delta 1), reused 0 (delta 0)
remote:
remote: To create a merge request for dev, visit:
remote: http://192.168.56.12/web-site/frontend/merge_requests/new?merge_request%5Bsource_branch%5D=dev
remote:
To 192.168.56.12:web-site/frontend.git
a33914c..17365f9 dev -> dev
5)git按分支、版本部署
八、Jenkins Pipeline
1、Pipeline介绍
Pipeline 是Jenkins 2.0的精髓,简单来说,就是一套运行于Jenkins上的工作流框架,将原本独立运行于单个或者多个节点的任务连接起来,实现单个任务难以完成的复杂发布流程。Pipeline的实现方式是一套Groovy DSL,任何发布流程都可以表述为一段Groovy脚本,并且Jenkins支持从代码库直接读取脚本,从而实现了Pipeline as Code的理念。
Stage: 阶段,一个Pipeline可以划分为若干个Stage,每个Stage代表一组操作。注意,Stage是一个逻辑分组的概念,可以跨多个Node。
Node: 节点,一个Node就是一个Jenkins节点,或者是Master,或者是Agent,是执行Step的具体运行期环境。
2、pipeline简单示例
配置页面前半部分和freestyle项目一样,只是后半部分少了源码管理、构建和构建后操作这部分内容,这是因为pipeline所有的这些操作都是要通过编写Groovy脚本来实现,大家不要怕,写一些我们常用的操作也不难,下面我们通过具体的例子带大家来学习。我们首先创建一个最简单的例子。
node {
echo 'Hello World'
}
此段代码的作用就是输出Hello World。
保存后执行,查看结果输出了Hello World。
3、Pipeline多stage示例
1)多stage Pipeline Job
我们使用如下的pipeline script:
node {
stage("Pull Code"){
echo "pull code from git "
}
stage("Code Build"){
echo "Buile code"
}
stage('Unit Test'){
echo "Unit Test"
}
}
stage表示阶段,每个阶段里可以执行具体的操作。我们暂时先简单的输出一些文字,后面再介绍其他常用操作。
保存后Job后,执行构建:
我们可以看每一个阶段的执行时间,点击可以查看每一个阶段执行的日志:
2)Pipeline Scipt 执行命令、脚本
我们可以使用如下方式执行命令或者脚本
node {
stage("Pull Code"){
echo "pull code from git"
sh "ls /etc"
}
stage("Code Build"){
echo "Buile code"
sh "/server/scripts/demo.sh"
}
stage('Unit Test'){
echo "Unit Test"
}
}
得到如下结果:
3)使用生成器生成pipeline脚本
现在我们使用Pipeline Script实现frontend-job,脚本如下:
node {
stage("获取代码"){
echo "获取代码"
git branch: 'dev', url: 'git@192.168.56.12:web-site/frontend.git'
}
stage("打包"){
echo "打包"
sh "tar czf frontend-${BUILD_NUMBER}.tar.gz ./*.html"
}
stage('发布到node1'){
echo "发布到node1"
sh "scp frontend-${BUILD_NUMBER}.tar.gz 192.168.56.11:/data/web"
}
}
构建执行后:
4)使用Pipeline Script调用己有的Job
我们的目录的是想一次性按顺序自动执行多个Job,我们还是使用生成器:
node {
stage("获取代码"){
echo "获取代码"
git branch: 'dev', url: 'git@192.168.56.12:web-site/frontend.git'
}
stage("打包"){
echo "打包"
sh "tar czf frontend-${BUILD_NUMBER}.tar.gz ./*.html"
}
stage('发布到node1'){
echo "发布到node1"
sh "scp frontend-${BUILD_NUMBER}.tar.gz 192.168.56.11:/data/web"
}
stage("调用frontend Job"){
build 'frontend-job'
}
}
执行结果如下:
九、创建Maven项目
上面我讲述的Job都是非编译项目,也就是代码从仓库中拉下来,不经过任何操作就可以发布,这对于像Java、Android等源码需要编译的项目是不可用的,下面我们讲解如何使用Maven插件来构建Java项目。
1、Maven介绍
Maven是一个项目管理和综合工具。Maven提供给开发人员构建一个完整的生命周期框架。
开发团队可以自动完成该项目的基础设施建设,Maven使用标准的目录结构和默认构建生命周期。
Apache的开源项目主要服务于JAVA平台的构建、依赖管理、项目管理。
Project Object Model,项目对象模型。通过xml格式保存的pom.xml文件。该文件用于管理:源代码、配置文件、开发者的信息和角色、问题追踪系统、组织信息、项目授权、项目的url、项目的依赖关系等等。该文件是由开发维护,我们运维人员可以不用去关心。
2、安装Maven插件
我们要使用Jenkins+Maven对Java项目进行构建,需要安装Maven Project Plugin,具体安装过程请参考插件管理部分
3、Linux下安装Maven
1)下载Maven 3安装包
官网:http://maven.apache.org/download.cgi
清华镜像:https://mirrors.tuna.tsinghua.edu.cn/apache/maven/
2)安装Maven
[root@node3 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@node3 src]# tar xf apache-maven-3.3.9-bin.tar.gz
[root@node3 src]# mv apache-maven-3.3.9 /usr/local/
[root@node3 src]# ln -s /usr/local/apache-maven-3.3.9/ /usr/local/maven
[root@node3 src]# cd ..
[root@node3 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.5.2.el7.x86_64", arch: "amd64", family: "unix"
3)配置
编辑/etc/profile文件,在末尾添加export PATH=/usr/local/apache-maven-3.3.9/bin/:$PATH
4、Maven 插件配置
配置如下
5、创建Maven Job
在我们创建Job之间,首先要保证我们的Gitlab仓库有一个java的源码仓库,下面我先在Gitlab上导入一个Java的仓库:
远程仓库地址:http://code.greatops.net/greatops/practice-code.git ,导入成功后我们得到这样的一个仓库
接下来我们创建Maven Job
通用部分:
源码管理部分:
构建部分:
执行构建后:
构建完成生,我们在看到在我们的工作区中,每个项目下面生成了一个target目录,里面有一个XXX.jar的文件,这个就是我们的构建产物,构建产物的名称是在项目的pom.xml文件定义,我们可以把这个文件发布到我们的服务器。
接着,我们增加一个Post Steps,用于将构建产物发布,
配置如下:
构建执行后:
我们还可以归档构建后产物:
构建后,在我们的项目可以看到构建产物:
6、Maven的常用命令
此部分内容了解即可,
1)创建Maven的普通java项目:
mvn archetype:create
-DgroupId=packageName
-DartifactId=projectName
2) 创建Maven的Web项目:
mvn archetype:create
-DgroupId=packageName
-DartifactId=webappName
-DarchetypeArtifactId=maven-archetype-webapp
3.)清除后再编译
mvn clean install
我们Jenkins Biuld部分最常用的配置是:clean install -Dmaven.test.skip=true。
十、权限配置
由于jenkins默认的权限管理体系不支持用户组或角色的配置,因此需要安装第三发插件来支持角色的配置,我们使用Role-based Authorization Strategy 插件,安装请参考前面插件管理章节。
1、启用插件
插件安装后,我们先启用该插件管理Jenkins权限。
2、创建用户
我们新建一个test用户:
3、创建角色
Jenkins用户都有两种角色:全局角色和Job角色,我们先创建全局角色test,
然后赋予test角色全局读的功能。
再创建Job角色test,并赋予Job只读权限
Pattern:用于匹配Job名称。
4、用户授权
在全局角色下添加我们的test用户,并赋予该用户我们刚才创建的全局test角色。
保存后,我们使用test用户登录:
我们只有查看的权限,而且看不到任何Job信息。接着我们再赋予test用户Job角色下的test角色:
再次使用test用户登录,我们发现匹配到的my-freestyle-job 出现了,并且我们只能查看该Job的信息。
我们赋予Job roles下test角色 构建权限后,再次登录,发现我们可以构建Job。
十一、Jenkins集群配置
Jenkins支持分布式部署,我们可以为Jenkins配置多个slave,在构建的时候将任务分派到slave上,从而减轻Jennins Master的负载。
1、添加Jenkins从节点
添加认证:
注:如果slave节点不能启动,可能需要在从节点上安装jdk,如果要在从节点上执行maven构建,还需要在从节点上安装maven。使用同样的方便添加node2-192.168.56.12。
2、分派Job到节点
我们配置frontend-job,在通用部分:
构建完成后,我们可以看到本此构建是在node1上执行的:
注:我们可以多个slave配置同一个标签,系统随机将任务调派到不同的节点。也可以做到高可用,避免一个slave宕机,整个构建不能执行。
3、参数化构建选择节点
此功能需要我们安装Node and Label parameter plugin ,插件安装过程请参考插件管理部分内容。
插件安装成功后,我们配置frontend-job,勾选参数化构建添加Node,
我们发现构建失败,查看输出,发现失败的原因是node2:192.168.56.12不能从Gitlab上拉取代码,因为我们没有配置node2访问gitlab的SSH Key。
配置完成后,我们继续执行构建:
同样构建失败,再次查看详细信息,发现失败的原因是我们没有做node2:192.168.56.12到192.168.56.11我的免密登录,执行发布命令失败。
配置后,执行构建,发现成功: