高级架构四 Jenkins持续集成

一 Jenkins介绍

1.1 软件开发周期

软件开发生命周期叫做ASLC(Software Development Life Sycle),集成了计划,开发,测试和部署过程集合。
在这里插入图片描述

1.1.1 需求分析

这是生命周期的第一阶段,根据项目需求,团队执行一个可行性计划的分析。项目需求可能是公司内部或者客户提出的。这阶段主要是对信息的收集,也有可能是对现有项目的改善和重新做一个新的项目。还要分析项目的预算多长,可以从哪方面受益及布局,这也是项目创建的目标。

1.1.2 设计

第二阶段就是设计阶段,系统架构和满意状态(就是要做成什么样子,有什么功能),和创建一个项目计划。计划可以使用图表,布局设计或者文档的方式呈现。

1.1.3 实现

第三阶段就是实现阶段

1.1.4 测试

测试人员进行代码测试 ,包括功能测试、代码测试、压力测试等。

1.1.5 进化

最后进阶段就是对产品不断的进化改进和维护阶段,根据用户使用情况,可能需要对某功能进行修改和bug修复

1.2 瀑布模型

瀑布模型是最著名和最常使用的软件开发模型。瀑布模型就是一系列的软件开发过程。它是由制造业繁衍出来的。一个高度化的结构流程在一个方向上流动,有点像生产线一样。在瀑布模型创建之初,没有其它开发的模型,有很多东西全靠开发人员去猜测,去开发。这样的模型仅适用于那些简单的软件开发, 但是已经不适合现在的开发了。
在这里插入图片描述

  • 缺点:各个阶段的划分完全固定,阶段之间产生大量的文档,极大地
    增加了工作量。
  • 由于开发模型是线性的,用户只有等到整个过程的末期才能见
    到开发成果,从而增加了开发风险。
  • 瀑布模型的突出缺点是不适应用户需求的变化。

1.3 敏捷开发

敏捷开发(Agile Development) 的核心是迭代开发(Iterative Development) 与 增量开发(Incremental Development) 。

1.3.1 何为迭代开发?

对于大型软件项目,传统的开发方式是采用一个大周期(比如一年)进行开发,整个过程就是一次"大开发";迭代开发的方式则不一样,它将开发过程拆分成多个小周期,即一次"大开发"变成多次"小开发",每次小开发都是同样的流程,所以看上去就好像重复在做同样的步骤。
举例来说,spacex公司想造一个大推力火箭,将人类送到火星。但是,它不是一开始就造大火箭,而是先造一个最简陋的小火箭 version1。结果,第一次发射就爆炸了,直到第四次发射,才成功进入轨道。然后,开发了中型火箭 version9,九年中发射了70次。最后,才开发重型火箭。如果spacex不采用迭代开发,它可能直到现在还无法上天。

1.3.2 何为增量开发?

软件的每个版本,都会新增一个用户可以感知的完整功能。也就是说,按照新增功能来划分迭代。
举例来说,房产公司开发一个10栋楼的小区。如果采用增量开发的模式,该公司第一个迭代就是交付一号楼,第二个迭代交付二号楼… 每个迭代都是完成一栋完整的楼。而不是第一个迭代挖好10栋楼的地基,第二个迭代建好每栋楼的骨架,第三个迭代架设屋顶…

敏捷开发如何迭代?
虽然敏捷开发将软件开发分成多个迭代,但是也要求,每次迭代都是一个完整的软件开发周期,必须按照软件工程的方法论,进行正规的流程管理。
在这里插入图片描述
敏捷开发有什么好处?

早期交付
敏捷开发的第一个好处,就是早期交付,从而大大降低成本。 还是以上一节的房产公司为例,如果按照传统的"瀑布开发模式",先挖10栋楼的地基、再盖骨架、然后架设屋顶,每个阶段都等到前一个阶段完成后开始,可能需要两年才能一次性交付10栋楼。也就是说,如果不考虑预售,该项目必须等到两年后才能回款。 敏捷开发是六个月后交付一号楼,后面每两个月交付一栋楼。因此,半年就能回款10%,后面每个月都会有现金流,资金压力就大大减轻了。

降低风险
敏捷开发的第二个好处是,及时了解市场需求,降低产品不适用的风险。 想一想,哪一种情况损失比较小:10栋楼都造好以后,才发现卖不出去,还是造好第一栋楼,就发现卖不出去,从而改进或停建后面9栋楼?

1.4 什么是持续集成

持续集成( Continuous integration , 简称 CI )指的是,频繁地(一天多次)将代码集成到主干。持续集成的目的,就是让产品可以快速迭代,同时还能保持高质量。它的核心措施是,代码集成到主干之前,必须通过自动化测试。只要有一个测试用例失败,就不能集成。通过持续集成, 团队可以快速的从一个功能到另一个功能,简而言之,敏捷软件开发很大一部分都要归功于持续集成。

持续集成的流程
根据持续集成的设计,代码从提交到生产,整个过程有以下几步。

  1. 提交
    流程的第一步,是开发者向代码仓库提交代码。所有后面的步骤都始于本地代码的一次提交(commit)。

  2. 测试(第一轮)
    代码仓库对commit操作配置了钩子(hook),只要提交代码或者合并进主干,就会跑自动化测试。
    测试的种类:
    单元测试:针对函数或模块的测试
    集成测试:针对整体产品的某个功能的测试,又称功能测试
    端对端测试:从用户界面直达数据库的全链路测试
    第一轮至少要跑单元测试。

  3. 构建
    通过第一轮测试,代码就可以合并进主干,就算可以交付了。
    交付后,就先进行构建(build),再进入第二轮测试。所谓构建,指的是将源码转换为可以运行的实际代码,比如code—>jar,或者是服务器环节的准备等等。
    常用的构建工具如下:
    Jenkins
    Travis
    Codeship
    Strider

  4. 测试(第二轮)
    第二轮是全面测试,单元测试和集成测试都会跑,也要做端对端测试。所有测试以自动化为主,少数无法自动化的测试用例,就要人工跑。
    需要强调的是,新版本的每一个更新点都必须测试到。如果测试的覆盖率不高,进入后面的部署阶段后,很可能会出现严重的问题。

  5. 部署
    过了第二轮测试,当前代码就是一个可以直接部署的版本(artifact)。将这个版本的所有文件打包(tar filename.tar * )存档,发到生产服务器。

  6. 回滚
    一旦当前版本发生问题,就要回滚到上一个版本的构建结果。最简单的做法就是修改一下符号链接,指向上一个版本的目录。

