一、持续集成应用背景:
DevOps:(英文Development(开发)和Operations(技术运营)的组合)是一组过程、方法与系统的统称,用于促进开发(应用程序/软件工程)、技术运营和质量保障(QA)部门之间的沟通、协作与整合。它的出现是由于软件行业日益清晰地认识到:为了按时交付软件产品和服务,开发和运营工作必须紧密合作;
应用背景:
一个开发单打独斗,撸代码,开发网站,自由自在;
多个开发同时开发一个网站,同时改一份代码。但是同时改一个文件会导致冲突;
采用分支结构,每天上班第一件事克隆代码,下班前最后一件事合并代码;
好景不长,开发越来越多,代码文件越来越多。每天下班前合并代码时,发现很多合并失败的文件。最后每天加班3小时人工合并代码;
解决方法:将代码合并的周期缩短,以前一天,现在一小时,半小时;
随时随地将代码合并,这种方法叫做持续集成;
理解持续集成、持续交付、持续部署:https://blog.csdn.net/kone0611/article/details/78534886
二、持续集成概述:
概述:持续集成(Continuous integration,简称CI),一种软件开发实践,即团队开发成员经常集成他们的工作,通过每个成员每天至少集成一次,也就意味着每天可能会发生多次集成。每次集成都通过自动化的构建(包括编译,发布,自动化测试)来验证,从而尽早地发现集成错误;
理解jenkins持续集成:https://www.cnblogs.com/liyuanhong/p/6548925.html
持续集成要素:
1.统一的代码库;
2.自动构建;
3.自动测试;
4.每个人每天都要向代码库主干提交代码;
5.每次代码递交后都会在持续集成服务器上触发一次构建;
6.保证快速构建;
7.模拟生产环境的自动测试;
8.每个人都可以很容易的获取最新可执行的应用程序;
9.每个人都清楚正在发生的状况;
10.自动化的部署;
三、持续交付概述:
概述:持续交付(Continuous delivery,简称CD),指的是:频繁地将软件的新版本,交付给质量团队或者用户,以供评审。如果评审通过,代码就进入生产阶段;持续交付可以看作持续集成的下一步。它强调的是,不管怎么更新,软件是随时随地可以交付的;
代码测试通过了,该到生产环境部署了,部署时要么成功,要么失败回滚;
四、持续部署概述:
概述:持续部署(Continuous Deployment,缩写为 CD)是持续交付的下一步,指的是代码通过评审以后,自动部署到生产环境;持续部署的目标是,代码在任何时刻都是可部署的,可以进入生产阶段;
五、Jenkins概述:
概述:Jenkins是一个用Java编写的开源的持续集成工具,Jenkins提供了软件开发的持续集成服务。它运行在Servlet容器中(例如Apache Tomcat)。它支持软件配置管理(SCM)工具(包括AccuRev SCM、CVS、Subversion、Git、Perforce、Clearcase和RTC),可以执行基于Apache Ant和Apache Maven的项目,以及任意的Shell脚本和Windows批处理命令;
Jenkins目的:
1.持续、自动地构建/测试软件项目;
2.监控软件开放流程,快速问题定位及处理,提示开放效率;
特性:
开源的java语言开发持续集成工具,支持CI,CD;
易于安装部署配置:可通过yum安装,或下载war包以及通过docker容器等快速实现安装部署,可方便web界面配置管理;
消息通知及测试报告:集成RSS/E-mail通过RSS发布构建结果或当构建完成时通过e-mail通知,生成JUnit/TestNG测试报告;
分布式构建:支持Jenkins能够让多台计算机一起构建/测试。
文件识别:Jenkins能够跟踪哪次构建生成哪些jar,哪次构建使用哪个版本的jar等;
丰富的插件支持:支持扩展插件,你可以开发适合自己团队使用的工具,如git,svn,maven,docker等;
产品发布流程:
产品设计成型 -> 开发人员开发代码 -> 测试人员测试功能 -> 运维人员发布上线
六、案例:部署Jenkins持续集成;
案例环境:
系统类型 | IP地址 | 主机名 | 所需软件 | 内存 |
Centos 7.4 1708 64bit | 192.168.100.101 | jenkins.linuxfan.cn | jdk-8u171-linux-x64.tar.gz apache-tomcat-9.0.10.tar.gz jenkins.war apache-maven-3.5.4-bin.tar.gz git gitlab-ce | 4G |
Centos 7.4 1708 64bit | 192.168.100.102 | http.linuxfan.cn | httpd | 1G |
组件作用:
Maven的作用:Maven负责java语言的编译和打包换个角度来说,Maven相当于Java中的make命令,同类型的工具有Ant,但是Ant不提供解决依赖关系的功能,如若上传nginx等html的文件则不需要maven程序;
JENKINS的作用:通过git或者svn等命令从仓库中拉取源码,让maven进行编译并打包,把打好的包发送到目标主机,执行部署脚本,自动触发构建操作;
Gitlab的作用:Gitlab用来做开发人员通过git提交的代码存放的仓库进行管理;
案例步骤:
- 安装Gitlab程序:
- 配置并启动Gitlab程序:
- 通过web页面配置Gitlab程序:
- 通过web页面创建Gitlab项目:
- 通过git命令测试下载Gitlab中的项目代码及测试上传项目代码:
- 访问Gitlab的web页面验证上传的项目代码:
- 安装部署jdk环境:
- 安装部署apache-maven框架:
- 安装部署jenkins程序(四种方式,在此使用第三种基于tomcat安装):
- 配置jenkins的web页面:
- 设置jenkins的环境变量与允许用户注册:
- 设置jenkins中的jdk的位置和maven的位置:
- 创建Jenkins任务:
- 构建任务完成后,构建触发任务,查看Jenkins是够能够成功连接到Gitlab:
- 模拟测试发布网站代码文件到gitlab,然后构建到Jenkins:
- 安装测试服务器上的httpd服务并且在jinkens主机上配置秘钥对,实现能远程到httpd服务:
- 配置jenkins程序构建任务推送网页文件到httpd服务器上:
- 验证httpd服务器的文件推送情况,客户端访问测试:
- 安装Gitlab程序:
[root@jenkins ~]# wget https://packages.gitlab.com/install/repositories/gitlab/gitlab-ce/script.rpm.sh [root@jenkins ~]# chmod +x script.rpm.sh [root@jenkins ~]# ./script.rpm.sh The repository is setup! You can now install packages. 有本地缓存的yum源最好啦 [root@jenkins ~]# yum install -y gitlab-ce
- 配置并启动Gitlab程序:
[root@jenkins ~]# vi /etc/gitlab/gitlab.rb 13 external_url 'http://192.168.100.101' :wq [root@jenkins ~]# gitlab-ctl reconfigure ##加载配置文件,每次修改后都需要 Running handlers: Running handlers complete Chef Client finished, 435/620 resources updated in 02 minutes 29 seconds gitlab Reconfigured! [root@jenkins ~]# gitlab-ctl start ok: run: alertmanager: (pid 13861) 17s ok: run: gitaly: (pid 13787) 19s ok: run: gitlab-monitor: (pid 13807) 19s ok: run: gitlab-workhorse: (pid 13770) 20s ok: run: logrotate: (pid 13360) 99s ok: run: nginx: (pid 13345) 105s ok: run: node-exporter: (pid 13457) 82s ok: run: postgres-exporter: (pid 13885) 16s ok: run: postgresql: (pid 13055) 146s ok: run: prometheus: (pid 13842) 17s ok: run: redis: (pid 12980) 152s ok: run: redis-exporter: (pid 13618) 65s ok: run: sidekiq: (pid 13307) 114s ok: run: unicorn: (pid 13263) 120s [root@jenkins ~]# netstat -utpln Active Internet connections (only servers) Proto Recv-Q Send-Q Local Address Foreign Address State PID/Program name tcp 0 0 127.0.0.1:9100 0.0.0.0:* LISTEN 2628/node_exporter tcp 0 0 127.0.0.1:9229 0.0.0.0:* LISTEN 3056/gitlab-workhor tcp 0 0 127.0.0.1:9168 0.0.0.0:* LISTEN 3102/ruby tcp 0 0 127.0.0.1:8080 0.0.0.0:* LISTEN 2481/unicorn master tcp 0 0 0.0.0.0:80 0.0.0.0:* LISTEN 2536/nginx: master tcp 0 0 127.0.0.1:8082 0.0.0.0:* LISTEN 2502/sidekiq 5.1.3 tcp 0 0 127.0.0.1:9236 0.0.0.0:* LISTEN 3072/gitaly tcp 0 0 0.0.0.0:22 0.0.0.0:* LISTEN 813/sshd tcp 0 0 127.0.0.1:25 0.0.0.0:* LISTEN 968/master tcp 0 0 0.0.0.0:8060 0.0.0.0:* LISTEN 2536/nginx: master tcp 0 0 127.0.0.1:9121 0.0.0.0:* LISTEN 2739/redis_exporter tcp 0 0 127.0.0.1:9090 0.0.0.0:* LISTEN 3117/prometheus tcp 0 0 127.0.0.1:9187 0.0.0.0:* LISTEN 3156/postgres_expor tcp 0 0 127.0.0.1:9093 0.0.0.0:* LISTEN 3129/alertmanager tcp 0 0 0.0.0.0:9094 0.0.0.0:* LISTEN 3129/alertmanager udp 0 0 0.0.0.0:9094 0.0.0.0:* 3129/alertmanager [root@jenkins ~]# chmod -R 755 /var/log/gitlab [root@jenkins ~]# yum -y install git [root@jenkins ~]# git config --global user.name "linuxfan" [root@jenkins ~]# git config --global user.email admin@linuxfan.cn [root@jenkins ~]# mkdir /opt/linuxfan [root@jenkins ~]# cd /opt/linuxfan [root@jenkins linuxfan]# git init 初始化空的 Git 版本库于 /opt/linuxfan/.git/ [root@jenkins linuxfan]# ssh-keygen -t rsa -C admin@linuxfan.cn [root@jenkins linuxfan]# cat /root/.ssh/id_rsa.pub ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDauS+Tnzq4FFole83uuSOt9iURbq0blLlSBp1dzXbS3re26o5idURw+SLFCc5BUp0Pd78I+Awtxtm1Nz58KAinATgmv5ImTN6yMSF99QTSR0ut/c8mIjm4cMHphGUIZgIplnCC5IwkbIcvQiHhkDzzn6YK/63Rp9hc3HyaGmMneDmxAhZglOeuno6i7i2hyNerKrDHlCaNPYx11u4KQ1J1wi9KGl1JL+FifTwQEtvWFgQE8HtkrslJsFwhzVrTi7Bv5d5U/GpnKn/7Fln0qPKNoWdl4MR/iD6zdZ8a5yDW+QK9ciiViKO0EzD3slWHxrq/evjPuTg6GRLtdKzVQAQL admin@linuxfan.cn
- 通过web页面配置Gitlab程序:
- 通过web页面创建Gitlab项目:
- 通过git命令测试下载Gitlab中的项目代码及测试上传项目代码:
[root@jenkins linuxfan]# git clone http://192.168.100.101/linuxfan/linuxfan.git 正克隆到 'linuxfan'... remote: Enumerating objects: 3, done. remote: Counting objects: 100% (3/3), done. remote: Total 3 (delta 0), reused 0 (delta 0) Unpacking objects: 100% (3/3), done. [root@jenkins linuxfan]# ls linuxfan [root@jenkins linuxfan]# ls linuxfan/ www.linuxfan.cn [root@jenkins linuxfan]# rm -rf linuxfan/ 或者[root@jenkins ~]# git clone git@192.168.100.101:linuxfan/linuxfan.git ##下载项目linuxfan 正克隆到 'linuxfan'... remote: Enumerating objects: 3, done. remote: Counting objects: 100% (3/3), done. remote: Total 3 (delta 0), reused 0 (delta 0) 接收对象中: 100% (3/3), done. [root@jenkins linuxfan]# cat linuxfan/www.linuxfan.cn ##查看项目下载后的代码 www.linuxfan.cn [root@jenkins linuxfan]# cd linuxfan/ ##切换到项目目录中 [root@jenkins linuxfan]# pwd /opt/linuxfan/linuxfan [root@jenkins linuxfan]# touch haha.txt ##创建测试代码文件 [root@jenkins linuxfan]# git add haha.txt [root@jenkins linuxfan]# git commit -m "haha.txt" ##将测试代码文件提交到git版本库中 [master ee68b76] haha.txt 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 haha.txt [root@jenkins linuxfan]# git remote add origin git@192.168.100.101:linuxfan ##创建远程的gitlab版本库,名称为origin [root@jenkins linuxfan]# git push ##将git版本库中的文件上传到gitlab Counting objects: 4, done. Compressing objects: 100% (2/2), done. Writing objects: 100% (3/3), 268 bytes | 0 bytes/s, done. Total 3 (delta 0), reused 0 (delta 0) To git@192.168.100.101:linuxfan/linuxfan.git bc0010d..ee68b76 master -> master
- 访问Gitlab的web页面验证上传的项目代码:
- 安装部署jdk环境:
[root@jenkins ~]# tar zxvf jdk-8u171-linux-x64.tar.gz [root@jenkins ~]# mv jdk1.8.0_171 /usr/local/java/ [root@jenkins ~]# vi /etc/profile export JAVA_HOME=/usr/local/java export PATH=$PATH:$MAVEN_HOME/bin:$JAVA_HOME/bin export JRE_HOME=$JAVA_HOME/jre export CLASSPATH=.:$JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tools.jar:$JRE_HOME/lib :wq [root@jenkins ~]# source /etc/profile [root@jenkins ~]# java -version java version "1.8.0_171" Java(TM) SE Runtime Environment (build 1.8.0_171-b11) Java HotSpot(TM) 64-Bit Server VM (build 25.171-b11, mixed mode)
- 安装部署apache-maven框架:
[root@jenkins ~]# wget http://mirror.bit.edu.cn/apache/maven/maven-3/3.5.4/binaries/apache-maven-3.5.4-bin.tar.gz [root@jenkins ~]# tar zxvf apache-maven-3.5.4-bin.tar.gz [root@jenkins ~]# mv apache-maven-3.5.4 /usr/local/maven [root@jenkins ~]# ls /usr/local/maven bin boot conf lib LICENSE NOTICE README.txt [root@jenkins ~]# ln -s /usr/local/maven/bin/* /usr/bin/ [root@jenkins ~]# vi /etc/profile export MAVEN_HOME=/usr/local/maven export PATH=$PATH:$MAVEN_HOME/bin :wq [root@jenkins ~]# source /etc/profile
- 安装部署jenkins程序(四种方式,在此使用第三种基于tomcat安装):
1.离线安装:
[root@jenkins ~]# wget http://pkg.jenkins-ci.org/redhat/jenkins-2.39-1.1.noarch.rpm ## 下载(也可以Windows下载再传过来) [root@jenkins ~]# rpm --import http://pkg.jenkins-ci.org/redhat/jenkins.io.key [root@jenkins ~]# yum -y install jenkins-*.noarch.rpm
2.在线安装:
[root@jenkins ~]# wget -O /etc/yum.repos.d/jenkins.repo https://pkg.jenkins.io/redhat/jenkins.repo [root@jenkins ~]# rpm --import https://pkg.jenkins.io/redhat/jenkins.io.key [root@jenkins ~]# yum -y install jenkins
3.基于 Tomcat 安装:
[root@jenkins ~]# wget http://mirrors.jenkins.io/war-stable/latest/jenkins.war [root@jenkins ~]# tar zxvf apache-tomcat-9.0.10.tar.gz [root@jenkins ~]# mv apache-tomcat-9.0.10 /usr/local/tomcat [root@jenkins ~]# cp jenkins.war /usr/local/tomcat/webapps/ [root@jenkins ~]# ls /usr/local/tomcat/webapps/jenkins.war ##上传jenkins.war包,tomcat自动识别 /usr/local/tomcat/webapps/jenkins.war [root@jenkins ~]# vi /usr/local/tomcat/conf/server.xml 69 <Connector port="8888" protocol="HTTP/1.1" :wq [root@jenkins ~]# /usr/local/tomcat/bin/startup.sh [root@jenkins ~]# netstat -utpln |grep java tcp 0 0 0.0.0.0:8888 0.0.0.0:* LISTEN 28027/java tcp 0 0 127.0.0.1:8005 0.0.0.0:* LISTEN 28027/java tcp 0 0 0.0.0.0:8009 0.0.0.0:* LISTEN 28027/java
发现浏览器安装jenkins卡在此处,通过以下方法解决;
[root@jenkins ~]# vi /root/.jenkins/hudson.model.UpdateCenter.xml 5 <url>http://mirror.xmission.com/jenkins/updates/update-center.json</url> :wq [root@jenkins ~]# vi .jenkins/updates/default.json :%s/google/baidu/g 将文件中的www.google.com替换成为www.baidu.com [root@jenkins ~]# /usr/local/tomcat/bin/shutdown.sh [root@jenkins ~]# /usr/local/tomcat/bin/startup.sh
再次刷新页面即可安装成功:
4.免安装方式:
[root@jenkins ~]# wget http://mirrors.jenkins.io/war-stable/latest/jenkins.war [root@jenkins ~]# java -jar jenkens.war ##启动服务,直至看到日志Jenkins is fully up and running [root@jenkins ~]# curl http://localhost:8080/ ##Jenkins已就绪
- 配置jenkins的web页面进行安装:
[root@jenkins ~]# cat .jenkins/secrets/initialAdminPassword 40e4323daf0e4717835df52068e66198
如若无法访问以下jenkins的主页,重启tomcat服务即可解决:
- 设置jenkins的环境变量与允许用户注册:
- 设置jenkins中的jdk的位置和maven的位置:
- 创建Jenkins任务:
- 构建任务完成后,构建触发任务,查看Jenkins是够能够成功连接到Gitlab:
- 模拟测试发布网站代码文件到gitlab,然后构建到Jenkins:
[root@jenkins ~]# cd /opt/linuxfan/ [root@jenkins ~]# rm -rf ./* [root@jenkins linuxfan]# git clone git@192.168.100.101:linuxfan/linuxfan.git 正克隆到 'linuxfan'... remote: Enumerating objects: 9, done. remote: Counting objects: 100% (9/9), done. remote: Compressing objects: 100% (5/5), done. remote: Total 9 (delta 1), reused 0 (delta 0) 接收对象中: 100% (9/9), done. 处理 delta 中: 100% (1/1), done. [root@jenkins linuxfan]# ls linuxfan [root@jenkins linuxfan]# cd linuxfan/ [root@jenkins linuxfan]# cat <<END >>index.html haohaoxuexi tiantianxiangshang END [root@jenkins linuxfan]# git add index.html [root@jenkins linuxfan]# git commit -m "index.html" [master 9cf216f] index.html 1 file changed, 2 insertions(+) create mode 100644 index.html [root@jenkins linuxfan]# git push Counting objects: 4, done. Writing objects: 100% (3/3), 261 bytes | 0 bytes/s, done. Total 3 (delta 0), reused 0 (delta 0) To git@192.168.100.101:linuxfan/linuxfan.git 04265b2..9cf216f master -> master
- 安装测试服务器上的httpd服务并且在jinkens主机上配置秘钥对,实现能远程到httpd服务:
[root@http ~]# yum -y install httpd [root@http ~]# systemctl start httpd [root@http ~]# rm -rf /var/www/html/* [root@jenkins linuxfan]# ssh-copy-id root@192.168.100.102 [root@jenkins linuxfan]# ssh root@192.168.100.102 Last login: Wed Sep 26 20:19:44 2018 from 192.168.100.1 [root@http ~]# exit
- 配置jenkins程序构建任务推送网页文件到httpd服务器上:
- 验证httpd服务器的文件推送情况,客户端访问测试:
定时触发构建
构建触发器: 只选中 Build periodically, “日程表”格式与 crontab 相似但有细微差别,示例如下:
## 每行由 5 个值组成(空格或TAB分隔),分别表示分(0-59)、时(0-23)、日(1-31)、月(1-12)、周(0-7, 0/7=周日)
## "M,N" 表示M和N;"M-N" 表示范围[M,N];"M-N/X" 表示范围[M,N]内每隔X;"*/X" 表示整个范围内每隔X
## 前面提到的M/N/X的值都可以用H(意为Hash)代替,散列值起到随机值的效果,且同一项目取值稳定,这对于项目多时分散压力很有用。
H/10 H(0-8) * * 1-5 ## 触发时间: 工作日、Hour为0~8按哈希随机、Minute以10为间隔
H/10 H * * 0,6,7 ## 触发时间: 周末、Hour为全天按哈希随机、Minute以10为间隔
## “日程表”修改后,下方会给出下次执行时间点的预告。