• 一、什么是持续集成?

(1)Continuous integration(CI)

持续集成是一种软件开发实践,即团队开发成员经常集成他们的工作,通常每个成员至少集成一次,也就意味着每天可能会发生多次集成。每次集成都通过自动化的构建(包括编译,发布,自动化测试)来验证,从而尽快地发现集成错误。许多团队发现这个过程可以大大减少集成的问题,让团队能够更快的开发内聚的软件。

SRE实战 互联网时代守护先锋,助力企业售后服务体系运筹帷幄!一键直达领取阿里云限量特价优惠。

学习Jenkins(三) 随笔 第1张

(2)没有持续集成

项目做模块集成的时候,发现很多借口都不通==>浪费大量时间

需要手动去编译打包最新的代码==>构建过程不透明

发布代码,上线,基本靠手工==>脚本乱飞

 

(3)持续集成最佳实践:

维护一个单一的代码库

使构建自动化

执行测试是构建的一部分

集成日志及历史记录

使用统一的依赖包管理库

每天至少集成一次

 

(4)jenkins介绍

Jenkins只是一个平台,真正运作的都是插件。这就是jenkins流行的原因,因为jenkins什么插件都有 
Hudson是Jenkins的前身,是基于Java开发的一种持续集成工具,用于监控程序重复的工作,Hudson后来被收购,成为商业版。后来创始人又写了一个jenkins,jenkins在功能上远远超过hudson

Jenkins官网:https://jenkins.io/

 

(5)部署代码上线流程:

1.代码获取(直接了拉取)

2.编译 (可选)

3.配置文件放进去

4.打包

5.scp到目标服务器

6.将目标服务器移除集群

7.解压并放置到Webroot

8.Scp 差异文件

9.重启 (可选)

10.测试

11.加入集群

  • 二、jenkins部署

1)安装JDK 
[root@linux-node2 ~]# yum instsall -y java-1.8.0-openjdk java-1.8.0-openjdk-devel
 
(2)下载jenkins的rpm包
[root@linux-node2 ~]# wget https://mirrors.tuna.tsinghua.edu.cn/jenkins/redhat-stable/jenkins-2.32.3-1.1.noarch.rpm
--2017-12-21 09:11:58--  https://mirrors.tuna.tsinghua.edu.cn/jenkins/redhat-stable/jenkins-2.32.3-1.1.noarch.rpm
正在解析主机 mirrors.tuna.tsinghua.edu.cn (mirrors.tuna.tsinghua.edu.cn)... 101.6.6.178, 2402:f000:1:416:101:6:6:177
正在连接 mirrors.tuna.tsinghua.edu.cn (mirrors.tuna.tsinghua.edu.cn)|101.6.6.178|:443... 已连接。
已发出 HTTP 请求,正在等待回应... 200 OK
长度:69675984 (66M) [application/x-redhat-package-manager]
正在保存至: “jenkins-2.32.3-1.1.noarch.rpm”
 
(3)安装jenkins
[root@linux-node2 ~]# rpm -ivh jenkins-2.32.3-1.1.noarch.rpm 
警告:jenkins-2.32.3-1.1.noarch.rpm: 头V4 DSA/SHA1 Signature, 密钥 ID d50582e6: NOKEY
准备中...                          ################################# [100%]
正在升级/安装...
   1:jenkins-2.32.3-1.1               ################################# [100%]
    
(4)启动jenkins
[root@linux-node2 ~]# service jenkins start
Starting jenkins (via systemctl):                          [  确定  ]
 
[root@linux-node2 ~]# netstat -tulnp|grep 8080
tcp6       0      0 :::8080                 :::*                    LISTEN      42160/java 
浏览器访问:192.168.56.12:8080:如图
[root@linux-node2 ~]# cat /var/lib/jenkins/secrets/initialAdminPassword
8addd06f53f6405da6133356af1ca3b0    #登陆界面有提示输入密码,初始密码文件为/var/lib/jenkins/secrets/initialAdminPassword
 
友情提示:jenkins如果跟gitlab在一台服务器需要将jenkins的端口进行修改,需要将jenkins的8080修改为其他端口

学习Jenkins(三) 随笔 第2张

安装所有插件:

学习Jenkins(三) 随笔 第3张

安装插件完成,设置用户名:jenkins,密码:jenkins

学习Jenkins(三) 随笔 第4张

  • 三、jenkins的插件以及配置

Jenkins系统管理比较重要的就是插件管理了 ,因为jenkins的工作全部是由插件来完成。

在插件管理中,有可更新、可选插件、已安装,日常的插件安装都是在这个界面上完成的。比如为了和gitlab协同,我们需要安装gitlab的插件。

学习Jenkins(三) 随笔 第5张

学习Jenkins(三) 随笔 第6张

在高级选项中,我们可以在jenkins官网下载插件,然后上传插件 ,如图:

 学习Jenkins(三) 随笔 第7张

因为很多插件需要×××才可以继续下载,jenkins还提供了代理的设置


还是在服务器目录下进行上传插件

目录路径= /var/lib/jenkins/plugins/

这个目录下是我们安装所有的插件

jenkins的目录介绍:

[root@linux-node2 ~]# rpm -ql jenkins
/etc/init.d/jenkins                #jenkins的启动文件
/etc/logrotate.d/jenkins
/etc/sysconfig/jenkins             #jenkins的配置文件
/usr/lib/jenkins                   
/usr/lib/jenkins/jenkins.war       #jenkins的程序war包
/usr/sbin/rcjenkins                #jenkins的为二进制文件
/var/cache/jenkins                 #jenkins的程序文件,运行程序解压出来的
/var/lib/jenkins                   #jenkins的主目录
/var/log/jenkins                   #jenkins的日志文件
 
jenkins的升级,只需要将war包解压到/var/lib/jenkins目录下,重启jenkins即可。
 
友情提示:
卡启动问题
jenkins在第一次安装启动时会向官网回传信息,如果网络离线可以正常安装。当网络在线,但是
还有可能是内存不足
 
备份:
tar zcvf jenkins.tar.gz /var/lib/jenkins

系统管理-->系统配置

执行者数量:配置并发数量,一般设置为5,不超过10

用法:如果是主server,可以不选,如果是从级别必须选择“尽可能的使用这个节点”

生成前等待时间:配置该时间,避免错误操作,有时间返回

学习Jenkins(三) 随笔 第8张

学习Jenkins(三) 随笔 第9张

  • 三、jenkins升级

1)查看war包所在的目录
[root@linux-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
 
(2)下载最新稳定版的war包
[root@linux-node2 ~]# wget https://mirrors.tuna.tsinghua.edu.cn/jenkins/war/2.46/jenkins.war
--2017-12-21 14:56:10--  https://mirrors.tuna.tsinghua.edu.cn/jenkins/war/2.46/jenkins.war
Resolving mirrors.tuna.tsinghua.edu.cn (mirrors.tuna.tsinghua.edu.cn)... 101.6.6.178, 2402:f000:1:416:101:6:6:177
Connecting to mirrors.tuna.tsinghua.edu.cn (mirrors.tuna.tsinghua.edu.cn)|101.6.6.178|:443... connected.
HTTP request sent, awaiting response... 200 OK
Length: 68663046 (65M) [application/java-archive]
Saving to: ‘jenkins.war’
 
36% [====================================================>                                                                                               ] 24,829,614   707KB/s  eta 60s

当前jenkins版本为2.32.2

学习Jenkins(三) 随笔 第10张

3)停止jenkins服务
[root@linux-node2 ~]# service jenkins stop
Stopping jenkins (via systemctl):                          [  OK  ]
 
(4)备份原来的war包,并拷贝最新版本war包到/usr/lib/jenkins目录下
[root@linux-node2 ~]# cd /usr/lib/jenkins/
[root@linux-node2 jenkins]# mv jenkins.war jenkins-2.32.2.war.bak
[root@linux-node2 jenkins]# mv /root/jenkins.war .
[root@linux-node2 jenkins]# service jenkins start
Starting jenkins (via systemctl):                          [  OK  ]
[root@linux-node2 jenkins]# netstat -tulnp |grep 8080
tcp6       0      0 :::8080                 :::*                    LISTEN      47298/java   
 
成功升级到jenkins 2.46版本

学习Jenkins(三) 随笔 第11张

  • 四、jenkins备份

在jenkins界面创建一些项目,这里使用rsync,主要是为了保持备份的属性,如果使用scp或cp有时会导致文件属性的改变而导致jenkins异常。

1)创建备份目录
[root@linux-node2 ~]# mkdir /data/backup/jenkins -p
 
(2)备份/var/lib/jenkins目录
[root@linux-node2 ~]# rsync -raz --delete --progress /var/lib/jenkins /data/backup/jenkins/3)删除/var/lib/jenkins/
[root@linux-node2 ~]# rm -rf /var/lib/jenkins/
 
[root@linux-node2 ~]# service jenkins restart
Restarting jenkins (via systemctl):  Job for jenkins.service failed because the control process exited with error code. See "systemctl status jenkins.service" and "journalctl -xe" for details.
                                                           [FAILED]
[root@linux-node2 ~]# service jenkins status
JENKINS_HOME directory does not exist: /var/lib/jenkins
 
(4)恢复备份
[root@linux-node2 ~]# rsync -raz --delete /data/backup/jenkins/jenkins /var/lib/
[root@linux-node2 ~]# service jenkins restart
Restarting jenkins (via systemctl):                        [  OK  ]

 #############################################################

  • 使用git+jenkins实现持续集成

学习Jenkins(三) 随笔 第12张

Step1:构建一个自由风格的php-deploy

学习Jenkins(三) 随笔 第13张

Step2:Gernal配置,丢弃旧的构建,防止jenkins构建较多之后变臃肿

 学习Jenkins(三) 随笔 第14张

Step3:源码管理:这里使用git插件,也可以使用svn插件

 学习Jenkins(三) 随笔 第15张

将git路径存在这里还需要权限认证,否则会出现error 。
jenkins服务器上生成SSH-Key

[root@linux-node2 ~]# yum install -y git
[root@linux-node2 ~]# ssh-keygen 
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:00FQjn5P6qAtok4BuE42TyfuNJnblzZ389XwKBhmHjY root@linux-node2
The key's randomart image is:
+---[RSA 2048]----+
|        .oo      |
|.        +       |
|o       . o      |
| o     . . .     |
|.+.o .  S E . .  |
|+ =.=    B O   +.|
| ..B    o + o ..o|
| .o = .B + o ..  |
| .o+ o+.+ o o.   |
+----[SHA256]-----+
[root@linux-node2 ~]# cat .ssh/id_rsa.pub 
ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQC+/XyUMNP5Wm63hhcACosVyRtmJxTSnT46HSKZ2PhduTHPIJcfhVTmeCk1zwO0fP8PmwXFf0+G9ki8CupE/+xcOy14TCqxNgvP8o514IjXOFV7SO1lnHKH3t0RfaFEloRZHnrgIcWiZrFvYRT/TFznWO86sfHPzlW6WF9elTqRURNR60bwv9C6iw4PpYjGVIST/SeGl75axtUjJr544jB5pEWtNZ09ktCKpPeFBvgCc9exdzOQuzaCXQrroNU0p6MB6KkoIOmpkN92cDPdg4EgBYDjwcl38FbXOq3N0QL8PT+IZpHBWFVEAZU2alI02H5NNUy9p2K/Br4NY3UvYZiP root@linux-node2

学习Jenkins(三) 随笔 第16张

学习Jenkins(三) 随笔 第17张

命令行测试添加ssh-key后能否正常拉取
[root@linux-node2 ~]# git clone git@192.168.56.11:java/app1.git
Cloning into 'app1'...
The authenticity of host '192.168.56.11 (192.168.56.11)' can't be established.
ECDSA key fingerprint is SHA256:p2lhKmsPQ6K+dWHHvbJg0GV+Ni9VM7vlViKrYsZLP1s.
ECDSA key fingerprint is MD5:22:14:1c:37:de:47:1c:4a:2f:88:b1:dc:e2:d0:02:17.
Are you sure you want to continue connecting (yes/no)? yes
Warning: Permanently added '192.168.56.11' (ECDSA) to the list of known hosts.
remote: Counting objects: 11, done.
remote: Compressing objects: 100% (7/7), done.
remote: Total 11 (delta 0), reused 11 (delta 0)
Receiving objects: 100% (11/11), done.
[root@linux-node2 ~]# ll
total 68048
-rw-------. 1 root root      948 Dec  3 01:26 anaconda-ks.cfg
drwxr-xr-x  3 root root       62 Dec 21 15:53 app1
-rw-r--r--  1 root root 69675984 Mar  2  2017 jenkins-2.32.3-1.1.noarch.rpm

学习Jenkins(三) 随笔 第18张

然后保存,立即构建一次,会拉取master的代码库

学习Jenkins(三) 随笔 第19张

点开学习Jenkins(三) 随笔 第20张可以看到控制台的输出,如图:

学习Jenkins(三) 随笔 第21张

/var/lib/jenkins/workspace/php-deploy目录用于存放代码信息

[root@linux-node2 php-deploy]# ll
total 12
-rw-r--r-- 1 root root 28 Dec 21 16:11 index.html
-rw-r--r-- 1 root root 12 Dec 21 16:11 new.html
-rw-r--r-- 1 root root 19 Dec 21 16:11 readme
[root@linux-node2 php-deploy]# pwd
/var/lib/jenkins/workspace/php-deploy

这里我们拉取的代码需要推送到远程代码目录,需要如下操作:
架设linux-node1为web服务,目录为/data/www/php-deploy 

[root@linux-node1 ~]# mkdir /data/www/php-deploy -p
添加node2的免秘钥登陆
[root@linux-node1 ~]# vim .ssh/authorized_keys
[root@linux-node1 ~]# chmod 600 .ssh/authorized_keys 
[root@linux-node2 ~]# ssh 192.168.56.11
Last login: Mon Dec  4 17:41:56 2017 from 192.168.56.1
[root@linux-node1 ~]# 

修改项目设置,配置构建:Execute shell,相当于将代码自动发布到linux-node1的代码目录中。

学习Jenkins(三) 随笔 第22张

接下来,我们重新构建一次,并查看控制台输出:

学习Jenkins(三) 随笔 第23张

在node1上查看目录,也会有相应的代码信息 

[root@linux-node1 ~]# ll /data/www/php-deploy/
total 12
-rw-r--r-- 1 root root 28 Dec 21 16:11 index.html
-rw-r--r-- 1 root root 12 Dec 21 16:11 new.html
-rw-r--r-- 1 root root 19 Dec 21 16:11 readme
[root@linux-node1 ~]# 

 #########################################################################

  • 一、什么是Maven

maven是一个项目管理和综合工具。Maven提供给开发人员构建一个完整的生命周期框架。