持续集成的组成要素

  1. 一个自动构建过程, 从检出代码、 编译构建、 运行测试、 结果记录、 测试统计等都是自动完成的, 无需人工干预。
  2. 一个代码存储库,即需要版本控制软件来保障代码的可维护性,同时作为构建过程的素材库,一般使用SVN或Git。
  3. 一个持续集成服务器, Jenkins 就是一个配置简单和使用方便的持续集成服务器。

在这里插入图片描述

持续集成的好处

  1. 降低风险,由于持续集成不断去构建,编译和测试,可以很早期发现问题,所以修复的代价就少;
  2. 对系统健康持续检查,减少发布风险带来的问题;
  3. 减少重复性工作;
  4. 持续部署,提供可部署单元包;
  5. 持续交付可供使用的版本;
  6. 增强团队信心;

1.5 Jenkins是什么

在这里插入图片描述

Jenkins 是一款流行的开源持续集成(Continuous Integration)工具,广泛用于项目开发,具有自动化构建、测试和部署等功能。官网: http://jenkins-ci.org/

Jenkins的特征:
开源的Java语言开发持续集成工具,支持持续集成,持续部署。
易于安装部署配置:可通过yum安装,或下载war包以及通过docker容器等快速实现安装部署,可方便web界面配置管理。

消息通知及测试报告:集成RSS/E-mail通过RSS发布构建结果或当构建完成时通过e-mail通知,生成JUnit/TestNG测试报告。

分布式构建:支持Jenkins能够让多台计算机一起构建/测试。

文件识别:Jenkins能够跟踪哪次构建生成哪些jar,哪次构建使用哪个版本的jar等。

丰富的插件支持:支持扩展插件,你可以开发适合自己团队使用的工具,如git,svn,maven,docker等。

二 Jenkins环境准备

2.1 Jenkins安装和持续集成环境配置

在这里插入图片描述

  1. 首先,开发人员每天进行代码提交,提交到Git仓库
  2. 然后,Jenkins作为持续集成工具,使用Git工具到Git仓库拉取代码到集成服务器,再配合JDK,Maven等软件完成代码编译,代码测试与审查,测试,打包等工作,在这个过程中每一步出错,都重新再执行一次整个流程。
  3. 最后,Jenkins把生成的jar或war包分发到测试服务器或者生产服务器,测试人员或用户就可以访问应用。

服务器列表
本博客虚拟机统一采用CentOS7
在这里插入图片描述
Gitlab安装步骤,参考:https://blog.csdn.net/qq_33417321/article/details/130365133

2.2 Jenkins服务器需要的环境

切换到192.168.0.109机器

  1. jdk:Jenkins使用java开发,首先必然需要安装jdk。
  2. tomcat:Jenkins是一个web应用程序,运行当然需要中间件;
    Jenkins的war包中包含了一个叫winstone的应用服务器,所以可以直接运行,但在生产环境建议安装tomcat等独立中间件。下载解压即可。
  3. maven:Jenkins使用maven构建,所以也需要安装maven。下载解压即可。

2.3 JDK环境

这里是将环境变量配置在etc/profile,即为所有用户配置JDK环境。
sudo vi /etc/profile

#set java env
export JAVA_HOME= /usr/local/tools/jdk1.8.0_181
export JRE_HOME=${JAVA_HOME}/jre 
export CLASSPATH=.:${JAVA_HOME}/lib:${JRE_HOME}/lib 
export PATH=${JAVA_HOME}/bin:$PATH

执行命令使之生效:source /etc/profile

javac测试好用即可
在这里插入图片描述

2.4 Maven环境

运行wget https://archive.apache.org/dist/maven/maven-3/3.6.1/binaries/apache-maven-3.6.1-bin.tar.gz,下载maven安装文件

运行tar zvxf apache-maven-3.6.1-bin.tar.gz,解压

编辑文件apache-maven-3.6.1/conf/settings.xml,可以指定本地仓库或者私服(默认)

开始配置环境变量,编辑文件/etc/profile

在最下面添加以下内容(MAVEN_HOME是刚才解压maven的路径)

export MAVEN_HOME=/usr/local/tools/apache-maven-3.6.1

export PATH=$MAVEN_HOME/bin:$PATH

source /etc/profile
在这里插入图片描述

2.5 Git环境

2.5.1 yum方式安装

1、在Linux上是有yum安装Git,非常简单,只需要一行命令

yum -y install git

输入 git --version查看Git是否安装完成以及查看其版本号

在这里插入图片描述
顺便说一下,yum安装git被安装在/usr/libexec/git-core目录下
至此,yum安装git完成。
注意:yum安装的版本不能控制。默认的1.8.3,我们想自己指定版本就要通过源码下载安装。

2.5.2 自定义版本安装

1、 进入git在GitHub上发布版本页面https://github.com/git/git/tags,这个页面我们可以找到所有git已发布的版本。这里我们选择最新版的tar.gz包。
下载的源码是2.22:https://github.com/git/git/archive/v2.22.2.tar.gz

tar -zxvf git-2.22.0.tar.gz

进入到解压后的文件夹

cd git-2.22.0

拿到解压后的源码以后我们需要编译源码了,不过在此之前需要安装编译所需要的依赖

yum install curl-devel expat-devel gettext-devel openssl-devel zlib-devel gcc perl-ExtUtils-MakeMaker

耐心等待安装完成,中途出现提示的时候输入y并按回车。

提示,安装编译源码所需依赖的时候,yum自动帮你安装了git,这时候你需要先卸载这个旧版的git。

yum -y remove git

编译git源码

make prefix=/usr/local/git all

安装git至/usr/local/git路径

make prefix=/usr/local/git install

配置环境变量

vi /etc/profile 

在底部加上

export PATH=$PATH:/usr/local/git/bin

( 输入 :wq! 保存修改)

刷新环境变量

source /etc/profile

11、查看Git是否安装完成

git --version

至此,从github上下载最新的源码编译后安装git完成。

三 Jenkins安装

下载地址:https://jenkins.io/download/

各个版本Jenkins下载
http://updates.jenkins-ci.org/download/war/,浏览器下载慢,可以借助迅雷等下载。

3.1 jenkins访问

如果使用tomcat,那么在jenkins下载完后将war包直接复制到tomcat的webapps目录下,然后启动tomcat
在这里插入图片描述
启动完成后直接访问链接:http://192.168.0.108:8080/jenkins/

3.2 jenkins初始化配置

初次访问http://192.168.0.108:8080/jenkins/,出现如下界面。密码在启动控制台打印出来,如果没找到,那到图中提示的文件查看即可。
在这里插入图片描述
点击继续
在这里插入图片描述
注意注意注意!!!!选择第二个自定义安装,然后选择无。
在这里插入图片描述
在这里插入图片描述
创建用户并且实例配置
在这里插入图片描述
在这里插入图片描述

四 Jenkins配置

镜像配置

重点来啦:我们要修改Jenkins插件下载地址,否则Jenkins会让你怀疑人生。

以下的配置Json其实在Jenkins的工作目录中

$ cd {你的Jenkins工作目录}/updates  #进入更新配置位置

tomcat安装的在/root/.jenkins里面updates

$ vim default.json   #这个Json文件与上边的配置文件是相同的

使用vim的命令,如下,替换所有插件下载的url

:1,$s/http:\/\/updates.jenkins-ci.org\/download/https:\/\/mirrors.tuna.tsinghua.edu.cn\/jenkins/g

替换连接测试url

:1,$s/http:\/\/www.google.com/https:\/\/www.baidu.com/g

进入vim先输入:然后再粘贴上边的:后边的命令,注意不要写两个冒号!
修改完成保存退出:wq
在这里插入图片描述
修改URL为:https://mirrors.tuna.tsinghua.edu.cn/jenkins/updates/update-center.json
在这里插入图片描述
提交
重启http://192.168.0.109:8080/jenkins/restart

测试镜像
下载中文汉化插件

Jenkins->Manage Jenkins->Manage Plugins,点击Available,搜索"Chinese"
在这里插入图片描述
安装。重启Jenkins后,就看到Jenkins汉化了!不同版本可能部分菜单汉化会失败。
在这里插入图片描述

五 Jenkins用户权限管理

5.1 插件安装和配置

我们可以利用Role-based Authorization Strategy 插件来管理Jenkins用户权限
在这里插入图片描述
开启权限全局安全配置
在这里插入图片描述
授权策略切换为"Role-Based Strategy",保存
在这里插入图片描述

5.2 创建角色

在系统管理页面进入
在这里插入图片描述
点击"Manage Roles"
在这里插入图片描述
Global roles(全局角色):管理员等高级用户可以创建基于全局的角色
item roles(项目角色):针对某个或者某些项目的角色
node roles(奴隶角色):节点相关的权限

我们添加以下三个角色:
tx_root:该角色为全局角色。这个角色需要绑定全部下面的Read权限,是为了给所有用户绑定最基本的Jenkins访问权限。注意:如果不给后续用户绑定这个角色,会报错误:用户名 ismissing the Overall/Read permission
架构师:该角色为项目角色。使用正则表达式绑定"tx.",意思是只能操作tx开头的项目。
测试组长:该角色也为项目角色。绑定"test.
",意思是只能操作test开头的项目。

在这里插入图片描述
保存

5.3 创建用户

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
给用户分配角色

系统管理页面进入Manage and Assign Roles,点击Assign Roles
绑定规则如下:
张三用户分别绑定tx_root和架构师角色
李四用户分别绑定tx_root和测试组长角色
在这里插入图片描述

5.4 角色分配

在这里插入图片描述
创建项目测试权限

以root管理员账户创建两个项目,分别为tx_project01和test_project01

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
结果为:
zhangsan用户登录,只能看到tx_project01项目
lisi用户登录,只能看到test_project01项目

六 Jenkins凭证管理

凭据可以用来存储需要密文保护的数据库密码、Gitlab密码信息、Docker私有仓库密码等,以便Jenkins可以和这些第三方的应用进行交互。
安装Credentials Binding插件
要在Jenkins使用凭证管理功能,需要安装Credentials Binding插件
在这里插入图片描述
安装插件后,左边多了"凭证"菜单,在这里管理所有凭证.
在这里插入图片描述
可以添加的凭证有5种:
在这里插入图片描述

  • Username with password:用户名和密码
  • SSH Username with private key: 使用SSH用户和密钥
  • Secret file:需要保密的文本文件,使用时Jenkins会将文件复制到一个临时目录中,再将文件路径设置到一个变量中,等构建结束后,所复制的Secret file就会被删除。
  • Secret text:需要保存的一个加密的文本串,如钉钉机器人或Github的api token
  • Certificate:通过上传证书文件的方式

常用的凭证类型有:Username with password(用户密码)和SSH Username with private key(SSH密钥)