开发团队可以自动完成该项目的基础设施建设,Maven使用标准的目录结构和默认构建生命周期

maven是属于Apache的开源项目

maven主要服务于java平台的构建、依赖管理、项目管理。

  • 二、手动安装MAVEN

1)下载maven
[root@linux-node2 ~]# wget http://mirrors.hust.edu.cn/apache/maven/maven-3/3.5.2/binaries/apache-maven-3.5.2-bin.tar.gz
2)解压
[root@linux-node2 ~]# tar -zxvf apache-maven-3.5.2-bin.tar.gz #解压即可使用
[root@linux-node2 ~]# mv apache-maven-3.5.2 /data/3)配置环境变量
[root@linux-node2 bin]# export PATH=$PATH:/data/apache-maven-3.5.2/bin
[root@linux-node2 bin]# vim /etc/profile
export PATH=$PATH:/data/apache-maven-3.5.2/bin

(4)测试
[root@linux-node2 ~]# mvn -v

Apache Maven 3.5.2 (138edd61fd100ec658bfa2d307c43b76940a5d7d; 2017-10-18T15:58:13+08:00)
Maven home: /data/apache-maven-3.5.2
Java version: 1.8.0_151, vendor: Oracle Corporation
Java home: /usr/lib/jvm/java-1.8.0-openjdk-1.8.0.151-1.b12.el7_4.x86_64/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"
  • 三、POM文件解析

POM是研发给出的

Project Object Model,项目对象模型

通过xml格式保存的pom.xml文件

作用类似ant的build.xml文件,功能更强大

该文件用于管理:源代码、配置文件、开发者的信息和角色、问题追踪系统、组织信息、项目授权、项目的url、项目的依赖关系等等。

  • 四、配置系统MAVEN

系统管理-->Global Tool Configuration

新增maven

取消自动安装

填写maven实际安装路径/data/apache-maven-3.5.2

学习Jenkins(三) 随笔 第24张

  • 四、新建maven项目

1)新建maven项目
(2)指定源码文职(git或svn)
(3)指定build选项
clean install
clean install -Dmaven.test.skip=true4)指定execute shell
java -jar target/testweb-0.0.1-SNAPSHOT.jar

配置maven:

settings.xml是maven的主要配置文件
位置$home/.m2是maven下载的插件的存储位置

(1)新建maven项目
新建一个项目,选择构建一个maven项目。如果此处没有“构建一个maven项目”的选项,需要安装插件:Maven Integration Plugin

学习Jenkins(三) 随笔 第25张

(2)指定源码位置(git或svn)

学习Jenkins(三) 随笔 第26张

(3)指定build选项
clean install
clean install -Dmaven.test.skip=true

学习Jenkins(三) 随笔 第27张

(4)指定execute shell
java -jar target/testweb-0.0.1-SNAPSHOT.jar

 学习Jenkins(三) 随笔 第28张

(5)立即构建
这里在构建的过程中,可能会出现插件下载失败,需要更改maven的插件源,编辑/data/apache-maven-3.5.2/conf/settings.xml

 学习Jenkins(三) 随笔 第29张

立即构建完成,可以在/var/lib/jenkins/workspace/Java/下可以看到拉取的代码,我们找到整个项目的的jar包并执行,可以看到hello world

学习Jenkins(三) 随笔 第30张

[root@linux-node2 target]# java -jar testweb-0.0.1-SNAPSHOT.jar 
Hello World! i am guo2
  • 五、将java的代码发布到linux-node1上

 (1)修改项目的Execte shell设置,再重新构建 

rsync -raz --delete --progress target/testweb-0.0.1-SNAPSHOT.jar 192.168.56.11:/opt/
ssh root@192.168.56.11 "java -jar /opt/testweb-0.0.1-SNAPSHOT.jar"

学习Jenkins(三) 随笔 第31张

[root@linux-node1 ~]# ll /opt/
total 8
drwxr-xr-x 10 root root 4096 Dec  9 17:08 gitlab
-rw-r--r--  1 root root 2663 Dec 22 14:16 testweb-0.0.1-SNAPSHOT.jar

[root@linux-node1 ~]# java -jar /opt/testweb-0.0.1-SNAPSHOT.jar 
Hello World! i am guo2

到此一个maven项目就完成了!

  •  六、maven项目按版本发布

1)安装git parameter plugin插件

(2)任务配置中勾选<参数化构建>3)选择git parameter

(4)创建变量名 release(自定义)

(5)选择发布类型:
tag:按标签发布
branch:按分支发布
Revison:按修订发布

(1)安装git parameter plugin插件

 学习Jenkins(三) 随笔 第32张

修改pom.xml中的版本改为v1.0

[root@linux-node2 testing]# vim pom.xml 

<version>v1.0</version>

[root@linux-node2 testing]# git status
# On branch 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:   pom.xml
#
no changes added to commit (use "git add" and/or "git commit -a")
[root@linux-node2 testing]# git add .
[root@linux-node2 testing]# git commit -m "v1.0"
[master eed5815] v1.0
 1 file changed, 1 insertion(+), 1 deletion(-)
[root@linux-node2 testing]# git push origin master
Counting objects: 5, done.
Compressing objects: 100% (3/3), done.
Writing objects: 100% (3/3), 281 bytes | 0 bytes/s, done.
Total 3 (delta 2), reused 0 (delta 0)
To git@192.168.56.11:java/Java.git
   37d2bd1..eed5815  master -> master

学习Jenkins(三) 随笔 第33张

给Java项目中的版本修改后打上标签

学习Jenkins(三) 随笔 第34张

此时我们再修改

[root@linux-node2 testing]# vim src/main/java/com/ghz/testweb/App.java 
package com.ghz.testweb;

/**
 * Hello world!
 *
 */
public class App
{
    public static void main( String[] args )
    {
        System.out.println( "Hello World! i am guo2 v1.0" );
    }
}
[root@linux-node2 testing]# git add .
[root@linux-node2 testing]# git commit -m "featrue1"
[master 6402300] featrue1
 1 file changed, 1 insertion(+), 1 deletion(-)
[root@linux-node2 testing]# git push origin master
Counting objects: 17, done.
Compressing objects: 100% (4/4), done.
Writing objects: 100% (9/9), 565 bytes | 0 bytes/s, done.
Total 9 (delta 2), reused 0 (delta 0)
To git@192.168.56.11:java/Java.git
   eed5815..6402300  master -> master

学习Jenkins(三) 随笔 第35张

此时进行构建,由于版本修改了,会报错:

学习Jenkins(三) 随笔 第36张

但是我们每次进行版本的修改后如果都去修改excute shell就显得太麻烦

(2)任务配置中勾选<参数化构建>

(3)选择git parameter

(4)创建变量名 release(自定义)

 学习Jenkins(三) 随笔 第37张

修改源码管理

 学习Jenkins(三) 随笔 第38张

学习Jenkins(三) 随笔 第39张

(5)选择发布类型:
tag:按标签发布

学习Jenkins(三) 随笔 第40张

(6)对代码进行多次修改,并提交

然后再代码库中对提交进行tag标记

再在jenkins中查看,即可按照不同的版本进行构建,如图:

 学习Jenkins(三) 随笔 第41张

##############################################################3

  • 一、Jenkins的远程管理

Jenkins的远程管理方式包含:

Shell ssh

SSH Plugin

ansible、saltstack

(1)Shell ssh
在项目构建时,jenkins使用了Execute Shell直接对远程主机操作,同步了代码到主机192.168.56.11上,并且可以增加对远程机器进行操作。例如执行某个脚本:ssh root@192.168.53.11 "/bin/sh /data/scripts/****.sh "
如图:

学习Jenkins(三) 随笔 第42张

(2)SSH plugin
除了以上方法之外,还可以使用SSH 的插件--SSH plugin
系统管理-->系统配置-->SSH remote hosts,配置好远程主机

学习Jenkins(三) 随笔 第43张

在项目中配置,如图:

学习Jenkins(三) 随笔 第44张

这样就完成了对远程主机的管理
此外,还可以使用自动化工具,如ansible,saltstack,模式一致,只是用的是ansible或者是saltstack的命令行工具的不同。

  •  二、Jenkins集群

当业务量变大时,单台的jenkins进行自动化构建部署,就显得没那么灵活,下面介绍jenkins的集群功能。
jenkins的集群并非像web服务器,mysql集群,jenkins的集群无需在额外的主机安装jenkins,但是用于java项目来说,要使用集群功能,额外的主机就必须要安装maven。

(1)在jenkins的web界面:系统管理-->Configure Global Security-->TCP port for JNLP agent配置端口30000

 学习Jenkins(三) 随笔 第45张

(2)系统管理-->管理节点-->新建节点

学习Jenkins(三) 随笔 第46张

(3)分配任务到节点
在项目中配置:
General-->Restrict where this project can be run-->Label Expression:node-01

 学习Jenkins(三) 随笔 第47张

学习Jenkins(三) 随笔 第48张

此时,在对项目进行构建,将会分配到node-01节点上进行构建,如图:

学习Jenkins(三) 随笔 第49张

############################################################################

  • 一、Jenkins按角色授权

当一个公司的开发分为多个组别,或者是多个项目等等。用于公司内部测试,让开发人员自行构建测试,此时不可能让所有的开发都在公用一个构建,这样变得很混乱,为了解决这一问题,jenkins也提供了角色授权的机制。每个开发有着对应的账号和权限,可以自行新建,构建,测试,发布等。角色授权需要安装的插件:Role-based Authorization Strategy

(1)系统配置
系统管理-->Configure Global Security-->访问控制-->授权策略-->Role-Base Strategy

学习Jenkins(三) 随笔 第50张

(2)新建用户
系统管理-->管理用户-->新建用户
这里创建一个java用户和php用户,用于区分php和java项目的构建

学习Jenkins(三) 随笔 第51张

(3)用户关联自己相关job,无法查看其他的job

建立项目角色,并对该用户进行项目的授权(包括Job的构建,取消,配置,创建,删除等等)
注意此处的添加,一个是Role是随意填写,最好规范点。Pattern是正则匹配,比如此处匹配的是所有包含Java开头的项目和php开头的项目

系统管理-->Manage and Assign Roles --> Manage Roles-->Project roles

 学习Jenkins(三) 随笔 第52张

配置好项目的权限,使用java用户或php用户登录是没有新建项目的权限,如需新增这样的权限,需要在Global roles中进行配置,新增一个角色(比如新增一个可以创建新项目的权限角色:new job,可登录查看的角色read):

 学习Jenkins(三) 随笔 第53张

 

 然后系统管理-->Manage and Assign Roles -->Assign Roles进行添加对应的权限

学习Jenkins(三) 随笔 第54张

使用php登录查看,可以看到php用户可以看到对应php开头的项目,但是没有新建项目的权限:

学习Jenkins(三) 随笔 第55张

  • 二、Jenkins的Pipeline(代码流水线管理)

Pipeline(代码流水线管理)

Pipeline名词顾名思义就是流水线的意思,因为公司可能会有很多项目。如果使用jenkins构建完成后,开发构建项目需要一项一项点击,比较麻烦。所以出现pipeline名词。

(1)下载pipeline。这样只需要构建一个项目,就会帮我们完成所有相关项目

搜索插件pipeline 

学习Jenkins(三) 随笔 第56张

等待安装完成 

 学习Jenkins(三) 随笔 第57张

(2)新建一个pipeline的项目

 学习Jenkins(三) 随笔 第58张

配置pipeline项目,使用Pipeline script脚本: 

node {
    stage 'build php-deploy'
    build 'php-deploy'
    stage 'build java'
    build 'java'
}

为了解决各个项目的依赖关系关系,使用pipeline的脚本进行控制。
第一步构建php项目,第二步构建java项目。Pipeline的脚本语法在Pipeline Syntax中有展示

学习Jenkins(三) 随笔 第59张

Pipeline Syntax的使用,如图:

 学习Jenkins(三) 随笔 第60张

立即构建p1的项目,如图:

 学习Jenkins(三) 随笔 第61张

代码流水线的功能就介绍到此!

###############################################################

思路图:

学习Jenkins(三) 随笔 第62张

  • 一、下载gitlab plugin

jenkins-->系统管理-->管理插件-->下载并安装gitlab plugin

  • 二、配置gitlab认证

路径:Jenkins-->Credentials-->System-->Global credentials(unrestricted)-->Add Credentials

1、Kind选择Gitlab API token

2、其中API token填写gitlab中有库权限的账号

3、ID填写用户账号

学习Jenkins(三) 随笔 第63张

gitlab生成Api token,将生成的token填入上面的证书内。

学习Jenkins(三) 随笔 第64张

学习Jenkins(三) 随笔 第65张

 

 

  • 三、选择连接

路径:系统管理-->系统设置

1、填写连接名

2、填写gitlab访问URL

3、选择gitlab认证

3、测试连接

学习Jenkins(三) 随笔 第66张

  • 四、配置任务在job配置中选择gitlab connection:gitlab

 学习Jenkins(三) 随笔 第67张

  • 五、任务配置

在job配置界面

1、勾选 Build when a change is pushed to GitLab. GitLab CI Service URL: http://192.168.56.12:8080/project/php-deploy

2、选择push events 时间触发构建

3、选择分支过滤(此处可以根据不同的需求来使用过滤功能)

4、secret token需要填入gitlab项目中的webhook

学习Jenkins(三) 随笔 第68张

在gitlab中找到项目-->setting-->Integrations配置

填写在上图生成的链接:

URL:http://192.168.56.12:8080/project/php-deploy

Secret Token:3f199086a22c54957579966e34ad120a

点击Add webhook

学习Jenkins(三) 随笔 第69张

测试是否生效:点击test-->选择push event会跳转到Hook excuted successfully:HTTP 200

 学习Jenkins(三) 随笔 第70张

学习Jenkins(三) 随笔 第71张

  • 六、构建发布PHP项目

在linux-node1上安装nginx,初始同步了线上代码,写入一个index.html。如图: 

[root@linux-node1 ~]# ll /data/www/php-deploy/
total 12
-rw-r--r-- 1 root root 28 Dec 23 15:45 index.html
-rw-r--r-- 1 root root 12 Dec 21 16:11 new.html
-rw-r--r-- 1 root root 19 Dec 21 16:11 readme
[root@linux-node1 ~]# cat /data/www/php-deploy/index.html 
<h1>welcome to beijing</h1>

学习Jenkins(三) 随笔 第72张

模拟程序员在linux-node2上进行修改代码,并提交到gitlab的master分支上

[root@linux-node2 app1]# pwd
/root/php/app1
[root@linux-node2 app1]# echo "Welcome to use Jenkins and Gitlab" > index.html 
[root@linux-node2 app1]# git status
# On branch 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@linux-node2 app1]# git add .
[root@linux-node2 app1]# git commit -m "jenkins + gitlab"
[master 7313bdd] jenkins + gitlab
 1 file changed, 1 insertion(+), 1 deletion(-)