接下来以使用Git工具到Gitlab拉取项目源码为例,演示Jenkins的如何管理Gitlab的凭证。
安装Git插件和Git工具为了让Jenkins支持从Gitlab拉取源码,需要安装Git插件以及在CentOS7上安装Git工具。

6.1 Git插件安装

在这里插入图片描述

6.2 用户密码凭证

创建凭证
Jenkins->凭证->系统->全局凭证->添加凭证
在这里插入图片描述
在这里插入图片描述
找到"源码管理"->“Git”,在Repository URL复制Gitlab中的项目URL
在这里插入图片描述
配置我们之前的tx_project01工程执行Gitlab的工程链接,同时选择用户密码的凭证。
在这里插入图片描述
这时会报错说无法连接仓库!在Credentials选择刚刚添加的凭证就不报错啦

保存配置后,点击构建”立即构建“ 开始构建项目,通过控制台查看可以看到代码已经拉取。
在这里插入图片描述
我们看到代码已经拉取下来/root/.jenkins/workspace/
在这里插入图片描述

6.3 ssh秘钥凭证

使用root用户生成公钥和私钥
ssh-keygen -t rsa
在/root/.ssh/目录保存了公钥和使用
在这里插入图片描述
在这里插入图片描述
id_rsa:私钥文件
id_rsa.pub:公钥文件

把生成的公钥放在Gitlab中
以root账户登录->点击头像->Settings->SSH Keys
在这里插入图片描述
复制刚才id_rsa.pub文件的内容到这里,点击"Add Key"

在Jenkins中添加凭证,配置私钥
在Jenkins添加一个新的凭证,类型为"SSH Username with private key",把刚才生成私有文件内容复制过来
在这里插入图片描述
测试凭证是否可用
新建"tx_project01_ssh"项目->源码管理->Git,这次要使用Gitlab的SSH连接,并且选择SSH凭证
到Gitlab上拷贝ssh凭证
在这里插入图片描述
在这里插入图片描述
同样尝试构建项目,如果代码可以正常拉取,代表凭证配置成功!
在这里插入图片描述
在这里插入图片描述

七 Maven安装和配置

下载解压,这些都省略
修改Maven的settings.xml

# 创建本地仓库目录
mkdir /root/repo 
vi /opt/maven/conf/settings.xml

本地仓库改为:/root/repo/
在这里插入图片描述
添加阿里云私服地址:

<mirror>
    <id>nexus-aliyun</id>
    <mirrorOf>central</mirrorOf>
    <name>Nexus aliyun</name>
    <url>http://maven.aliyun.com/nexus/content/groups/public</url>
</mirror>

在这里插入图片描述
测试Maven是否配置成功,使用之前的gitlab密码测试项目,修改配置
在这里插入图片描述
输入mvn clean package
在这里插入图片描述
构建完成
在这里插入图片描述
可以看到war包
在这里插入图片描述
在Jenkins中配置全局环境变量
在这里插入图片描述
在这里插入图片描述

八 Tomcat安装和配置

切换到192.168.0.110机器
准备好jdk,Tomcat

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
配置Tomcat用户角色权限,默认情况下Tomcat是没有配置用户角色权限的
在这里插入图片描述
在这里插入图片描述
后续Jenkins部署项目到Tomcat服务器,需要用到Tomcat的用户,所以修改tomcat以下配置,添加用户及权限

vi conf/tomcat-users.xml
注意:配置文件不要折行。

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

用户和密码都是:tomcat
注意:为了能够刚才配置的用户登录到Tomcat,还需要修改以下配置

vi /webapps/manager/META-INF/context.xml
<!--
 <Valve  className="org.apache.catalina.valves.RemoteAddrValve"
            allow="127\.\d+\.\d+\.\d+|::1|0:0:0:0:0:0:0:1"  />
 -->

把上面这行注释掉即可! 重启Tomcat,访问测试
在这里插入图片描述

九 Jenkins构建项目部署服务

Jenkins中自动构建项目的类型有很多,常用的有以下三种:

  1. 自由风格软件项目(FreeStyle Project)
  2. Maven项目(Maven Project)
  3. 流水线项目(Pipeline Project)

每种类型的构建其实都可以完成一样的构建过程与结果,只是在操作方式、灵活度等方面有所区别,在实际开发中可以根据自己的需求和习惯来选择。

9.1 自由风格项目构建

下面演示创建一个自由风格项目来完成项目的集成过程:
拉取代码->编译->打包->部署

  1. 创建项目
    在这里插入图片描述
  2. 配置源码管理,从gitlab拉取代码
    在这里插入图片描述
  3. 编译打包
echo "开始编译和打包"
mvn clean package
echo "编译和打包结束"
  1. 把项目部署到远程的Tomcat里面
    Jenkins本身无法实现远程部署到Tomcat的功能,需要安装Deploy to container插件实现
    (1)插件安装
    在这里插入图片描述
    (2) 添加Tomcat凭证
    在这里插入图片描述
    (3)添加构建后步骤
    在这里插入图片描述
    填入如下的对应内容
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述

9.2 Maven项目构建

(1) 安装Maven Integration插件
在这里插入图片描述
(2) 创建Maven项目
在这里插入图片描述
配置同上,不过这里要输入pom.xml和Maven要执行的命令
在这里插入图片描述
然后配置好部署(同上)成功
在这里插入图片描述
在这里插入图片描述

十 Jenkins常用的构建触发器

Jenkins内置4种构建触发器:

  • 触发远程构建
  • 其他工程构建后触发(Build after other projects are build)
  • 定时构建(Build periodically)
  • 轮询SCM(Poll SCM)

在这里插入图片描述

10.1 触发远程构建

身份令牌最好是加密为好。
在这里插入图片描述
http://192.168.0.109:8080/jenkins/job/tx_project_pipeline/build?taken=6666
访问时候我们发现Jenkins要求使用post方式,点击Proceed即可
在这里插入图片描述
构建结构发生
在这里插入图片描述

10.2 其他工程构建后触发

创建前置工程并且配置
在这里插入图片描述
配置前置工程,保存。
在这里插入图片描述
我们构建pre_project完毕时候会触发tx_project_pipeline工程的构建。

10.3 定时构建

定时字符串从左往右分别为: 分 时 日 月 周
一些定时表达式的例子:

1.	每30分钟构建一次:H代表每隔(以当前时间为基准,如果H换成0就表示从整点开始) H/30 * * * *   10:02 10:32
2.	每2个小时构建一次: H H/2 * * *
3.	每天的8点,12点,22点,一天构建3次: (多个时间点中间用逗号隔开) 
    0 8,12,22 * * *
4.	每天中午12点定时构建一次 H 12 * * *
5.	每天下午18点定时构建一次 H 18 * * *
6.	在每个小时的前半个小时内的每10分钟 H(0-29)/10 * * * *
7.	每两小时一次,每个工作日上午9点到下午5点(也许是上午10:38,下午12:38,下午2:38,下午4:38) H H(9-16)/2 * * 1-5

我们对我们的工程设置为定时构建 H/2 * * * *
在这里插入图片描述
保存后,我们等2分钟即可看到结果

10.4 Git hook自动触发构建

利用Gitlab的webhook实现代码push到仓库,立即触发项目自动构建。

10.4.1 安装插件

安装Gitlab Hook插件,需要安装两个插件:Gitlab Hook和GitLab
在这里插入图片描述

10.4.2 Jenkins设置自动构建

Jenkins设置自动构建
在这里插入图片描述
等会需要把生成的webhook URL配置到Gitlab中。

10.4.3 Gitlab配置webhook

  1. 开启webhook功能
    使用root账户登录到后台,点击Admin Area -> Settings
    勾选"Allow requests to the local network from web hooks and services
    在这里插入图片描述

  2. 在项目添加webhook
    点击项目->Settings->Integrations
    在这里插入图片描述
    在这里插入图片描述
    我们可以进行测试,我们发现会有错误。
    在这里插入图片描述
    注意:以下设置必须完成,否则会报错!
    Jenkins->系统配置
    去掉这个钩
    在这里插入图片描述
    回到Gitlab重新测试即可。
    在这里插入图片描述
    测试webhook,回到工程中添加一行代码,提交并且推送。
    在这里插入图片描述
    我们发现构建已经发生。
    在这里插入图片描述
    Tomcat也自动生效。
    在这里插入图片描述

10.4.4 参数化构建

有时在项目构建的过程中,我们需要根据用户的输入动态传入一些参数,从而影响整个构建结果,这时们可以使用参数化构建。
Jenkins支持非常丰富的参数类型

  1. 设置参数化构建
    在这里插入图片描述
    选择字符参数,设置分支名字,我们来设置动态分支构建
    在这里插入图片描述
    我们可以在这里指的要构建的参数值。
    在这里插入图片描述
  2. 修改Jenkinsfile脚本
    通过设置读取变量的方式来动态获得分支名字
    在这里插入图片描述
    然后把把文件推送到Gitlab
  3. 创建新的分支feature
    在这里插入图片描述
    并且自动切换到feature分支
    在这里插入图片描述
    修改代码并且提交到feature分支。
    在这里插入图片描述
    feature分支产生。
    在这里插入图片描述
  4. 参数化构建动态分支
    输入feature开始构建
    在这里插入图片描述
    在这里插入图片描述
    可以看到成功的结果。

十一 Jenkins+Docker+SpringCloud微服务持续集成

11.1 Jenkins+Docker+SpringCloud持续集成流程说明

在这里插入图片描述
大致流程说明:

  1. 开发人员每天把代码提交到Gitlab代码仓库
  2. Jenkins从Gitlab中拉取项目源码,编译并打成jar包,然后构建成Docker镜像,将镜像上传到Harbor私有仓库。
  3. Jenkins发送SSH远程命令,让生产部署服务器到Harbor私有仓库拉取镜像到本地,然后创建容器。
  4. 所需服务器列表
服务器名称Ip地址安装软件
代码托管服务器192.168.0.108Gitlab
持续集成服务器192.168.0.109Jdk,Maven,Tomcat,Jenkins,docker
Docker仓库服务器192.168.0.111Docker,harbor
生产部署服务器192.168.0.110Docker,Tomcat

11.2 准备微服务代码

  1. Springcloud微服务Demo
    在这里插入图片描述
    springcloud-tx:父工程,存放基础配置
    txservicecloud-common:通用工程,存放工具类和公共代码
    txservicecloud-eureka_10001:端口是10001的SpringCloud的Eureka注册中心
    txservicecloud-provider-dep-8001:端口是8001的服务提供者
    txservicecloud-consumer-dep-80:端口是80的服务消费者

每个服务逐一测试,保证成功。
SpringBoot微服务项目打包必须导入该插件

<build>
    <plugins>
        <plugin>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-maven-plugin</artifactId>
            <executions>
                <execution>
                    <goals>
                        <goal>repackage</goal>
                    </goals>
                </execution>
            </executions>
        </plugin>
    </plugins>
</build>

打包后在target下产生jar包

  1. 本地运行微服务的jar包
java -jar xxx.jar
  1. 查看效果

11.3 Docker环境安装

主机:192.168.0.109
卸载旧版docker软件
名称一般为docker,docker-io或者docker-engine
卸载完成还需要查看并清理旧的docker数据目录,包含镜像,容器,网络等配置

sudo yum remove docker docker-engine docker-common \
    docker-client docker-client-latest docker-latest docker-latest-logrotate \
    docker-logrotate docker-selinux docker-engine-selinux