[root@linux-node2 app1]# git push origin master
Counting objects: 5, done.
Compressing objects: 100% (2/2), done.
Writing objects: 100% (3/3), 334 bytes | 0 bytes/s, done.
Total 3 (delta 0), reused 0 (delta 0)
To git@192.168.56.11:java/app1.git
   dd37af6..7313bdd  master -> master

学习Jenkins(三) 随笔 第73张

学习Jenkins(三) 随笔 第74张

到此,自动触发和发布就完成了!这只是一个简单的构建发布,作为内部测试使用还是可以的!生产使用,有待优化!

######################################################################

  • 1、什么是Nexus?

在前面进行maven项目的构建中,可以看到在构建的过程中需要安装maven的依赖插件,如图:学习Jenkins(三) 随笔 第75张

而在maven的默认配置中是在官网的中央仓库和第三方的maven仓库进行下载,速度偏慢。这里提供阿里云的maven插件库(http://maven.aliyun.com/nexus/#view-repositories),可以在/data/apache-maven-3.5.2/conf/settings.xml 配置文件中进行修改。

 

在日常的开发构建中,我们也可以自己搭建一个私有的nexus。那么什么是nexus呢?

Nexus是maven的私有仓库;

如果没有nexus,项目的打包都需要在公网下载,不利于包的管理和共用;

如果没有私有仓库,我们所需要的所有构件都需要通过maven的中央仓库和第三方的maven仓库下载到本地,而一个团队的所有人都需要重复地从maven仓库中下载构件。

  • 2、Nexus的安装

1)下载Nexus
[root@linux-node2 ~]# wget https://sonatype-download.global.ssl.fastly.net/nexus/oss/nexus-2.14.5-02-bundle.tar.gz
--2017-12-25 10:45:42--  https://sonatype-download.global.ssl.fastly.net/nexus/oss/nexus-2.14.5-02-bundle.tar.gz
Resolving sonatype-download.global.ssl.fastly.net (sonatype-download.global.ssl.fastly.net)... 151.101.228.249
Connecting to sonatype-download.global.ssl.fastly.net (sonatype-download.global.ssl.fastly.net)|151.101.228.249|:443... connected.
HTTP request sent, awaiting response... 200 OK
Length: 73187012 (70M) [application/octet-stream]
Saving to: ‘nexus-2.14.5-02-bundle.tar.gz’
 5% [=======>                                                                                                                                            ] 4,375,805   76.4KB/s  eta 12m 59s
 
(2)解压Nexus
[root@linux-node2 ~]# tar -zxvf nexus-2.14.5-02-bundle.tar.gz
[root@linux-node2 ~]# mv nexus-2.14.5-02 sonatype-work /data/3)启动Nexus
[root@linux-node2 ~]# cd /data/nexus-2.14.5-02
[root@linux-node2 nexus-2.14.5-02]# ls
bin  conf  lib  LICENSE.txt  logs  nexus  NOTICE.txt  tmp
[root@linux-node2 nexus-2.14.5-02]# cd bin/
[root@linux-node2 bin]# ./nexus start
****************************************
WARNING - NOT RECOMMENDED TO RUN AS ROOT
****************************************
If you insist running as root, then set the environment variable RUN_AS_USER=root before running this script.
[root@linux-node2 bin]# export RUN_AS_USER=root
[root@linux-node2 bin]# ./nexus start
****************************************
WARNING - NOT RECOMMENDED TO RUN AS ROOT
****************************************
Starting Nexus OSS...
Started Nexus OSS.
[root@linux-node2 bin]# netstat -tulnp |grep 8081
tcp        0      0 0.0.0.0:8081            0.0.0.0:*               LISTEN      4773/java

(4)浏览器访问仓库
浏览器访问:http://192.168.56.12:8081/nexus,如图:

学习Jenkins(三) 随笔 第76张

点击右上角"login" 默认用户名密码:admin ,admin123

在仓库中,默认会在本地去查找插件,当未发现有插件时,会通过第三方仓库查到,这些仓库的类型都是hosts类型,也就是在本机进行查询。

当本地内未能查找到相应的插件,会通过代理(proxy)类型进行下载插件,配置就在Central——>Remote Storage    Location(回源地址),这里我们填写阿里云的maven远程仓库进行下载

http://maven.aliyun.com/nexus/content/groups/public/

学习Jenkins(三) 随笔 第77张

学习Jenkins(三) 随笔 第78张

配置完成nexus后,在修改maven的settings配置

[root@linux-node2 ~]# vim /data/apache-maven-3.5.2/conf/settings.xml 
将其中的仓库链接地址修改为:
http://192.168.56.12:8081/nexus/content/groups/public/

这样在构建时,首次会从阿里云的maven仓库中下载插件,后面再次重新下载插件时会从本地进行下载

#########################################################################

  • 一、新建一台虚拟机安装tomcat

1)安装JDK
官网下载jdk:http://www.oracle.com/technetwork/java/javase/downloads/jdk8-downloads-2133151.html
下载jdk8,放到/usr/local/src/目录下
[root@linux-node3 ~]# tar -zxvf jdk-8u151-linux-x64.tar.gz
[root@linux-node3 ~]# mv jdk1.8.0_151 /usr/local/jdk1.8
[root@linux-node3 ~]# vim /etc/profile
增加如下内容:
JAVA_HOME=/usr/local/jdk1.8/
JAVA_BIN=/usr/local/jdk1.8/bin
JRE_HOME=/usr/local/jdk1.8/jre
PATH=$PATH:/usr/local/jdk1.8/bin:/usr/local/jdk1.8/jre/bin
CLASSPATH=/usr/local/jdk1.8/jre/lib:/usr/local/jdk1.8/lib:/usr/local/jdk1.8/jre/lib/charsets.jar
[root@linux-node3 ~]# source /etc/profile
[root@linux-node3 ~]# java -version
java version "1.8.0_151"
Java(TM) SE Runtime Environment (build 1.8.0_151-b12)
Java HotSpot(TM) 64-Bit Server VM (build 25.151-b12, mixed mode)
 
(2)安装tomcat
[root@linux-node3 ~]# wget http://apache.fayea.com/tomcat/tomcat-8/v8.5.20/bin/apache-tomcat-8.5.20.tar.gz
[root@linux-node3 ~]# tar -zxvf apache-tomcat-8.5.24.tar.gz 
[root@linux-node3 ~]# mv apache-tomcat-8.5.24 /usr/local/tomcat
[root@linux-node3 ~]# /usr/local/tomcat/bin/startup.sh 
[root@linux-node3 ~]# netstat -tulnp |grep 8080
tcp6       0      0 :::8080                 :::*                    LISTEN      3765/java 
 
提示:三个端口8080为提供web服务的端口,8005为管理端口,8009端口为第三方服务调用的端口,比如httpd和Tomcat结合时会用到
 
(3)配置tomcat
[root@linux-node3 ~]# vim /usr/local/tomcat/conf/tomcat-users.xml 
<tomcat-users>
<role rolename="admin"/>
<role rolename="admin-gui"/>
<role rolename="admin-script"/>
<role rolename="manager"/>
<role rolename="manager-gui"/>
<role rolename="manager-script"/>
<role rolename="manager-jmx"/>
<role rolename="manager-status"/>
<user name="admin" password="admin123456" roles="admin,manager,admin-gui,admin-script,manager-gui,manager-script,manager-jmx,manager-status" />
</tomcat-users>
[root@linux-node3 ~]# /usr/local/tomcat/bin/shutdown.sh 
[root@linux-node3 ~]# /usr/local/tomcat/bin/startup.sh 
 
在访问tomcat时,点击"manager webapp"会跳出一个验证弹框,输入用户名密码

学习Jenkins(三) 随笔 第79张

会跳转到以下界面,说明用户名密码无误,如图:

 学习Jenkins(三) 随笔 第80张

  • 二、下载zrlog的java代码push到gitlab上 

1)下载zrlog的代码
[root@linux-node2 home]# wget https://codeload.github.com/94fzb/zrlog/zip/master
--2017-12-25 11:02:45--  https://codeload.github.com/94fzb/zrlog/zip/master
Resolving codeload.github.com (codeload.github.com)... 192.30.255.121, 192.30.255.120
Connecting to codeload.github.com (codeload.github.com)|192.30.255.121|:443... connected.
HTTP request sent, awaiting response... 200 OK
Length: unspecified [application/zip]
Saving to: ‘master’
    [                                      <=>   ] 1,669,502    199KB/s   in 8.6s   
2017-12-25 11:02:56 (189 KB/s) - ‘master’ saved [1669502]
[root@linux-node2 home]# du -sh
1.7M.
[root@linux-node2 home]# du -sh master
1.6Mmaster
 
(2)解压
[root@linux-node2 home]# yum install -y unzip
[root@linux-node2 home]# unzip master
 
(3)初始化仓库,并将zrlog的代码push到gitlab
[root@linux-node2 home]# mkdir Java
[root@linux-node2 Java]# mv zrlog-master/* Java/
[root@linux-node2 Java]# git remote add orgin git@192.168.56.11:java/zrlog.git
[root@linux-node2 Java]# git add .
[root@linux-node2 Java]# git commit -m "add origin"
# On branch master
nothing to commit, working directory clean
[root@linux-node2 Java]# ll
total 48
drwxr-xr-x 2 root root 55 Dec 25 17:45 bin
-rw-r--r-- 1 root root 6114 Dec 25 17:45 CHANGELOG.md
drwxr-xr-x 2 root root 42 Dec 25 17:45 doc
-rw-r--r-- 1 root root 11358 Dec 25 17:45 LICENSE
-rwxr-xr-x 1 root root 6468 Dec 25 17:45 mvnw
-rw-r--r-- 1 root root 4994 Dec 25 17:45 mvnw.cmd
-rw-r--r-- 1 root root 7664 Dec 25 17:45 pom.xml
-rw-r--r-- 1 root root 3574 Dec 25 17:45 README.md
drwxr-xr-x 4 root root 28 Dec 25 17:45 src
[root@linux-node2 Java]# git push origin master
Counting objects: 457, done.
Compressing objects: 100% (426/426), done.
Writing objects: 100% (457/457), 2.98 MiB | 1.72 MiB/s, done.
Total 457 (delta 51), reused 0 (delta 0)
remote: Resolving deltas: 100% (51/51), done.
To git@192.168.56.11:java/zrlog.git
* [new branch] master -> master
  • 三、新建一个maven项目zr_blog

(1)新建项目

登录jenkins,点击“新建”,任务名称自定义(zr_blog)

选择“构建一个maven项目”

点击“确定”

(2)配置项目

源码管理

选择 “git”, Repository URL填写你的git地址,并配置对应的key,大家最好事前先在jenkins这台机器上能够直接远程git操作私有仓库

 构建触发器、构建环境、Pre Steps保持默认

 Build