rpm -qa |grep docker*
ll /var/lib/docker/
rm -rf /var/lib/docker 删除docker的所有镜像和容

配置docker的yum仓库

yum install yum-utils lvm2 device-mapper-persistent-data -y

配置stable库

yum-config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo

禁用edge和test库

yum-config-manager --disable docker-ce-edge docker-ce-test

1)yum-utils提供yum-config-manager和utility工具
2)lvm2和device-mapper-persistent-data提供devicemapper的存储驱动
3)即使不使用edge库或test库也必须安装
4)建议上午安装,如果下载超时可以手动下载然后上传到/etc/yum.repos.d/目录
5)Note: Starting with Docker 17.06, stable releases are also pushed to the edge and test repositories.
6)如果启用edge和test库,yum安装时会安装最新版的docker,一般为test测试版,如果要安装最新的稳定版需要禁用该选项

查看可安装的docker-ce列表

yum list docker-ce --showduplicates

安装最新版docker-ce

yum install docker-ce

要安装指定版本docker,可以从上面的列表选择对应的版本号

yum install docker-ce-<VERSION STRING>
yum install docker-ce-18.06.1.ce-3.el7

升级docker-ce

yum -y upgrade <包名>

启动docker配置开机自启动

systemctl start docker
systemctl enable docker
ps -ef |grep docker 

阿里云镜像加速:
1.登录:https://dev.aliyun.com/search.html
2.登录阿里云
在这里插入图片描述
编辑配置文件
vi /etc/docker/daemon.json
拷贝下面的内容/etc/docker/daemon.json中

{ "registry-mirrors": ["https://tj3411jq.mirror.aliyuncs.com"] }

在这里插入图片描述
执行下面两条命令
sudo systemctl daemon-reload
sudo systemctl restart docker

在192.168.0.110机器执行
docker run -itd -p 3306:3306 -e MYSQL_ROOT_PASSWORD=root docker.io/mysql:5.7

1.数据库脚本

DROP DATABASE IF EXISTS cloudDB;
CREATE DATABASE cloudDB CHARACTER SET UTF8;
USE cloudDB;
CREATE TABLE dept
(
    deptno BIGINT NOT NULL PRIMARY KEY AUTO_INCREMENT,
    dname VARCHAR(60),
    db_source VARCHAR(60)
);
INSERT INTO dept(dname,db_source) VALUES('开发部',DATABASE());
INSERT INTO dept(dname,db_source) VALUES('人事部',DATABASE());
INSERT INTO dept(dname,db_source) VALUES('财务部',DATABASE());
INSERT INTO dept(dname,db_source) VALUES('市场部',DATABASE());
INSERT INTO dept(dname,db_source) VALUES('运维部',DATABASE());
SELECT * FROM dept;

在这里插入图片描述

11.4 dockerfile制作镜像

使用Dockerfile制作微服务镜像

我们利用Dockerfile制作一个Eureka注册中心的镜像
1)上传Eureka的微服务jar包到linux
2)编写dockerfile01

FROM  openjdk:8-jdk-alpine
ARG  JAR_FILE
COPY  ${JAR_FILE}  app.jar
EXPOSE  10001
ENTRYPOINT  ["java","-jar","/app.jar"]

3)构建镜像

docker build -f dockerfile01 --build-arg JAR_FILE=txservicecloud-eureka-10001-1.0-SNAPSHOT.jar -t eureka:v1 .

在这里插入图片描述
4)查看镜像是否创建成功
docker images
在这里插入图片描述
5)创建容器

docker run -i --name=eureka -p 10001: 10001 eureka:v1

在这里插入图片描述
6)访问容器
在这里插入图片描述

11.5 Harbor镜像仓库安装及使用

Harbor简介
在这里插入图片描述
Harbor(港口,港湾)是一个用于存储和分发Docker镜像的企业级Registry服务器。
除了Harbor这个私有镜像仓库之外,还有Docker官方提供的Registry。相对Registry,Harbor具有很多优势:

  1. 提供分层传输机制,优化网络传输 Docker镜像是是分层的,而如果每次传输都使用全量文件(所以用FTP的方式并不适合),显然不经济。必须提供识别分层传输的机制,以层的UUID为标识,确定传输的对象。
  2. 提供WEB界面,优化用户体验 只用镜像的名字来进行上传下载显然很不方便,需要有一个用户界面可以支持登陆、搜索功能,包括区分公有、私有镜像。
  3. 支持水平扩展集群 当有用户对镜像的上传下载操作集中在某服务器,需要对相应的访问压力作分解。
  4. 良好的安全机制 企业中的开发团队有很多不同的职位,对于不同的职位人员,分配不同的权限,具有更好的安全性。

11.5.1 Harbor安装

Harbor需要安装在192.168.0.111上面, 同时安装docker
1)先安装Docker并启动Docker(已完成)
参考之前的安装过程
2)安装docker-compose

sudo curl -L https://github.com/docker/compose/releases/download/1.21.2/docker-compose-`uname -s`-`uname -m` > /usr/local/bin/docker-compose

3)给docker-compose添加执行权限

sudo  chmod +x /usr/local/bin/docker-compose

4)查看docker-compose是否安装成功

docker-compose -version

5)下载Harbor的压缩包(本课程版本为:v1.9.2)

https://github.com/goharbor/harbor/releases

6)上传压缩包到linux,并解压

tar -xzf harbor-offline-installer-v1.9.2.tgz 
mkdir /opt/harbor
mv harbor/* /opt/harbor
cd /opt/harbor

7)修改Harbor的配置

vi harbor.yml

修改hostname和port

hostname: 192.168.0.111
port: 85

8)安装Harbor

./prepare
./install.sh

9)启动Harbor

docker-compose up -d 启动
docker-compose stop 停止
docker-compose restart 重新启动

10)访问Harbor
http://192.168…111:85
默认账户密码:admin/Harbor12345
在这里插入图片描述
在Harbor创建用户和项目

1)创建项目
Harbor的项目分为公开和私有的:
公开项目:所有用户都可以访问,通常存放公共的镜像,默认有一个library公开项目。
私有项目:只有授权用户才可以访问,通常存放项目本身的镜像。
我们可以为微服务项目创建一个新的项目:

在这里插入图片描述
2)创建用户
在这里插入图片描述
用户密码:txjava Txjava123
3)给私有项目分配用户
进入springcloud-tx项目->成员
在这里插入图片描述

角色权限说明
访客对于指定项目拥有只读权限
开发人员对于指定项目拥有读写权限
维护人员对于指定项目拥有读写权限,创建 Webhooks
项目管理员除了读写权限,同时拥有用户管理/镜像扫描等管理权限

4)以新用户登录Harbor设置注册中心

把Harbor地址加入到Docker作为私服中心,修改

vi /etc/docker/daemon.json
{ 
  "registry-mirrors": ["https://tj3411jq.mirror.aliyuncs.com"] 
  ,"insecure-registries":  ["192.168.0.111:85"]
}

重启docker
systemctl restart docker

5)登录Harbor

docker login -u 用户名 -p 密码 192.168.0.111:85

docker login -u txjava -p Txjava123 192.168.0.111:85
在这里插入图片描述
6)把镜像上传到Harbor
打标签指定注册中心

docker tag eureka:v1 192.168.0.111:85/springcloud-tx/eureka:v1
上传镜像

docker push 192.168.0.111:85/springcloud-tx/eureka:v1

在这里插入图片描述
在这里插入图片描述

11.5.2 应用服务器拉取镜像

服务器环境192.168.0.110
从Harbor下载镜像

需求:在192.168.0.110服务器完成从Harbor下载镜像
1)安装Docker,并启动Docker(已经完成)
2)修改Docker配置
把Harbor地址加入到Docker作为私服中心,修改vi /etc/docker/daemon.json

{ 
  "registry-mirrors": ["https://tj3411jq.mirror.aliyuncs.com"] 
  ,"insecure-registries":  ["192.168.0.111:85"]
}

重启docker

systemctl restart docker

登录

docker login -u txjava -p Txjava123 192.168.0.111:85

拉取

docker pull 192.168.0.111:85/springcloud-tx/eureka:v1

容器运行

docker run -i --name=eureka -p 10001:10001 192.168.0.111:85/springcloud-tx/eureka:v1

在这里插入图片描述
在这里插入图片描述

11.6 持续构建

11.6.1 上传代码到Gitlab

Gitlab创建工程,上传代码。
在这里插入图片描述

11.6.2 Gitlab拉取项目源码

在这里插入图片描述
在这里插入图片描述

//注意:变量引用使用双引号
def git_auth = "108bc789-e1ee-4c1d-ac5a-54d5049b1cf7"
def project_url = "git@192.168.0.108:root/springcloud-tx.git"
node {
   stage('拉取') {
     checkout([$class: 'GitSCM', branches: [[name: '*/${branch}']], doGenerateSubmoduleConfigurations: false, extensions: [], submoduleCfg: [], userRemoteConfigs: [[credentialsId: "${git_auth}", url: "${project_url}"]]])
   }
}

在这里插入图片描述

11.6.3 使用Dockerfile编译、生成镜像

我们可以先测试构建

//注意:变量引用使用双引号
def git_auth = "108bc789-e1ee-4c1d-ac5a-54d5049b1cf7"
def project_url = "git@192.168.0.108:root/springcloud-tx.git"
node {
   stage('拉取') {
     checkout([$class: 'GitSCM', branches: [[name: '*/${branch}']], doGenerateSubmoduleConfigurations: false, extensions: [], submoduleCfg: [], userRemoteConfigs: [[credentialsId: "${git_auth}", url: "${project_url}"]]])
   }

   stage('构建') {
      sh  "mvn  -f  txservicecloud-common  clean  install"
      sh  "mvn  -f  ${project_name}  clean  package"
   }
}

测试构建保证成功
在这里插入图片描述

11.6.4 上传到Harbor镜像仓库

在每一个项目根目录下创建Dockerfile,注意修改对应工程的端口

#FROM  java:8
FROM  openjdk:8-jdk-alpine
ARG  JAR_FILE
COPY  ${JAR_FILE}  app.jar
EXPOSE  10001
ENTRYPOINT  ["java","-jar","/app.jar"]

添加Harbor凭证
在这里插入图片描述
生成流水线脚本
在这里插入图片描述
完善Jenkins脚本

//注意:变量引用使用双引号
def git_auth = "108bc789-e1ee-4c1d-ac5a-54d5049b1cf7"
def project_url = "git@192.168.0.108:root/springcloud-tx.git"
//构建版本的名称
def  tag  =  "latest"
//Harbor私服地址
def  harbor_url  =  "192.168.0.111:85"
//Harbor的项目名称
def  harbor_project_name  =  "springcloud-tx"
def harbor_auth = "06955aa2-c0dc-4c53-9bd6-5c563bd13666"