“Root POM”为pom.xml, Goals and options 填写 clean install -D maven.test.skip=true

 Post Steps、构建设置保持默认

 构建后操作

 点击“增加构建后操作步骤”选择“Deploy war/ear to a container”,“WAR/EAR files”填写“**/*.war”,Contex path留空,Containers选择Tomcat 8.x,Tomcat URL填写要把war包发布到的那台机器的url,如http://192.168.56.13:8080

 Credentials这里需要点击右侧的Add,添加用户名和密码

 学习Jenkins(三) 随笔 第81张

点击"立即构建"查看控制台信息,如图:

 学习Jenkins(三) 随笔 第82张

(3)查看发布结果

查看linux-node3的webapps目录,会有相对应的war包,并已经进行解压,使用浏览器访问

[root@linux-node3 ~]# ll /usr/local/tomcat/webapps/
total 7160
drwxr-x--- 14 root root    4096 Dec 25 03:08 docs
drwxr-x---  6 root root    4096 Dec 25 03:08 examples
drwxr-x---  5 root root    4096 Dec 25 03:08 host-manager
drwxr-x---  6 root root    4096 Dec 25 04:05 manager
drwxr-x---  3 root root    4096 Dec 25 03:08 ROOT
drwxr-x---  9 root root    4096 Dec 25 04:04 zrlog-1.8.0
-rw-r-----  1 root root 7306944 Dec 25 04:04 zrlog-1.8.0.war

学习Jenkins(三) 随笔 第83张

 ###########################################################################

目录

一、环境说明和准备

1、环境说明

主机名 IP地址 角色 系统
deploy-server 192.168.56.12 发布 Centos 7.4
web 192.168.56.13 web服务器,nfs服务器 Centos 7.4

2、服务器准备工作

(1)发布机前期准备

a.增加普通用户并配置密码
[root@deploy-server ~]# useradd www
[root@deploy-server ~]# id www
uid=1000(www) gid=1000(www) groups=1000(www)
[root@deploy-server ~]# passwd www
[root@deploy-server ~]# yum install -y git tree
b.创建部署需要的目录并初始化git目录
[root@deploy-server ~]# mkdir -pv /deploy/{code/{www,jxs,wap,gys,glzx,yyzx},config,tar,tmp}
[root@deploy-server ~]# chown -R www.www /deploy
[www@deploy-server ~]$ tree /deploy
/deploy
├── code
│   ├── glzx
│   ├── gys
│   ├── jxs
│   ├── wap
│   ├── www
│   └── yyzx
├── config
├── tar
└── tmp
[www@deploy-server ~]$ cd /deploy/code/www && git init
c.创建配置文件config.php
[www@deploy-server ~]$ vim /deploy/config/config.php 
this is config.php
[www@deploy-server ~]$ tree /deploy
/deploy
├── code
│   ├── glzx
│   ├── gys
│   ├── jxs
│   ├── wap
│   ├── www
│   └── yyzx
├── config
│   └── config.php
├── tar
└── tmp
d.配置发布机和目标机的ssh通信
[www@deploy-server deploy]$ cat /home/www/.ssh/id_rsa.pub 
ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDzM3AW6/X+djvKJTsdFbY3ik+mlradxpD3COoTP5h6x509unksuCdduV7awPjEGHvK2GVjJmvckxdvLkMc23p7bsctHlturPN2VozJTrYwXMAbmxf97cKE/fpKhjPXG8HlWBLpEaTM8PITgvdcyaeAUaIN+/h5VrA8TZKFAgbxDLxtgwqPzYIG9nqCO7MMCgzhJxI6PDQ6KVU9rHal/p4XKTIy4Rq4FzZTav2tS4zNJ7kX9+e6EO0JTooPanJXBTltLOJJsKxnlA7tc20rq6+0XVqbUBKYahL/8ZzkxZozNrNq7wtIuuJo0WTDFzDdPcJyAGlRWLuwct7y4p4UApVz www@deploy-server

[www@deploy-server ~]$ ssh-copy-id www@192.168.56.13
/bin/ssh-copy-id: INFO: Source of key(s) to be installed: "/home/www/.ssh/id_rsa.pub"
The authenticity of host '192.168.56.13 (192.168.56.13)' can't be established.
ECDSA key fingerprint is SHA256:ahG6dBy/Z1nUIUWhQQrylsiwBlnDKC/jz8rnaPU2eF0.
ECDSA key fingerprint is MD5:6e:58:0b:02:1c:a4:41:51:e8:7d:33:4d:46:bb:a0:68.
Are you sure you want to continue connecting (yes/no)? yes
/bin/ssh-copy-id: INFO: attempting to log in with the new key(s), to filter out any that are already installed
/bin/ssh-copy-id: INFO: 1 key(s) remain to be installed -- if you are prompted now it is to install the new keys
www@192.168.56.13's password: 

Number of key(s) added: 1

Now try logging into the machine, with:   "ssh 'www@192.168.56.13'"
and check to make sure that only the key(s) you wanted were added.

[www@deploy-server ~]$ ssh 192.168.56.13
Last login: Fri Nov  2 18:01:02 2018
[www@web ~]$ 
e.将ssh公钥复制到github或gitlab

学习Jenkins(三) 随笔 第84张

(2)web服务器准备

a.部署NFS服务器
[root@web ~]# yum install -y nfs-utils rpcbind
[root@web ~]# vim /etc/exports
/nas/www 192.168.56.0/24(rw,sync,no_root_squash)
/nas/jxs 192.168.56.0/24(rw,sync,no_root_squash)
/nas/wap 192.168.56.0/24(rw,sync,no_root_squash)
/nas/glzx 192.168.56.0/24(rw,sync,no_root_squash)
/nas/yyzx 192.168.56.0/24(rw,sync,no_root_squash)
/nas/gys 192.168.56.0/24(rw,sync,no_root_squash)
[root@web ~]# systemctl start rpcbind
[root@web ~]# systemctl start nfs
[root@web ~]# showmount -e
Export list for web:
/nas/gys  192.168.56.0/24
/nas/yyzx 192.168.56.0/24
/nas/glzx 192.168.56.0/24
/nas/wap  192.168.56.0/24
/nas/jxs  192.168.56.0/24
/nas/www  192.168.56.0/24
b.挂载共享目录
[root@web ~]# mkdir /webroot/{www,jxs,wap,gys,glzx,yyzx}
[root@web ~]# chown -R www.www /webroot
[root@web ~]# mount -f nfs 192.168.56.13:/nas/www /webroot/www
[root@web ~]# df -h
Filesystem               Size  Used Avail Use% Mounted on
/dev/mapper/centos-root 18G 1.7G 16G 10% /
devtmpfs                 482M     0  482M   0% /dev
tmpfs                    493M     0  493M   0% /dev/shm
tmpfs                    493M  6.8M  486M   2% /run
tmpfs                    493M     0  493M   0% /sys/fs/cgroup
/dev/sda1                497M  171M  326M  35% /boot
tmpfs                     99M     0   99M   0% /run/user/0
192.168.56.13:/nas/www    18G  1.7G   16G  10% /webroot/www
c.部署nginx+php
[root@web ~]# useradd www
[root@web ~]# passwd www
[root@web ~]# yum install -y nginx php php-fpm
[root@web ~]# vim /etc/nginx/nginx.conf
user www;
worker_processes auto;
error_log /var/log/nginx/error.log;
pid /run/nginx.pid;

# Load dynamic modules. See /usr/share/nginx/README.dynamic.
include /usr/share/nginx/modules/*.conf;

events {
    worker_connections 1024;
}

http {
    log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
                      '$status $body_bytes_sent "$http_referer" '
                      '"$http_user_agent" "$http_x_forwarded_for"';

    access_log  /var/log/nginx/access.log  main;

    sendfile            on;
    tcp_nopush          on;
    tcp_nodelay         on;
    keepalive_timeout   65;
    types_hash_max_size 2048;

    include             /etc/nginx/mime.types;
    default_type        application/octet-stream;

    # Load modular configuration files from the /etc/nginx/conf.d directory.
    # See http://nginx.org/en/docs/ngx_core_module.html#include
    # for more information.
    include /etc/nginx/conf.d/*.conf;


}
[root@web ~]# mkdir /data/web -pv && chown -R www.www /data
[root@web ~]# vim /etc/nginx/nginx.conf
server {
        listen 80;
        server_name  localhost;

        root /data/web/www;
        index index.php index.htm index.html;
        client_max_body_size 20m;
        location / {
                proxy_read_timeout 150;
                try_files $uri $uri/ /index.php; } location ~* .*\.php$ { #try_files $uri =404; include fastcgi_params; fastcgi_pass 127.0.0.1:9000; fastcgi_split_path_info ^(.+\.php)(/.+)$;
                fastcgi_param PATH_INFO       $fastcgi_path_info;
                fastcgi_index index.php;
                fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
        }
}
[root@web ~]# nginx -t
nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
nginx: configuration file /etc/nginx/nginx.conf test is successful
[root@web ~]# systemctl start nginx
[root@web ~]# vim /etc/php-fpm.d/www.conf 
user www
group www
....
[root@web ~]# php-fpm -t
[03-Nov-2018 10:16:18] NOTICE: configuration file /etc/php-fpm.conf test is successful
[root@web ~]# systemctl start php-fpm
[root@web ~]# curl localhost -I
HTTP/1.1 200 OK
Server: nginx/1.12.2
Date: Sat, 03 Nov 2018 02:16:36 GMT
Content-Type: text/html
Content-Length: 35
Last-Modified: Sat, 03 Nov 2018 02:07:00 GMT
Connection: keep-alive
ETag: "5bdd02c4-23"
Accept-Ranges: bytes

二、发布脚本编写

1、自动化部署流程设计

  1. 发布机获取代码(直接拉取),从svn或git仓库进行拉取
  2. 发布机编译代码(可选,java语言需要编译,PHP无需编译)
  3. 将配置文件拷贝到代码文件(由于配置文件有数据库等机密信息,需要独立处理)
  4. 代码打包(将代码进行压缩打包)
  5. SCP到目标服务器目录
  6. 将目标服务器移除集群
  7. 在目标服务器上进行解压传过来的代码
  8. 解压后,对代码根目录进行软链接到刚才的目录文件,实现版本链接
  9. 重启(可选,tomcat需要重启)
  10. 测试
  11. 加入集群

2、自动化部署脚本编写

#!/bin/bash 
#deploy-server create dir as root
#[ -d /deploy ] && mkdir -pv /deploy/{code/web-demo,config,tar,tmp} && chown -R www.www /deploy

#node-server create dir as root
#[ -d /data ] && mkdir -pv /data/web && chown -R www.www /data
#nfs dir /nas/www mount to /webroot

#Node List
NODE="192.168.56.13"

#Shell ENV
SHELL_NAME="deploy.sh"
SHELL_DIR="/home/www"
SHELL_LOG="${SHELL_DIR}/${SHELL_NAME}.log"

#Code ENV
PRO_NAME="www"
CODE_DIR="/deploy/code/www"
CONFIG_DIR="/deploy/config"
TMP_DIR="/deploy/tmp"
TAR_DIR="deploy/tar"
LOCK_FILE="/tmp/deploy.lock"

#Date/Time ENV
LOG_DATE='date "+%Y-%m-%d"'
LOG_TIME='date "+%H-%M-%S"'

CDATE=$(date "+%Y-%m-%d")
CTIME=$(date "+%H-%M-%S")

useage(){
    echo $"Useage: $0 { deploy |rollback [ list | version ] }"
}

url_test(){
    URL=$1
    curl -s --head $URL |grep '200 OK'
    if [ $? -ne 0 ];then
        shell_unlock;
        writelog "test error" && exit;
    fi
}

writelog(){
    LOGINFO=$1
    echo "${CDATE} ${CTIME}: ${SHELL_NAME} : ${LOGINFO} " >> ${SHELL_LOG}
}

code_get(){
    writelog "code_get";
    cd ${CODE_DIR} && git pull git@github.com:kin08200/learngit.git
    cp -r ${CODE_DIR} ${TMP_DIR}
    API_VERL=$(git show |grep commit |cut -d ' ' -f2 )
        API_VER=$(echo ${API_VERL:0:6})
    echo $API_VER
}

code_config(){
    writelog "code_config"
    /bin/cp -r ${CONFIG_DIR}/* ${TMP_DIR}/${PRO_NAME}
        PKG_NAME=${PRO_NAME}_"${API_VER}"_"${CDATE}-${CTIME}"
        cd ${TMP_DIR} && mv ${PRO_NAME} ${PKG_NAME}
}

code_tar(){
    writelog "code_tar"
    cd ${TMP_DIR} && tar -czf ${PKG_NAME}.tar.gz ${PKG_NAME}
        writelog "${PKG_NAME}.tar.gz"
}

code_scp(){
    writelog "code_scp"
    scp ${TMP_DIR}/${PKG_NAME}.tar.gz $NODE:/webroot/www
}

code_deploy(){
    writelog "code_deploy"
    ssh $NODE "cd /webroot/www && tar -zxf ${PKG_NAME}.tar.gz"
    ssh $NODE "rm -rf /data/web/www && ln -s /webroot/www/${PKG_NAME} /data/web/www"
}

code_test(){
    url_test "http://192.168.56.13"
}

rollback_fun(){
    ssh $NODE "rm -rf /data/web/www && ln -s /webroot/www/$1 /data/web/www"   
}

rollback(){
    if [ -z $1 ];then
        shell_unlock;
        echo "Please input rollback version." && exit;
        fi
        case $1 in 
            list)
            ls -l /deploy/tmp/*.tar.gz
            ;;
            *)
            rollback_fun $1
            ;;
        esac
}


shell_lock(){
    touch ${LOCK_FILE}
}

shell_unlock(){
    rm -f ${LOCK_FILE}
}

main(){
    if [ -f ${LOCK_FILE} ];then
        echo "Deploy is running" && exit
    fi
    DEPLOY_METHOD=$1
    ROLLBACK_VER=$2
    case $DEPLOY_METHOD in
        deploy)
            shell_lock;
        code_get;
        code_config;
        code_tar;
            code_scp;
        code_deploy;
        code_test;
        shell_unlock;
        ;;
    rollback)
        shell_lock;
        rollback $ROLLBACK_VER;
        shell_unlock;
        ;;
    *)
        useage;
        ;;
    esac
}

main $1 $2

三、发布测试

1、开发机和github添加ssh信任

[www@localhost ~]$ cat .ssh/id_rsa.pub 
ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQC+ta7tkljnIgqvgEugQvIfVxH/a+geX250ZhOpe+14Q8EBQSI+qGyXCeihln+0aQpzIERvNBZ7JjWCg5XeQlgPBgCmqoQKNTWl/NUBT+uY/NY9fIGdRCVBvVcDC554Be48zB57mtapKQEkqm/8kmq7sPRQDv98l5wvFvYOPxocmjnioDZr3GeYmgdFPNJ5WGg6yY29IHXgh2v3eCXLwX2Z2eUdKCpV1LS42wdAN8TqHFCEmthREIq2r86ZKPOovD6Micq7wa2yJqtA/hkv+DvEhRzOIVznfW5EptOyKYcittGu63JGMSbCr1uCdW7PLUQ8aIWDDlip+/EcIt0KkuJJ www@localhost.localdomain

2、克隆项目到开发机进行开发测试

[www@localhost ~]$ mkdir dev && cd dev
[www@localhost dev]$ git clone git@github.com:kin08200/learngit.git
[www@localhost dev]$ ll
total 4
drwxrwxr-x 3 www www 4096 Nov  2 22:02 learngit
[www@localhost dev]$ cd learngit

3、修改index.html文件

[www@localhost learngit]$ ll
total 8
-rw-rw-r-- 1 www www  0 Nov  2 04:31 123
-rw-rw-r-- 1 www www 35 Nov  2 22:02 index.html
-rw-rw-r-- 1 www www 80 Nov  2 04:31 readme.txt
[www@localhost learngit]$ echo "<h1> welcome to Beijing </h1>" > index.html

4、提交代码

[www@localhost learngit]$ git add .
[www@localhost learngit]$ git commit -m "modify index.html"
[www@localhost learngit]$ git push origin master

5、发布代码

[www@deploy-server ~]$ ./deploy.sh deploy
remote: Enumerating objects: 5, done.
remote: Counting objects: 100% (5/5), done.
remote: Compressing objects: 100% (2/2), done.
remote: Total 3 (delta 0), reused 3 (delta 0), pack-reused 0
Unpacking objects: 100% (3/3), done.
From github.com:kin08200/learngit
 * branch            HEAD       -> FETCH_HEAD
Updating 9a781b2..683a440
Fast-forward
 index.html | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)
683a44
www_683a44_2018-11-03-10-06-56.tar.gz                                                                                                                      100%   22KB   9.3MB/s   00:00    
HTTP/1.1 200 OK

6、测试访问

[www@deploy-server ~]$ curl 192.168.56.13
<h1>
    welcome to Beijing!!!!
</h1>

7、回滚测试

[root@web ~]# ll /data/web/
total 0
lrwxrwxrwx 1 www www 43 Nov  3 10:46 www -> /webroot/www/www_683a44_2018-11-03-10-06-56

测试访问如下,下面进行查看版本列表,并选择回滚到www_9a781b_2018-11-03-09-59-44版本

学习Jenkins(三) 随笔 第85张

[www@deploy-server ~]$ ./deploy.sh rollback list
-rw-rw-r-- 1 www www 22686 Nov 3 10:07 /deploy/tmp/www_683a44_2018-11-03-10-06-56.tar.gz
-rw-rw-r-- 1 www www 22685 Nov 3 10:44 /deploy/tmp/www_683a44_2018-11-03-10-43-55.tar.gz
-rw-rw-r-- 1 www www 22222 Nov 3 09:48 /deploy/tmp/www_9a781b_2018-11-03-09-48-36.tar.gz
-rw-rw-r-- 1 www www 22231 Nov 3 09:52 /deploy/tmp/www_9a781b_2018-11-03-09-52-32.tar.gz
-rw-rw-r-- 1 www www 22228 Nov 3 09:58 /deploy/tmp/www_9a781b_2018-11-03-09-58-15.tar.gz
-rw-rw-r-- 1 www www 22234 Nov 3 09:59 /deploy/tmp/www_9a781b_2018-11-03-09-59-44.tar.gz

[www@deploy-server ~]$ ./deploy.sh rollback www_9a781b_2018-11-03-09-59-44
[root@web ~]# ll /data/web/
total 0
lrwxrwxrwx 1 www www 43 Nov  3 10:48 www -> /webroot/www/www_9a781b_2018-11-03-09-59-44

再进行访问测试:

学习Jenkins(三) 随笔 第86张

,
  • 一、什么是持续集成?

(1)Continuous integration(CI)

持续集成是一种软件开发实践,即团队开发成员经常集成他们的工作,通常每个成员至少集成一次,也就意味着每天可能会发生多次集成。每次集成都通过自动化的构建(包括编译,发布,自动化测试)来验证,从而尽快地发现集成错误。许多团队发现这个过程可以大大减少集成的问题,让团队能够更快的开发内聚的软件。

学习Jenkins(三) 随笔 第87张

(2)没有持续集成

项目做模块集成的时候,发现很多借口都不通==>浪费大量时间

需要手动去编译打包最新的代码==>构建过程不透明

发布代码,上线,基本靠手工==>脚本乱飞

 

(3)持续集成最佳实践:

维护一个单一的代码库

使构建自动化

执行测试是构建的一部分

集成日志及历史记录

使用统一的依赖包管理库

每天至少集成一次

 

(4)jenkins介绍

Jenkins只是一个平台,真正运作的都是插件。这就是jenkins流行的原因,因为jenkins什么插件都有 
Hudson是Jenkins的前身,是基于Java开发的一种持续集成工具,用于监控程序重复的工作,Hudson后来被收购,成为商业版。后来创始人又写了一个jenkins,jenkins在功能上远远超过hudson

Jenkins官网:https://jenkins.io/

 

(5)部署代码上线流程:

1.代码获取(直接了拉取)

2.编译 (可选)

3.配置文件放进去

4.打包

5.scp到目标服务器

6.将目标服务器移除集群

7.解压并放置到Webroot

8.Scp 差异文件

9.重启 (可选)

10.测试

11.加入集群

  • 二、jenkins部署

1)安装JDK 
[root@linux-node2 ~]# yum instsall -y java-1.8.0-openjdk java-1.8.0-openjdk-devel
 
(2)下载jenkins的rpm包
[root@linux-node2 ~]# wget https://mirrors.tuna.tsinghua.edu.cn/jenkins/redhat-stable/jenkins-2.32.3-1.1.noarch.rpm
--2017-12-21 09:11:58--  https://mirrors.tuna.tsinghua.edu.cn/jenkins/redhat-stable/jenkins-2.32.3-1.1.noarch.rpm
正在解析主机 mirrors.tuna.tsinghua.edu.cn (mirrors.tuna.tsinghua.edu.cn)... 101.6.6.178, 2402:f000:1:416:101:6:6:177
正在连接 mirrors.tuna.tsinghua.edu.cn (mirrors.tuna.tsinghua.edu.cn)|101.6.6.178|:443... 已连接。
已发出 HTTP 请求,正在等待回应... 200 OK
长度:69675984 (66M) [application/x-redhat-package-manager]
正在保存至: “jenkins-2.32.3-1.1.noarch.rpm”
 
(3)安装jenkins
[root@linux-node2 ~]# rpm -ivh jenkins-2.32.3-1.1.noarch.rpm 
警告:jenkins-2.32.3-1.1.noarch.rpm: 头V4 DSA/SHA1 Signature, 密钥 ID d50582e6: NOKEY
准备中...                          ################################# [100%]
正在升级/安装...
   1:jenkins-2.32.3-1.1               ################################# [100%]
    
(4)启动jenkins
[root@linux-node2 ~]# service jenkins start
Starting jenkins (via systemctl):                          [  确定  ]
 
[root@linux-node2 ~]# netstat -tulnp|grep 8080
tcp6       0      0 :::8080                 :::*                    LISTEN      42160/java 
浏览器访问:192.168.56.12:8080:如图
[root@linux-node2 ~]# cat /var/lib/jenkins/secrets/initialAdminPassword
8addd06f53f6405da6133356af1ca3b0    #登陆界面有提示输入密码,初始密码文件为/var/lib/jenkins/secrets/initialAdminPassword
 
友情提示:jenkins如果跟gitlab在一台服务器需要将jenkins的端口进行修改,需要将jenkins的8080修改为其他端口

学习Jenkins(三) 随笔 第88张

安装所有插件:

学习Jenkins(三) 随笔 第89张

安装插件完成,设置用户名:jenkins,密码:jenkins

学习Jenkins(三) 随笔 第90张

  • 三、jenkins的插件以及配置

Jenkins系统管理比较重要的就是插件管理了 ,因为jenkins的工作全部是由插件来完成。

在插件管理中,有可更新、可选插件、已安装,日常的插件安装都是在这个界面上完成的。比如为了和gitlab协同,我们需要安装gitlab的插件。

学习Jenkins(三) 随笔 第91张

学习Jenkins(三) 随笔 第92张

在高级选项中,我们可以在jenkins官网下载插件,然后上传插件 ,如图:

 学习Jenkins(三) 随笔 第93张

因为很多插件需要×××才可以继续下载,jenkins还提供了代理的设置


还是在服务器目录下进行上传插件

目录路径= /var/lib/jenkins/plugins/

这个目录下是我们安装所有的插件

jenkins的目录介绍:

[root@linux-node2 ~]# rpm -ql jenkins
/etc/init.d/jenkins                #jenkins的启动文件
/etc/logrotate.d/jenkins
/etc/sysconfig/jenkins             #jenkins的配置文件
/usr/lib/jenkins                   
/usr/lib/jenkins/jenkins.war       #jenkins的程序war包
/usr/sbin/rcjenkins                #jenkins的为二进制文件
/var/cache/jenkins                 #jenkins的程序文件,运行程序解压出来的
/var/lib/jenkins                   #jenkins的主目录
/var/log/jenkins                   #jenkins的日志文件
 
jenkins的升级,只需要将war包解压到/var/lib/jenkins目录下,重启jenkins即可。
 
友情提示:
卡启动问题
jenkins在第一次安装启动时会向官网回传信息,如果网络离线可以正常安装。当网络在线,但是
还有可能是内存不足
 
备份:
tar zcvf jenkins.tar.gz /var/lib/jenkins

系统管理-->系统配置

执行者数量:配置并发数量,一般设置为5,不超过10

用法:如果是主server,可以不选,如果是从级别必须选择“尽可能的使用这个节点”

生成前等待时间:配置该时间,避免错误操作,有时间返回

学习Jenkins(三) 随笔 第94张

学习Jenkins(三) 随笔 第95张

  • 三、jenkins升级

1)查看war包所在的目录
[root@linux-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
 
(2)下载最新稳定版的war包
[root@linux-node2 ~]# wget https://mirrors.tuna.tsinghua.edu.cn/jenkins/war/2.46/jenkins.war
--2017-12-21 14:56:10--  https://mirrors.tuna.tsinghua.edu.cn/jenkins/war/2.46/jenkins.war
Resolving mirrors.tuna.tsinghua.edu.cn (mirrors.tuna.tsinghua.edu.cn)... 101.6.6.178, 2402:f000:1:416:101:6:6:177
Connecting to mirrors.tuna.tsinghua.edu.cn (mirrors.tuna.tsinghua.edu.cn)|101.6.6.178|:443... connected.
HTTP request sent, awaiting response... 200 OK
Length: 68663046 (65M) [application/java-archive]
Saving to: ‘jenkins.war’
 
36% [====================================================>                                                                                               ] 24,829,614   707KB/s  eta 60s

当前jenkins版本为2.32.2

学习Jenkins(三) 随笔 第96张

3)停止jenkins服务
[root@linux-node2 ~]# service jenkins stop
Stopping jenkins (via systemctl):                          [  OK  ]
 
(4)备份原来的war包,并拷贝最新版本war包到/usr/lib/jenkins目录下
[root@linux-node2 ~]# cd /usr/lib/jenkins/
[root@linux-node2 jenkins]# mv jenkins.war jenkins-2.32.2.war.bak
[root@linux-node2 jenkins]# mv /root/jenkins.war .
[root@linux-node2 jenkins]# service jenkins start
Starting jenkins (via systemctl):                          [  OK  ]
[root@linux-node2 jenkins]# netstat -tulnp |grep 8080
tcp6       0      0 :::8080                 :::*                    LISTEN      47298/java   
 
成功升级到jenkins 2.46版本

学习Jenkins(三) 随笔 第97张

  • 四、jenkins备份

在jenkins界面创建一些项目,这里使用rsync,主要是为了保持备份的属性,如果使用scp或cp有时会导致文件属性的改变而导致jenkins异常。

1)创建备份目录
[root@linux-node2 ~]# mkdir /data/backup/jenkins -p
 
(2)备份/var/lib/jenkins目录
[root@linux-node2 ~]# rsync -raz --delete --progress /var/lib/jenkins /data/backup/jenkins/3)删除/var/lib/jenkins/
[root@linux-node2 ~]# rm -rf /var/lib/jenkins/
 
[root@linux-node2 ~]# service jenkins restart
Restarting jenkins (via systemctl):  Job for jenkins.service failed because the control process exited with error code. See "systemctl status jenkins.service" and "journalctl -xe" for details.
                                                           [FAILED]
[root@linux-node2 ~]# service jenkins status
JENKINS_HOME directory does not exist: /var/lib/jenkins
 
(4)恢复备份
[root@linux-node2 ~]# rsync -raz --delete /data/backup/jenkins/jenkins /var/lib/
[root@linux-node2 ~]# service jenkins restart
Restarting jenkins (via systemctl):                        [  OK  ]

 #############################################################

,
  • 使用git+jenkins实现持续集成

学习Jenkins(三) 随笔 第98张

Step1:构建一个自由风格的php-deploy

学习Jenkins(三) 随笔 第99张

Step2:Gernal配置,丢弃旧的构建,防止jenkins构建较多之后变臃肿

 学习Jenkins(三) 随笔 第100张

Step3:源码管理:这里使用git插件,也可以使用svn插件

 学习Jenkins(三) 随笔 第101张

将git路径存在这里还需要权限认证,否则会出现error 。
jenkins服务器上生成SSH-Key

[root@linux-node2 ~]# yum install -y git
[root@linux-node2 ~]# ssh-keygen 
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:00FQjn5P6qAtok4BuE42TyfuNJnblzZ389XwKBhmHjY root@linux-node2
The key's randomart image is:
+---[RSA 2048]----+
|        .oo      |
|.        +       |
|o       . o      |
| o     . . .     |
|.+.o .  S E . .  |
|+ =.=    B O   +.|
| ..B    o + o ..o|
| .o = .B + o ..  |
| .o+ o+.+ o o.   |
+----[SHA256]-----+
[root@linux-node2 ~]# cat .ssh/id_rsa.pub 
ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQC+/XyUMNP5Wm63hhcACosVyRtmJxTSnT46HSKZ2PhduTHPIJcfhVTmeCk1zwO0fP8PmwXFf0+G9ki8CupE/+xcOy14TCqxNgvP8o514IjXOFV7SO1lnHKH3t0RfaFEloRZHnrgIcWiZrFvYRT/TFznWO86sfHPzlW6WF9elTqRURNR60bwv9C6iw4PpYjGVIST/SeGl75axtUjJr544jB5pEWtNZ09ktCKpPeFBvgCc9exdzOQuzaCXQrroNU0p6MB6KkoIOmpkN92cDPdg4EgBYDjwcl38FbXOq3N0QL8PT+IZpHBWFVEAZU2alI02H5NNUy9p2K/Br4NY3UvYZiP root@linux-node2

学习Jenkins(三) 随笔 第102张

学习Jenkins(三) 随笔 第103张

命令行测试添加ssh-key后能否正常拉取
[root@linux-node2 ~]# git clone git@192.168.56.11:java/app1.git
Cloning into 'app1'...
The authenticity of host '192.168.56.11 (192.168.56.11)' can't be established.
ECDSA key fingerprint is SHA256:p2lhKmsPQ6K+dWHHvbJg0GV+Ni9VM7vlViKrYsZLP1s.
ECDSA key fingerprint is MD5:22:14:1c:37:de:47:1c:4a:2f:88:b1:dc:e2:d0:02:17.
Are you sure you want to continue connecting (yes/no)? yes
Warning: Permanently added '192.168.56.11' (ECDSA) to the list of known hosts.
remote: Counting objects: 11, done.
remote: Compressing objects: 100% (7/7), done.
remote: Total 11 (delta 0), reused 11 (delta 0)
Receiving objects: 100% (11/11), done.
[root@linux-node2 ~]# ll
total 68048
-rw-------. 1 root root      948 Dec  3 01:26 anaconda-ks.cfg
drwxr-xr-x  3 root root       62 Dec 21 15:53 app1
-rw-r--r--  1 root root 69675984 Mar  2  2017 jenkins-2.32.3-1.1.noarch.rpm

学习Jenkins(三) 随笔 第104张

然后保存,立即构建一次,会拉取master的代码库

学习Jenkins(三) 随笔 第105张

点开学习Jenkins(三) 随笔 第106张可以看到控制台的输出,如图:

学习Jenkins(三) 随笔 第107张

/var/lib/jenkins/workspace/php-deploy目录用于存放代码信息

[root@linux-node2 php-deploy]# ll
total 12
-rw-r--r-- 1 root root 28 Dec 21 16:11 index.html
-rw-r--r-- 1 root root 12 Dec 21 16:11 new.html
-rw-r--r-- 1 root root 19 Dec 21 16:11 readme
[root@linux-node2 php-deploy]# pwd
/var/lib/jenkins/workspace/php-deploy

这里我们拉取的代码需要推送到远程代码目录,需要如下操作:
架设linux-node1为web服务,目录为/data/www/php-deploy 

[root@linux-node1 ~]# mkdir /data/www/php-deploy -p
添加node2的免秘钥登陆
[root@linux-node1 ~]# vim .ssh/authorized_keys
[root@linux-node1 ~]# chmod 600 .ssh/authorized_keys 
[root@linux-node2 ~]# ssh 192.168.56.11
Last login: Mon Dec  4 17:41:56 2017 from 192.168.56.1
[root@linux-node1 ~]# 

修改项目设置,配置构建:Execute shell,相当于将代码自动发布到linux-node1的代码目录中。

学习Jenkins(三) 随笔 第108张

接下来,我们重新构建一次,并查看控制台输出:

学习Jenkins(三) 随笔 第109张

在node1上查看目录,也会有相应的代码信息 

[root@linux-node1 ~]# ll /data/www/php-deploy/
total 12
-rw-r--r-- 1 root root 28 Dec 21 16:11 index.html
-rw-r--r-- 1 root root 12 Dec 21 16:11 new.html
-rw-r--r-- 1 root root 19 Dec 21 16:11 readme
[root@linux-node1 ~]# 

 #########################################################################

,
  • 一、什么是Maven

maven是一个项目管理和综合工具。Maven提供给开发人员构建一个完整的生命周期框架。

开发团队可以自动完成该项目的基础设施建设,Maven使用标准的目录结构和默认构建生命周期

maven是属于Apache的开源项目

maven主要服务于java平台的构建、依赖管理、项目管理。

  • 二、手动安装MAVEN

1)下载maven
[root@linux-node2 ~]# wget http://mirrors.hust.edu.cn/apache/maven/maven-3/3.5.2/binaries/apache-maven-3.5.2-bin.tar.gz
2)解压
[root@linux-node2 ~]# tar -zxvf apache-maven-3.5.2-bin.tar.gz #解压即可使用
[root@linux-node2 ~]# mv apache-maven-3.5.2 /data/3)配置环境变量
[root@linux-node2 bin]# export PATH=$PATH:/data/apache-maven-3.5.2/bin
[root@linux-node2 bin]# vim /etc/profile
export PATH=$PATH:/data/apache-maven-3.5.2/bin

(4)测试
[root@linux-node2 ~]# mvn -v

Apache Maven 3.5.2 (138edd61fd100ec658bfa2d307c43b76940a5d7d; 2017-10-18T15:58:13+08:00)
Maven home: /data/apache-maven-3.5.2
Java version: 1.8.0_151, vendor: Oracle Corporation
Java home: /usr/lib/jvm/java-1.8.0-openjdk-1.8.0.151-1.b12.el7_4.x86_64/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"
  • 三、POM文件解析

POM是研发给出的

Project Object Model,项目对象模型

通过xml格式保存的pom.xml文件

作用类似ant的build.xml文件,功能更强大

该文件用于管理:源代码、配置文件、开发者的信息和角色、问题追踪系统、组织信息、项目授权、项目的url、项目的依赖关系等等。

  • 四、配置系统MAVEN

系统管理-->Global Tool Configuration

新增maven

取消自动安装

填写maven实际安装路径/data/apache-maven-3.5.2

学习Jenkins(三) 随笔 第110张

  • 四、新建maven项目

1)新建maven项目
(2)指定源码文职(git或svn)
(3)指定build选项
clean install
clean install -Dmaven.test.skip=true4)指定execute shell
java -jar target/testweb-0.0.1-SNAPSHOT.jar

配置maven:

settings.xml是maven的主要配置文件
位置$home/.m2是maven下载的插件的存储位置

(1)新建maven项目
新建一个项目,选择构建一个maven项目。如果此处没有“构建一个maven项目”的选项,需要安装插件:Maven Integration Plugin

学习Jenkins(三) 随笔 第111张

(2)指定源码位置(git或svn)

学习Jenkins(三) 随笔 第112张

(3)指定build选项
clean install
clean install -Dmaven.test.skip=true

学习Jenkins(三) 随笔 第113张

(4)指定execute shell
java -jar target/testweb-0.0.1-SNAPSHOT.jar

 学习Jenkins(三) 随笔 第114张

(5)立即构建
这里在构建的过程中,可能会出现插件下载失败,需要更改maven的插件源,编辑/data/apache-maven-3.5.2/conf/settings.xml

 学习Jenkins(三) 随笔 第115张

立即构建完成,可以在/var/lib/jenkins/workspace/Java/下可以看到拉取的代码,我们找到整个项目的的jar包并执行,可以看到hello world

学习Jenkins(三) 随笔 第116张

[root@linux-node2 target]# java -jar testweb-0.0.1-SNAPSHOT.jar 
Hello World! i am guo2
  • 五、将java的代码发布到linux-node1上

 (1)修改项目的Execte shell设置,再重新构建 

rsync -raz --delete --progress target/testweb-0.0.1-SNAPSHOT.jar 192.168.56.11:/opt/
ssh root@192.168.56.11 "java -jar /opt/testweb-0.0.1-SNAPSHOT.jar"

学习Jenkins(三) 随笔 第117张

[root@linux-node1 ~]# ll /opt/
total 8
drwxr-xr-x 10 root root 4096 Dec  9 17:08 gitlab
-rw-r--r--  1 root root 2663 Dec 22 14:16 testweb-0.0.1-SNAPSHOT.jar

[root@linux-node1 ~]# java -jar /opt/testweb-0.0.1-SNAPSHOT.jar 
Hello World! i am guo2

到此一个maven项目就完成了!

  •  六、maven项目按版本发布

1)安装git parameter plugin插件

(2)任务配置中勾选<参数化构建>3)选择git parameter

(4)创建变量名 release(自定义)

(5)选择发布类型:
tag:按标签发布
branch:按分支发布
Revison:按修订发布

(1)安装git parameter plugin插件

 学习Jenkins(三) 随笔 第118张

修改pom.xml中的版本改为v1.0

[root@linux-node2 testing]# vim pom.xml 

<version>v1.0</version>

[root@linux-node2 testing]# git status
# On branch 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:   pom.xml
#
no changes added to commit (use "git add" and/or "git commit -a")
[root@linux-node2 testing]# git add .
[root@linux-node2 testing]# git commit -m "v1.0"
[master eed5815] v1.0
 1 file changed, 1 insertion(+), 1 deletion(-)
[root@linux-node2 testing]# git push origin master
Counting objects: 5, done.
Compressing objects: 100% (3/3), done.
Writing objects: 100% (3/3), 281 bytes | 0 bytes/s, done.
Total 3 (delta 2), reused 0 (delta 0)
To git@192.168.56.11:java/Java.git
   37d2bd1..eed5815  master -> master

学习Jenkins(三) 随笔 第119张

给Java项目中的版本修改后打上标签

学习Jenkins(三) 随笔 第120张

此时我们再修改

[root@linux-node2 testing]# vim src/main/java/com/ghz/testweb/App.java 
package com.ghz.testweb;

/**
 * Hello world!
 *
 */
public class App
{
    public static void main( String[] args )
    {
        System.out.println( "Hello World! i am guo2 v1.0" );
    }
}
[root@linux-node2 testing]# git add .
[root@linux-node2 testing]# git commit -m "featrue1"
[master 6402300] featrue1
 1 file changed, 1 insertion(+), 1 deletion(-)
[root@linux-node2 testing]# git push origin master
Counting objects: 17, done.
Compressing objects: 100% (4/4), done.
Writing objects: 100% (9/9), 565 bytes | 0 bytes/s, done.
Total 9 (delta 2), reused 0 (delta 0)
To git@192.168.56.11:java/Java.git
   eed5815..6402300  master -> master

学习Jenkins(三) 随笔 第121张

此时进行构建,由于版本修改了,会报错:

学习Jenkins(三) 随笔 第122张

但是我们每次进行版本的修改后如果都去修改excute shell就显得太麻烦

(2)任务配置中勾选<参数化构建>

(3)选择git parameter

(4)创建变量名 release(自定义)

 学习Jenkins(三) 随笔 第123张

修改源码管理

 学习Jenkins(三) 随笔 第124张

学习Jenkins(三) 随笔 第125张

(5)选择发布类型:
tag:按标签发布

学习Jenkins(三) 随笔 第126张

(6)对代码进行多次修改,并提交