node {
   stage('拉取') {
     checkout([$class: 'GitSCM', branches: [[name: '*/${branch}']], doGenerateSubmoduleConfigurations: false, extensions: [], submoduleCfg: [], userRemoteConfigs: [[credentialsId: "${git_auth}", url: "${project_url}"]]])
   }

   stage('构建') {

    //定义镜像名称
     def  imageName  =  "${project_name}:${tag}"
     sh  "mvn  -f  txservicecloud-common  clean  install"
     //sh  "mvn  -f  ${project_name}  clean  package"
     //编译,构建本地镜像
     sh  "mvn  -f  ${project_name}  clean  package  dockerfile:build"
     //给镜像打标签
     sh  "docker  tag  ${imageName} ${harbor_url}/${harbor_project_name}/${imageName}"

     //登录Harbor,并上传镜像
     withCredentials([usernamePassword(credentialsId:  "${harbor_auth}",
        passwordVariable:  'password',  usernameVariable:  'username')])  {
         //登录
         sh  "docker  login  -u  ${username}  -p  ${password}  ${harbor_url}"
         //上传镜像
         sh  "docker  push  ${harbor_url}/${harbor_project_name}/${imageName}"
        }

   //删除本地镜像
   sh  "docker  rmi  -f  ${imageName}"
   sh  "docker  rmi  -f  ${harbor_url}/${harbor_project_name}/${imageName}"
}
}

可以看到镜像上传完毕
在这里插入图片描述

11.6.5 拉取镜像和发布应用

  1. 安装 Publish Over SSH 插件
    安装以下插件,可以实现远程发送Shell命令
    在这里插入图片描述
    配置远程部署服务器

1)拷贝公钥到远程服务器

ssh-copy-id 192.168.0.110

在这里插入图片描述
3)系统配置->添加远程服务器
在这里插入图片描述
修改Jenkinsfile构建脚本,生成远程调用模板代码
在这里插入图片描述

sshPublisher(publishers: [sshPublisherDesc(configName: 'master_server', transfers: [sshTransfer(cleanRemote: false, excludes: '', execCommand: '', execTimeout: 120000, flatten: false, makeEmptyDirs: false, noDefaultExcludes: false, patternSeparator: '[, ]+', remoteDirectory: '', remoteDirectorySDF: false, removePrefix: '', sourceFiles: '')], usePromotionTimestamp: false, useWorkspaceInPromotion: false, verbose: false)])

构建之前要把springcloud-tx父工程打包拷贝(此时不要包含子模块)到192.168.0.110的仓库里面
在这里插入图片描述
完整Jenkins脚本

//注意:变量引用使用双引号
def git_auth = "108bc789-e1ee-4c1d-ac5a-54d5049b1cf7"
def project_url = "git@192.168.0.108:root/springcloud-tx.git"
//构建版本的名称
def  tag  =  "latest"
//Harbor私服地址
def  harbor_url  =  "192.168.0.111:85"
//Harbor的项目名称
def  harbor_project_name  =  "springcloud-tx"
def harbor_auth = "06955aa2-c0dc-4c53-9bd6-5c563bd13666"
//定义镜像名称
def  imageName  =  "${project_name}:${tag}"

node {
   stage('代码拉取') {
     checkout([$class: 'GitSCM', branches: [[name: '*/${branch}']], doGenerateSubmoduleConfigurations: false, extensions: [], submoduleCfg: [], userRemoteConfigs: [[credentialsId: "${git_auth}", url: "${project_url}"]]])
   }

   stage('工程镜像构建') {
     sh  "mvn  -f  txservicecloud-common  clean  install"
     //编译,构建本地镜像
     sh  "mvn  -f  ${project_name}  clean  package  dockerfile:build"
     //给镜像打标签
     sh  "docker  tag  ${imageName} ${harbor_url}/${harbor_project_name}/${imageName}"
    }

    stage('登录Harbor上传镜像') {
     //登录Harbor,并上传镜像
     withCredentials([usernamePassword(credentialsId:  "${harbor_auth}",
        passwordVariable:  'password',  usernameVariable:  'username')])  {
         //登录
         sh  "docker  login  -u  ${username}  -p  ${password}  ${harbor_url}"
         //上传镜像
         sh  "docker  push  ${harbor_url}/${harbor_project_name}/${imageName}"
        }
    }

    stage('删除本地镜像') {
        //删除本地镜像
       sh  "docker  rmi  -f  ${imageName}"
       sh  "docker  rmi  -f  ${harbor_url}/${harbor_project_name}/${imageName}"
    }

   stage('远程触发镜像拉取') {
       sshPublisher(publishers: [sshPublisherDesc(configName: 'master_server',
                                                    transfers: [sshTransfer(cleanRemote: false, excludes: '',
       execCommand: "/opt/jenkins_shell/deploy.sh  $harbor_url  $harbor_project_name  $project_name $tag  $port",
       execTimeout: 120000, flatten: false, makeEmptyDirs: false, noDefaultExcludes: false,
       patternSeparator: '[, ]+', remoteDirectory: '', remoteDirectorySDF: false, removePrefix: '', sourceFiles: '')],
       usePromotionTimestamp: false, useWorkspaceInPromotion: false, verbose: false)])
    }
}

在192.168.0.110机器部署脚本。
部署脚本

#! /bin/sh
#接收外部参数
harbor_url=$1
harbor_project_name=$2
project_name=$3
tag=$4
port=$5

imageName=$harbor_url/$harbor_project_name/$project_name:$tag

echo "$imageName"

#查询容器是否存在,存在则删除
containerId=`docker ps -a | grep -w ${project_name}:${tag}  | awk '{print $1}'`
if [ "$containerId" !=  "" ] ; then
    #停掉容器
    docker stop $containerId

    #删除容器
    docker rm $containerId
	
	echo "成功删除容器"
fi

#查询镜像是否存在,存在则删除
imageId=`docker images | grep -w $project_name  | awk '{print $3}'`

if [ "$imageId" !=  "" ] ; then
      
    #删除镜像
    docker rmi -f $imageId
	
	echo "成功删除镜像"
fi

# 登录Harbor
docker login -u txjava -p Txjava12345 $harbor_url

# 下载镜像
docker pull $imageName

# 启动容器
docker run -di -p $port:$port --net=host $imageName

echo "容器启动成功"

在这里插入图片描述
微服务运行结果。
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

麦芽糖0219

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值