然后再代码库中对提交进行tag标记

再在jenkins中查看,即可按照不同的版本进行构建,如图:

 学习Jenkins(三) 随笔 第127张

,
  • 一、Jenkins的远程管理

Jenkins的远程管理方式包含:

Shell ssh

SSH Plugin

ansible、saltstack

(1)Shell ssh
在项目构建时,jenkins使用了Execute Shell直接对远程主机操作,同步了代码到主机192.168.56.11上,并且可以增加对远程机器进行操作。例如执行某个脚本:ssh root@192.168.53.11 "/bin/sh /data/scripts/****.sh "
如图:

学习Jenkins(三) 随笔 第128张

(2)SSH plugin
除了以上方法之外,还可以使用SSH 的插件--SSH plugin
系统管理-->系统配置-->SSH remote hosts,配置好远程主机

学习Jenkins(三) 随笔 第129张

在项目中配置,如图:

学习Jenkins(三) 随笔 第130张

这样就完成了对远程主机的管理
此外,还可以使用自动化工具,如ansible,saltstack,模式一致,只是用的是ansible或者是saltstack的命令行工具的不同。

  •  二、Jenkins集群

当业务量变大时,单台的jenkins进行自动化构建部署,就显得没那么灵活,下面介绍jenkins的集群功能。
jenkins的集群并非像web服务器,mysql集群,jenkins的集群无需在额外的主机安装jenkins,但是用于java项目来说,要使用集群功能,额外的主机就必须要安装maven。

(1)在jenkins的web界面:系统管理-->Configure Global Security-->TCP port for JNLP agent配置端口30000

 学习Jenkins(三) 随笔 第131张

(2)系统管理-->管理节点-->新建节点

学习Jenkins(三) 随笔 第132张

(3)分配任务到节点
在项目中配置:
General-->Restrict where this project can be run-->Label Expression:node-01

 学习Jenkins(三) 随笔 第133张

学习Jenkins(三) 随笔 第134张

此时,在对项目进行构建,将会分配到node-01节点上进行构建,如图:

学习Jenkins(三) 随笔 第135张

,
  • 一、Jenkins按角色授权

当一个公司的开发分为多个组别,或者是多个项目等等。用于公司内部测试,让开发人员自行构建测试,此时不可能让所有的开发都在公用一个构建,这样变得很混乱,为了解决这一问题,jenkins也提供了角色授权的机制。每个开发有着对应的账号和权限,可以自行新建,构建,测试,发布等。角色授权需要安装的插件:Role-based Authorization Strategy

(1)系统配置
系统管理-->Configure Global Security-->访问控制-->授权策略-->Role-Base Strategy

学习Jenkins(三) 随笔 第136张

(2)新建用户
系统管理-->管理用户-->新建用户
这里创建一个java用户和php用户,用于区分php和java项目的构建

学习Jenkins(三) 随笔 第137张

(3)用户关联自己相关job,无法查看其他的job

建立项目角色,并对该用户进行项目的授权(包括Job的构建,取消,配置,创建,删除等等)
注意此处的添加,一个是Role是随意填写,最好规范点。Pattern是正则匹配,比如此处匹配的是所有包含Java开头的项目和php开头的项目

系统管理-->Manage and Assign Roles --> Manage Roles-->Project roles

 学习Jenkins(三) 随笔 第138张

配置好项目的权限,使用java用户或php用户登录是没有新建项目的权限,如需新增这样的权限,需要在Global roles中进行配置,新增一个角色(比如新增一个可以创建新项目的权限角色:new job,可登录查看的角色read):

 学习Jenkins(三) 随笔 第139张

 

 然后系统管理-->Manage and Assign Roles -->Assign Roles进行添加对应的权限

学习Jenkins(三) 随笔 第140张

使用php登录查看,可以看到php用户可以看到对应php开头的项目,但是没有新建项目的权限:

学习Jenkins(三) 随笔 第141张

  • 二、Jenkins的Pipeline(代码流水线管理)

Pipeline(代码流水线管理)

Pipeline名词顾名思义就是流水线的意思,因为公司可能会有很多项目。如果使用jenkins构建完成后,开发构建项目需要一项一项点击,比较麻烦。所以出现pipeline名词。

(1)下载pipeline。这样只需要构建一个项目,就会帮我们完成所有相关项目

搜索插件pipeline 

学习Jenkins(三) 随笔 第142张

等待安装完成 

 学习Jenkins(三) 随笔 第143张

(2)新建一个pipeline的项目

 学习Jenkins(三) 随笔 第144张

配置pipeline项目,使用Pipeline script脚本: 

node {
    stage 'build php-deploy'
    build 'php-deploy'
    stage 'build java'
    build 'java'
}

为了解决各个项目的依赖关系关系,使用pipeline的脚本进行控制。
第一步构建php项目,第二步构建java项目。Pipeline的脚本语法在Pipeline Syntax中有展示

学习Jenkins(三) 随笔 第145张

Pipeline Syntax的使用,如图:

 学习Jenkins(三) 随笔 第146张

立即构建p1的项目,如图:

 学习Jenkins(三) 随笔 第147张

代码流水线的功能就介绍到此!

,

思路图:

学习Jenkins(三) 随笔 第148张

  • 一、下载gitlab plugin

jenkins-->系统管理-->管理插件-->下载并安装gitlab plugin

  • 二、配置gitlab认证

路径:Jenkins-->Credentials-->System-->Global credentials(unrestricted)-->Add Credentials

1、Kind选择Gitlab API token

2、其中API token填写gitlab中有库权限的账号

3、ID填写用户账号

学习Jenkins(三) 随笔 第149张

gitlab生成Api token,将生成的token填入上面的证书内。

学习Jenkins(三) 随笔 第150张

学习Jenkins(三) 随笔 第151张

 

 

  • 三、选择连接

路径:系统管理-->系统设置

1、填写连接名

2、填写gitlab访问URL

3、选择gitlab认证

3、测试连接

学习Jenkins(三) 随笔 第152张

  • 四、配置任务在job配置中选择gitlab connection:gitlab

 学习Jenkins(三) 随笔 第153张

  • 五、任务配置

在job配置界面

1、勾选 Build when a change is pushed to GitLab. GitLab CI Service URL: http://192.168.56.12:8080/project/php-deploy

2、选择push events 时间触发构建

3、选择分支过滤(此处可以根据不同的需求来使用过滤功能)

4、secret token需要填入gitlab项目中的webhook

学习Jenkins(三) 随笔 第154张

在gitlab中找到项目-->setting-->Integrations配置

填写在上图生成的链接:

URL:http://192.168.56.12:8080/project/php-deploy

Secret Token:3f199086a22c54957579966e34ad120a

点击Add webhook

学习Jenkins(三) 随笔 第155张

测试是否生效:点击test-->选择push event会跳转到Hook excuted successfully:HTTP 200

 学习Jenkins(三) 随笔 第156张

学习Jenkins(三) 随笔 第157张

  • 六、构建发布PHP项目

在linux-node1上安装nginx,初始同步了线上代码,写入一个index.html。如图: 

[root@linux-node1 ~]# ll /data/www/php-deploy/
total 12
-rw-r--r-- 1 root root 28 Dec 23 15:45 index.html
-rw-r--r-- 1 root root 12 Dec 21 16:11 new.html
-rw-r--r-- 1 root root 19 Dec 21 16:11 readme
[root@linux-node1 ~]# cat /data/www/php-deploy/index.html 
<h1>welcome to beijing</h1>

学习Jenkins(三) 随笔 第158张

模拟程序员在linux-node2上进行修改代码,并提交到gitlab的master分支上

[root@linux-node2 app1]# pwd
/root/php/app1
[root@linux-node2 app1]# echo "Welcome to use Jenkins and Gitlab" > index.html 
[root@linux-node2 app1]# git status
# On branch 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@linux-node2 app1]# git add .
[root@linux-node2 app1]# git commit -m "jenkins + gitlab"
[master 7313bdd] jenkins + gitlab
 1 file changed, 1 insertion(+), 1 deletion(-)
[root@linux-node2 app1]# git push origin master
Counting objects: 5, done.
Compressing objects: 100% (2/2), done.
Writing objects: 100% (3/3), 334 bytes | 0 bytes/s, done.
Total 3 (delta 0), reused 0 (delta 0)
To git@192.168.56.11:java/app1.git
   dd37af6..7313bdd  master -> master

学习Jenkins(三) 随笔 第159张

学习Jenkins(三) 随笔 第160张

到此,自动触发和发布就完成了!这只是一个简单的构建发布,作为内部测试使用还是可以的!生产使用,有待优化!

,
  • 1、什么是Nexus?

在前面进行maven项目的构建中,可以看到在构建的过程中需要安装maven的依赖插件,如图:学习Jenkins(三) 随笔 第161张

而在maven的默认配置中是在官网的中央仓库和第三方的maven仓库进行下载,速度偏慢。这里提供阿里云的maven插件库(http://maven.aliyun.com/nexus/#view-repositories),可以在/data/apache-maven-3.5.2/conf/settings.xml 配置文件中进行修改。

 

在日常的开发构建中,我们也可以自己搭建一个私有的nexus。那么什么是nexus呢?

Nexus是maven的私有仓库;

如果没有nexus,项目的打包都需要在公网下载,不利于包的管理和共用;

如果没有私有仓库,我们所需要的所有构件都需要通过maven的中央仓库和第三方的maven仓库下载到本地,而一个团队的所有人都需要重复地从maven仓库中下载构件。

  • 2、Nexus的安装

1)下载Nexus
[root@linux-node2 ~]# wget https://sonatype-download.global.ssl.fastly.net/nexus/oss/nexus-2.14.5-02-bundle.tar.gz
--2017-12-25 10:45:42--  https://sonatype-download.global.ssl.fastly.net/nexus/oss/nexus-2.14.5-02-bundle.tar.gz
Resolving sonatype-download.global.ssl.fastly.net (sonatype-download.global.ssl.fastly.net)... 151.101.228.249
Connecting to sonatype-download.global.ssl.fastly.net (sonatype-download.global.ssl.fastly.net)|151.101.228.249|:443... connected.
HTTP request sent, awaiting response... 200 OK
Length: 73187012 (70M) [application/octet-stream]
Saving to: ‘nexus-2.14.5-02-bundle.tar.gz’
 5% [=======>                                                                                                                                            ] 4,375,805   76.4KB/s  eta 12m 59s
 
(2)解压Nexus
[root@linux-node2 ~]# tar -zxvf nexus-2.14.5-02-bundle.tar.gz
[root@linux-node2 ~]# mv nexus-2.14.5-02 sonatype-work /data/3)启动Nexus
[root@linux-node2 ~]# cd /data/nexus-2.14.5-02
[root@linux-node2 nexus-2.14.5-02]# ls
bin  conf  lib  LICENSE.txt  logs  nexus  NOTICE.txt  tmp
[root@linux-node2 nexus-2.14.5-02]# cd bin/
[root@linux-node2 bin]# ./nexus start
****************************************
WARNING - NOT RECOMMENDED TO RUN AS ROOT
****************************************
If you insist running as root, then set the environment variable RUN_AS_USER=root before running this script.
[root@linux-node2 bin]# export RUN_AS_USER=root
[root@linux-node2 bin]# ./nexus start
****************************************
WARNING - NOT RECOMMENDED TO RUN AS ROOT
****************************************
Starting Nexus OSS...
Started Nexus OSS.
[root@linux-node2 bin]# netstat -tulnp |grep 8081
tcp        0      0 0.0.0.0:8081            0.0.0.0:*               LISTEN      4773/java

(4)浏览器访问仓库
浏览器访问:http://192.168.56.12:8081/nexus,如图:

学习Jenkins(三) 随笔 第162张

点击右上角"login" 默认用户名密码:admin ,admin123

在仓库中,默认会在本地去查找插件,当未发现有插件时,会通过第三方仓库查到,这些仓库的类型都是hosts类型,也就是在本机进行查询。

当本地内未能查找到相应的插件,会通过代理(proxy)类型进行下载插件,配置就在Central——>Remote Storage    Location(回源地址),这里我们填写阿里云的maven远程仓库进行下载

http://maven.aliyun.com/nexus/content/groups/public/

学习Jenkins(三) 随笔 第163张

学习Jenkins(三) 随笔 第164张

配置完成nexus后,在修改maven的settings配置

[root@linux-node2 ~]# vim /data/apache-maven-3.5.2/conf/settings.xml 
将其中的仓库链接地址修改为:
http://192.168.56.12:8081/nexus/content/groups/public/

这样在构建时,首次会从阿里云的maven仓库中下载插件,后面再次重新下载插件时会从本地进行下载

,
  • 一、新建一台虚拟机安装tomcat

1)安装JDK
官网下载jdk:http://www.oracle.com/technetwork/java/javase/downloads/jdk8-downloads-2133151.html
下载jdk8,放到/usr/local/src/目录下
[root@linux-node3 ~]# tar -zxvf jdk-8u151-linux-x64.tar.gz
[root@linux-node3 ~]# mv jdk1.8.0_151 /usr/local/jdk1.8
[root@linux-node3 ~]# vim /etc/profile
增加如下内容:
JAVA_HOME=/usr/local/jdk1.8/
JAVA_BIN=/usr/local/jdk1.8/bin
JRE_HOME=/usr/local/jdk1.8/jre
PATH=$PATH:/usr/local/jdk1.8/bin:/usr/local/jdk1.8/jre/bin
CLASSPATH=/usr/local/jdk1.8/jre/lib:/usr/local/jdk1.8/lib:/usr/local/jdk1.8/jre/lib/charsets.jar
[root@linux-node3 ~]# source /etc/profile
[root@linux-node3 ~]# java -version
java version "1.8.0_151"
Java(TM) SE Runtime Environment (build 1.8.0_151-b12)
Java HotSpot(TM) 64-Bit Server VM (build 25.151-b12, mixed mode)
 
(2)安装tomcat
[root@linux-node3 ~]# wget http://apache.fayea.com/tomcat/tomcat-8/v8.5.20/bin/apache-tomcat-8.5.20.tar.gz
[root@linux-node3 ~]# tar -zxvf apache-tomcat-8.5.24.tar.gz 
[root@linux-node3 ~]# mv apache-tomcat-8.5.24 /usr/local/tomcat
[root@linux-node3 ~]# /usr/local/tomcat/bin/startup.sh 
[root@linux-node3 ~]# netstat -tulnp |grep 8080
tcp6       0      0 :::8080                 :::*                    LISTEN      3765/java 
 
提示:三个端口8080为提供web服务的端口,8005为管理端口,8009端口为第三方服务调用的端口,比如httpd和Tomcat结合时会用到
 
(3)配置tomcat
[root@linux-node3 ~]# vim /usr/local/tomcat/conf/tomcat-users.xml 
<tomcat-users>
<role rolename="admin"/>
<role rolename="admin-gui"/>
<role rolename="admin-script"/>
<role rolename="manager"/>
<role rolename="manager-gui"/>
<role rolename="manager-script"/>
<role rolename="manager-jmx"/>
<role rolename="manager-status"/>
<user name="admin" password="admin123456" roles="admin,manager,admin-gui,admin-script,manager-gui,manager-script,manager-jmx,manager-status" />
</tomcat-users>
[root@linux-node3 ~]# /usr/local/tomcat/bin/shutdown.sh 
[root@linux-node3 ~]# /usr/local/tomcat/bin/startup.sh 
 
在访问tomcat时,点击"manager webapp"会跳出一个验证弹框,输入用户名密码

学习Jenkins(三) 随笔 第165张

会跳转到以下界面,说明用户名密码无误,如图:

 学习Jenkins(三) 随笔 第166张

  • 二、下载zrlog的java代码push到gitlab上 

1)下载zrlog的代码
[root@linux-node2 home]# wget https://codeload.github.com/94fzb/zrlog/zip/master
--2017-12-25 11:02:45--  https://codeload.github.com/94fzb/zrlog/zip/master
Resolving codeload.github.com (codeload.github.com)... 192.30.255.121, 192.30.255.120
Connecting to codeload.github.com (codeload.github.com)|192.30.255.121|:443... connected.
HTTP request sent, awaiting response... 200 OK
Length: unspecified [application/zip]
Saving to: ‘master’
    [                                      <=>   ] 1,669,502    199KB/s   in 8.6s   
2017-12-25 11:02:56 (189 KB/s) - ‘master’ saved [1669502]
[root@linux-node2 home]# du -sh
1.7M.
[root@linux-node2 home]# du -sh master
1.6Mmaster
 
(2)解压
[root@linux-node2 home]# yum install -y unzip
[root@linux-node2 home]# unzip master
 
(3)初始化仓库,并将zrlog的代码push到gitlab
[root@linux-node2 home]# mkdir Java
[root@linux-node2 Java]# mv zrlog-master/* Java/
[root@linux-node2 Java]# git remote add orgin git@192.168.56.11:java/zrlog.git
[root@linux-node2 Java]# git add .
[root@linux-node2 Java]# git commit -m "add origin"
# On branch master
nothing to commit, working directory clean
[root@linux-node2 Java]# ll
total 48
drwxr-xr-x 2 root root 55 Dec 25 17:45 bin
-rw-r--r-- 1 root root 6114 Dec 25 17:45 CHANGELOG.md
drwxr-xr-x 2 root root 42 Dec 25 17:45 doc
-rw-r--r-- 1 root root 11358 Dec 25 17:45 LICENSE
-rwxr-xr-x 1 root root 6468 Dec 25 17:45 mvnw
-rw-r--r-- 1 root root 4994 Dec 25 17:45 mvnw.cmd
-rw-r--r-- 1 root root 7664 Dec 25 17:45 pom.xml
-rw-r--r-- 1 root root 3574 Dec 25 17:45 README.md
drwxr-xr-x 4 root root 28 Dec 25 17:45 src
[root@linux-node2 Java]# git push origin master
Counting objects: 457, done.
Compressing objects: 100% (426/426), done.
Writing objects: 100% (457/457), 2.98 MiB | 1.72 MiB/s, done.
Total 457 (delta 51), reused 0 (delta 0)
remote: Resolving deltas: 100% (51/51), done.
To git@192.168.56.11:java/zrlog.git
* [new branch] master -> master
  • 三、新建一个maven项目zr_blog

(1)新建项目

登录jenkins,点击“新建”,任务名称自定义(zr_blog)

选择“构建一个maven项目”

点击“确定”

(2)配置项目

源码管理

选择 “git”, Repository URL填写你的git地址,并配置对应的key,大家最好事前先在jenkins这台机器上能够直接远程git操作私有仓库

 构建触发器、构建环境、Pre Steps保持默认

 Build

“Root POM”为pom.xml, Goals and options 填写 clean install -D maven.test.skip=true

 Post Steps、构建设置保持默认

 构建后操作

 点击“增加构建后操作步骤”选择“Deploy war/ear to a container”,“WAR/EAR files”填写“**/*.war”,Contex path留空,Containers选择Tomcat 8.x,Tomcat URL填写要把war包发布到的那台机器的url,如http://192.168.56.13:8080

 Credentials这里需要点击右侧的Add,添加用户名和密码

 学习Jenkins(三) 随笔 第167张

点击"立即构建"查看控制台信息,如图:

 学习Jenkins(三) 随笔 第168张

(3)查看发布结果

查看linux-node3的webapps目录,会有相对应的war包,并已经进行解压,使用浏览器访问

[root@linux-node3 ~]# ll /usr/local/tomcat/webapps/
total 7160
drwxr-x--- 14 root root    4096 Dec 25 03:08 docs
drwxr-x---  6 root root    4096 Dec 25 03:08 examples
drwxr-x---  5 root root    4096 Dec 25 03:08 host-manager
drwxr-x---  6 root root    4096 Dec 25 04:05 manager
drwxr-x---  3 root root    4096 Dec 25 03:08 ROOT
drwxr-x---  9 root root    4096 Dec 25 04:04 zrlog-1.8.0
-rw-r-----  1 root root 7306944 Dec 25 04:04 zrlog-1.8.0.war

学习Jenkins(三) 随笔 第169张

 ###########################################################################

,

目录

一、环境说明和准备

1、环境说明

主机名 IP地址 角色 系统
deploy-server 192.168.56.12 发布 Centos 7.4
web 192.168.56.13 web服务器,nfs服务器 Centos 7.4

2、服务器准备工作

(1)发布机前期准备

a.增加普通用户并配置密码
[root@deploy-server ~]# useradd www
[root@deploy-server ~]# id www
uid=1000(www) gid=1000(www) groups=1000(www)
[root@deploy-server ~]# passwd www
[root@deploy-server ~]# yum install -y git tree
b.创建部署需要的目录并初始化git目录
[root@deploy-server ~]# mkdir -pv /deploy/{code/{www,jxs,wap,gys,glzx,yyzx},config,tar,tmp}
[root@deploy-server ~]# chown -R www.www /deploy
[www@deploy-server ~]$ tree /deploy
/deploy
├── code
│   ├── glzx
│   ├── gys
│   ├── jxs
│   ├── wap
│   ├── www
│   └── yyzx
├── config
├── tar
└── tmp
[www@deploy-server ~]$ cd /deploy/code/www && git init
c.创建配置文件config.php
[www@deploy-server ~]$ vim /deploy/config/config.php 
this is config.php
[www@deploy-server ~]$ tree /deploy
/deploy
├── code
│   ├── glzx
│   ├── gys
│   ├── jxs
│   ├── wap
│   ├── www
│   └── yyzx
├── config
│   └── config.php
├── tar
└── tmp
d.配置发布机和目标机的ssh通信
[www@deploy-server deploy]$ cat /home/www/.ssh/id_rsa.pub 
ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDzM3AW6/X+djvKJTsdFbY3ik+mlradxpD3COoTP5h6x509unksuCdduV7awPjEGHvK2GVjJmvckxdvLkMc23p7bsctHlturPN2VozJTrYwXMAbmxf97cKE/fpKhjPXG8HlWBLpEaTM8PITgvdcyaeAUaIN+/h5VrA8TZKFAgbxDLxtgwqPzYIG9nqCO7MMCgzhJxI6PDQ6KVU9rHal/p4XKTIy4Rq4FzZTav2tS4zNJ7kX9+e6EO0JTooPanJXBTltLOJJsKxnlA7tc20rq6+0XVqbUBKYahL/8ZzkxZozNrNq7wtIuuJo0WTDFzDdPcJyAGlRWLuwct7y4p4UApVz www@deploy-server

[www@deploy-server ~]$ ssh-copy-id www@192.168.56.13
/bin/ssh-copy-id: INFO: Source of key(s) to be installed: "/home/www/.ssh/id_rsa.pub"
The authenticity of host '192.168.56.13 (192.168.56.13)' can't be established.
ECDSA key fingerprint is SHA256:ahG6dBy/Z1nUIUWhQQrylsiwBlnDKC/jz8rnaPU2eF0.
ECDSA key fingerprint is MD5:6e:58:0b:02:1c:a4:41:51:e8:7d:33:4d:46:bb:a0:68.
Are you sure you want to continue connecting (yes/no)? yes
/bin/ssh-copy-id: INFO: attempting to log in with the new key(s), to filter out any that are already installed
/bin/ssh-copy-id: INFO: 1 key(s) remain to be installed -- if you are prompted now it is to install the new keys
www@192.168.56.13's password: 

Number of key(s) added: 1

Now try logging into the machine, with:   "ssh 'www@192.168.56.13'"
and check to make sure that only the key(s) you wanted were added.

[www@deploy-server ~]$ ssh 192.168.56.13
Last login: Fri Nov  2 18:01:02 2018
[www@web ~]$ 
e.将ssh公钥复制到github或gitlab

学习Jenkins(三) 随笔 第170张

(2)web服务器准备

a.部署NFS服务器
[root@web ~]# yum install -y nfs-utils rpcbind
[root@web ~]# vim /etc/exports
/nas/www 192.168.56.0/24(rw,sync,no_root_squash)
/nas/jxs 192.168.56.0/24(rw,sync,no_root_squash)
/nas/wap 192.168.56.0/24(rw,sync,no_root_squash)
/nas/glzx 192.168.56.0/24(rw,sync,no_root_squash)
/nas/yyzx 192.168.56.0/24(rw,sync,no_root_squash)
/nas/gys 192.168.56.0/24(rw,sync,no_root_squash)
[root@web ~]# systemctl start rpcbind
[root@web ~]# systemctl start nfs
[root@web ~]# showmount -e
Export list for web:
/nas/gys  192.168.56.0/24
/nas/yyzx 192.168.56.0/24
/nas/glzx 192.168.56.0/24
/nas/wap  192.168.56.0/24
/nas/jxs  192.168.56.0/24
/nas/www  192.168.56.0/24
b.挂载共享目录
[root@web ~]# mkdir /webroot/{www,jxs,wap,gys,glzx,yyzx}
[root@web ~]# chown -R www.www /webroot
[root@web ~]# mount -f nfs 192.168.56.13:/nas/www /webroot/www
[root@web ~]# df -h
Filesystem               Size  Used Avail Use% Mounted on
/dev/mapper/centos-root 18G 1.7G 16G 10% /
devtmpfs                 482M     0  482M   0% /dev
tmpfs                    493M     0  493M   0% /dev/shm
tmpfs                    493M  6.8M  486M   2% /run
tmpfs                    493M     0  493M   0% /sys/fs/cgroup
/dev/sda1                497M  171M  326M  35% /boot
tmpfs                     99M     0   99M   0% /run/user/0
192.168.56.13:/nas/www    18G  1.7G   16G  10% /webroot/www
c.部署nginx+php
[root@web ~]# useradd www
[root@web ~]# passwd www
[root@web ~]# yum install -y nginx php php-fpm
[root@web ~]# vim /etc/nginx/nginx.conf
user www;
worker_processes auto;
error_log /var/log/nginx/error.log;
pid /run/nginx.pid;

# Load dynamic modules. See /usr/share/nginx/README.dynamic.
include /usr/share/nginx/modules/*.conf;

events {
    worker_connections 1024;
}

http {
    log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
                      '$status $body_bytes_sent "$http_referer" '
                      '"$http_user_agent" "$http_x_forwarded_for"';

    access_log  /var/log/nginx/access.log  main;

    sendfile            on;
    tcp_nopush          on;
    tcp_nodelay         on;
    keepalive_timeout   65;
    types_hash_max_size 2048;

    include             /etc/nginx/mime.types;
    default_type        application/octet-stream;

    # Load modular configuration files from the /etc/nginx/conf.d directory.
    # See http://nginx.org/en/docs/ngx_core_module.html#include
    # for more information.
    include /etc/nginx/conf.d/*.conf;


}
[root@web ~]# mkdir /data/web -pv && chown -R www.www /data
[root@web ~]# vim /etc/nginx/nginx.conf
server {
        listen 80;
        server_name  localhost;

        root /data/web/www;
        index index.php index.htm index.html;
        client_max_body_size 20m;
        location / {
                proxy_read_timeout 150;
                try_files $uri $uri/ /index.php; } location ~* .*\.php$ { #try_files $uri =404; include fastcgi_params; fastcgi_pass 127.0.0.1:9000; fastcgi_split_path_info ^(.+\.php)(/.+)$;
                fastcgi_param PATH_INFO       $fastcgi_path_info;
                fastcgi_index index.php;
                fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
        }
}
[root@web ~]# nginx -t
nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
nginx: configuration file /etc/nginx/nginx.conf test is successful
[root@web ~]# systemctl start nginx
[root@web ~]# vim /etc/php-fpm.d/www.conf 
user www
group www
....
[root@web ~]# php-fpm -t
[03-Nov-2018 10:16:18] NOTICE: configuration file /etc/php-fpm.conf test is successful
[root@web ~]# systemctl start php-fpm
[root@web ~]# curl localhost -I
HTTP/1.1 200 OK
Server: nginx/1.12.2
Date: Sat, 03 Nov 2018 02:16:36 GMT
Content-Type: text/html
Content-Length: 35
Last-Modified: Sat, 03 Nov 2018 02:07:00 GMT
Connection: keep-alive
ETag: "5bdd02c4-23"
Accept-Ranges: bytes

二、发布脚本编写

1、自动化部署流程设计

  1. 发布机获取代码(直接拉取),从svn或git仓库进行拉取
  2. 发布机编译代码(可选,java语言需要编译,PHP无需编译)
  3. 将配置文件拷贝到代码文件(由于配置文件有数据库等机密信息,需要独立处理)
  4. 代码打包(将代码进行压缩打包)
  5. SCP到目标服务器目录
  6. 将目标服务器移除集群
  7. 在目标服务器上进行解压传过来的代码
  8. 解压后,对代码根目录进行软链接到刚才的目录文件,实现版本链接
  9. 重启(可选,tomcat需要重启)
  10. 测试
  11. 加入集群

2、自动化部署脚本编写

#!/bin/bash 
#deploy-server create dir as root
#[ -d /deploy ] && mkdir -pv /deploy/{code/web-demo,config,tar,tmp} && chown -R www.www /deploy

#node-server create dir as root
#[ -d /data ] && mkdir -pv /data/web && chown -R www.www /data
#nfs dir /nas/www mount to /webroot

#Node List
NODE="192.168.56.13"

#Shell ENV
SHELL_NAME="deploy.sh"
SHELL_DIR="/home/www"
SHELL_LOG="${SHELL_DIR}/${SHELL_NAME}.log"

#Code ENV
PRO_NAME="www"
CODE_DIR="/deploy/code/www"
CONFIG_DIR="/deploy/config"
TMP_DIR="/deploy/tmp"
TAR_DIR="deploy/tar"
LOCK_FILE="/tmp/deploy.lock"

#Date/Time ENV
LOG_DATE='date "+%Y-%m-%d"'
LOG_TIME='date "+%H-%M-%S"'

CDATE=$(date "+%Y-%m-%d")
CTIME=$(date "+%H-%M-%S")

useage(){
    echo $"Useage: $0 { deploy |rollback [ list | version ] }"
}

url_test(){
    URL=$1
    curl -s --head $URL |grep '200 OK'
    if [ $? -ne 0 ];then
        shell_unlock;
        writelog "test error" && exit;
    fi
}

writelog(){
    LOGINFO=$1
    echo "${CDATE} ${CTIME}: ${SHELL_NAME} : ${LOGINFO} " >> ${SHELL_LOG}
}

code_get(){
    writelog "code_get";
    cd ${CODE_DIR} && git pull git@github.com:kin08200/learngit.git
    cp -r ${CODE_DIR} ${TMP_DIR}
    API_VERL=$(git show |grep commit |cut -d ' ' -f2 )
        API_VER=$(echo ${API_VERL:0:6})
    echo $API_VER
}

code_config(){
    writelog "code_config"
    /bin/cp -r ${CONFIG_DIR}/* ${TMP_DIR}/${PRO_NAME}
        PKG_NAME=${PRO_NAME}_"${API_VER}"_"${CDATE}-${CTIME}"
        cd ${TMP_DIR} && mv ${PRO_NAME} ${PKG_NAME}
}

code_tar(){
    writelog "code_tar"
    cd ${TMP_DIR} && tar -czf ${PKG_NAME}.tar.gz ${PKG_NAME}
        writelog "${PKG_NAME}.tar.gz"
}

code_scp(){
    writelog "code_scp"
    scp ${TMP_DIR}/${PKG_NAME}.tar.gz $NODE:/webroot/www
}

code_deploy(){
    writelog "code_deploy"
    ssh $NODE "cd /webroot/www && tar -zxf ${PKG_NAME}.tar.gz"
    ssh $NODE "rm -rf /data/web/www && ln -s /webroot/www/${PKG_NAME} /data/web/www"
}

code_test(){
    url_test "http://192.168.56.13"
}

rollback_fun(){
    ssh $NODE "rm -rf /data/web/www && ln -s /webroot/www/$1 /data/web/www"   
}

rollback(){
    if [ -z $1 ];then
        shell_unlock;
        echo "Please input rollback version." && exit;
        fi
        case $1 in 
            list)
            ls -l /deploy/tmp/*.tar.gz
            ;;
            *)
            rollback_fun $1
            ;;
        esac
}


shell_lock(){
    touch ${LOCK_FILE}
}

shell_unlock(){
    rm -f ${LOCK_FILE}
}

main(){
    if [ -f ${LOCK_FILE} ];then
        echo "Deploy is running" && exit
    fi
    DEPLOY_METHOD=$1
    ROLLBACK_VER=$2
    case $DEPLOY_METHOD in
        deploy)
            shell_lock;
        code_get;
        code_config;
        code_tar;
            code_scp;
        code_deploy;
        code_test;
        shell_unlock;
        ;;
    rollback)
        shell_lock;
        rollback $ROLLBACK_VER;
        shell_unlock;
        ;;
    *)
        useage;
        ;;
    esac
}

main $1 $2

三、发布测试

1、开发机和github添加ssh信任

[www@localhost ~]$ cat .ssh/id_rsa.pub 
ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQC+ta7tkljnIgqvgEugQvIfVxH/a+geX250ZhOpe+14Q8EBQSI+qGyXCeihln+0aQpzIERvNBZ7JjWCg5XeQlgPBgCmqoQKNTWl/NUBT+uY/NY9fIGdRCVBvVcDC554Be48zB57mtapKQEkqm/8kmq7sPRQDv98l5wvFvYOPxocmjnioDZr3GeYmgdFPNJ5WGg6yY29IHXgh2v3eCXLwX2Z2eUdKCpV1LS42wdAN8TqHFCEmthREIq2r86ZKPOovD6Micq7wa2yJqtA/hkv+DvEhRzOIVznfW5EptOyKYcittGu63JGMSbCr1uCdW7PLUQ8aIWDDlip+/EcIt0KkuJJ www@localhost.localdomain

2、克隆项目到开发机进行开发测试

[www@localhost ~]$ mkdir dev && cd dev
[www@localhost dev]$ git clone git@github.com:kin08200/learngit.git
[www@localhost dev]$ ll
total 4
drwxrwxr-x 3 www www 4096 Nov  2 22:02 learngit
[www@localhost dev]$ cd learngit

3、修改index.html文件

[www@localhost learngit]$ ll
total 8
-rw-rw-r-- 1 www www  0 Nov  2 04:31 123
-rw-rw-r-- 1 www www 35 Nov  2 22:02 index.html
-rw-rw-r-- 1 www www 80 Nov  2 04:31 readme.txt
[www@localhost learngit]$ echo "<h1> welcome to Beijing </h1>" > index.html

4、提交代码

[www@localhost learngit]$ git add .
[www@localhost learngit]$ git commit -m "modify index.html"
[www@localhost learngit]$ git push origin master

5、发布代码

[www@deploy-server ~]$ ./deploy.sh deploy
remote: Enumerating objects: 5, done.
remote: Counting objects: 100% (5/5), done.
remote: Compressing objects: 100% (2/2), done.
remote: Total 3 (delta 0), reused 3 (delta 0), pack-reused 0
Unpacking objects: 100% (3/3), done.
From github.com:kin08200/learngit
 * branch            HEAD       -> FETCH_HEAD
Updating 9a781b2..683a440
Fast-forward
 index.html | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)
683a44
www_683a44_2018-11-03-10-06-56.tar.gz                                                                                                                      100%   22KB   9.3MB/s   00:00    
HTTP/1.1 200 OK

6、测试访问

[www@deploy-server ~]$ curl 192.168.56.13
<h1>
    welcome to Beijing!!!!
</h1>

7、回滚测试

[root@web ~]# ll /data/web/
total 0
lrwxrwxrwx 1 www www 43 Nov  3 10:46 www -> /webroot/www/www_683a44_2018-11-03-10-06-56

测试访问如下,下面进行查看版本列表,并选择回滚到www_9a781b_2018-11-03-09-59-44版本

学习Jenkins(三) 随笔 第171张

[www@deploy-server ~]$ ./deploy.sh rollback list
-rw-rw-r-- 1 www www 22686 Nov 3 10:07 /deploy/tmp/www_683a44_2018-11-03-10-06-56.tar.gz
-rw-rw-r-- 1 www www 22685 Nov 3 10:44 /deploy/tmp/www_683a44_2018-11-03-10-43-55.tar.gz
-rw-rw-r-- 1 www www 22222 Nov 3 09:48 /deploy/tmp/www_9a781b_2018-11-03-09-48-36.tar.gz
-rw-rw-r-- 1 www www 22231 Nov 3 09:52 /deploy/tmp/www_9a781b_2018-11-03-09-52-32.tar.gz
-rw-rw-r-- 1 www www 22228 Nov 3 09:58 /deploy/tmp/www_9a781b_2018-11-03-09-58-15.tar.gz
-rw-rw-r-- 1 www www 22234 Nov 3 09:59 /deploy/tmp/www_9a781b_2018-11-03-09-59-44.tar.gz

[www@deploy-server ~]$ ./deploy.sh rollback www_9a781b_2018-11-03-09-59-44
[root@web ~]# ll /data/web/
total 0
lrwxrwxrwx 1 www www 43 Nov  3 10:48 www -> /webroot/www/www_9a781b_2018-11-03-09-59-44

再进行访问测试:

学习Jenkins(三) 随笔 第172张

扫码关注我们
微信号:SRE实战
拒绝背锅 运筹帷幄