第1章 引言
1.1 持续集成介绍
随着软件开发复杂度的不断提高,团队开发成员间如何更好地协同工作以确保软件开发的质量已经慢慢成为开发过程中不可回避的问题。尤其是近些年来,敏捷(Agile) 在软件工程领域越来越红火,如何能再不断变化的需求中快速适应和保证软件的质量也显得尤其的重要。
持续集成正是针对这一类问题的一种软件开发实践,对于提高软件开发效率并保障软件开发质量提供了理论基础。它倡导团队开发成员必须经常集成他们的工作,甚至每天都可能发生多次集成。而每次的集成都是通过自动化的构建来验证,包括自动编译、发布和测试,从而尽快地发现集成错误,让团队能够更快的开发内聚的软件。
持续集成最早由Martin Fowler 于10年前已经提出,希望通过持续集成能够实现以下过程:
Ø 任何人在任何地点,任何时间可以构建整个项目。
Ø 在持续集成构建过程中,每一个单元测试都必须被执行。
Ø 在持续集成构建过程中,每一个单元测试都必须通过。
Ø 持续集成构建的结果是可以发布的软件包。
Ø 当以上任何一点不能满足时,整个团队的主要任务就是去解决这个问题。
1.2 持续集成核心价值
持续集成中的任何一个环节都是自动完成的,无需太多的人工干预,有利于减少重复过程以节省时间、费用和工作量;
持续集成保障了每个时间点上团队成员提交的代码是能成功集成的。换言之,任何时间点都能第一时间发现软件的集成问题,使任意时间发布可部署的软件成为了可能;
持续集成还能利于软件本身的发展趋势,这点在需求不明确或是频繁性变更的情景中尤其重要,持续集成的质量能帮助团队进行有效决策,同时建立团队对开发产品的信心。
1.3 持续集成组成部分
由此可见,一个完整的构建系统必须包括:
Ø 一个自动构建过程,包括自动编译、分发、部署和测试等。
Ø 一个代码存储库,即需要版本控制软件来保障代码的可维护性,同时作为构建过程的素材库。
Ø 一个持续集成服务器。本文中介绍的 Jenkins/Jenkins 就是一个配置简单和使用方便的持续集成服务器。
1.4 Jenkins介绍
Jenkins是一个软件界非常流行的开源CI服务器,Hodson是基于Java开发的一种持续集成工具,用于监控持续重复的工作,功能包括:
Ø 持续的软件版本发布/测试项目。
Ø 监控外部调用执行的工作。
Jenkins的新版本取名叫Jenkins,所以本文档中的指Jenkins与Jenkins这2个词为指同一个软件。
使用Jenkins人员需要对持续集成的概念有所了解,更多的要求对代码的编译过程很了解,Jenkins对于maven工程完整的编译和发布流程如下:
Ø Jenkins从SVN上拉取代码到指定的编译机器上。
Ø 在编译机器上触发编译命令或脚本。
Ø 编译得到的结果文件。
Ø 把结果文件传到指定的服务器上。
使用Jenkins进行编译的人员,需要对自己的代码的编译方法,过程十分了解,对编译任务进行分拆。
第2章 环境准备
2.1 服务器准备
2.1.1 服务器列表
服务器编号 | 服务器用途 | 版本 | 内存 | cpu | 备注 |
---|---|---|---|---|---|
SERVER_NO_1 | Jenkins服务器 | Centos7 | 4g | 2核 | 安装Jenkins、组件 |
SERVER_NO_2 | Gitlab服务器 | Centos7 | 8g | 2核 | 代码管理 |
2.1.2 服务器搭建
搭建详情,请参考该目录下[服务器搭建和docker安装.docx](服务器搭建和docker 安装.docx)中的2.1.1章节内容。
2.2 软件列表
软件 | 版本 | 备注 |
---|---|---|
DOCKER | 18.03.1-ce | Docker 集成jenkins |
2.2.1 Docker安装
Docker安装详情,请参考该目录下[服务器搭建和docker安装.docx](服务器搭建和docker 安装.docx)中的3.1章节内容。
2.2.2 JDK安装
2.2.2.1 虚拟机安装JDK
1、通过yum命令可直接进行安装
yum install java-1.8.0-openjdk* -y
2、查看JAVA_HOME
JDK默认安装到/usr/lib/jvm目录下,即可找到对应的JAVA_HOME。
3、配置JAVA_HOME
export JAVA_HOME=/usr/lib/jvm/java-1.8.0-openjdk-1.8.0.232.b09-0.el7_7.x86_64
export JRE_HOME=$JAVA_HOME/jre
export CLASSPATH=$JAVA_HOME/lib:$JRE_HOME/lib:$CLASSPATH
export PATH=$JAVA_HOME/bin:$JRE_HOME/bin:$PATH
4、配置生效
source /etc/profile
5、查看安装版本
java -version
2.2.2.2 Docker安装JDK
当Jenkins安装完成后,访问Jenkins管理界面后,通过Jenkins中的全局工具配置,可以安装JDK。
在安装JDK之前如果没有oracle账号,需注册一个oracle账号,在安装过程中需要填写账号信息。
点击新增JDK输入对应的JDK别名,选择对应的JDK版本就可以成功安装。
安装成功后通过在镜像中通过java -version就可以查看JDK安装版本。
2.3 组件部署
2.3.1 Gitlab部署
Gitlab部署教程,请参考该目录下的Gitlab代码仓库搭建文档。
2.3.2 Sonarqube部署
Sonarqube部署教程,请参考该目录下的Sonarqube组件部署文档。
第3章 JENKINS搭建
3.1 安装JENKINS
3.1.1 镜像下载
Docker安装完成后可以通过docker命令下载一个jenkins镜像,命令如下,执行后开始下载中。
docker pull jenkinsci/blueocean
3.1.2 运行镜像进行启动
docker run -u root --name jenkins-image -d -p 8080:8080 -p 50000:50000 -v jenkins-data:/var/jenkins_home -v /var/run/docker.sock:/var/run/docker.sock jenkinsci/blueocean
运行命令参数讲解
参数 | 含义 | 备注 |
---|---|---|
-u root | 指定容器的用户root | |
--name jenkins-image | 镜像起一个name的别名 | jenkins-image镜像别名 |
-d | 在后台运行容器(即“分离”模式)并输出容器ID。如果您不指定此选项, 则在终端窗口中输出正在运行的此容器的Docker日志。 | |
-p 8080:8080 | 容器的端口8080到主机上的端口8080 | Jenkins默认采用8080端口进行访问 |
-p 50000:50000 | 容器的端口50000 映射到主机上的端口50000 | 如果您在其他机器上设置了一个或多个基于JNLP的Jenkins代理程序,而这些代理程序又与 jenkinsci/blueocean 容器交互(充当“主”Jenkins服务器,或者简称为“Jenkins主”), 则这是必需的。默认情况下,基于JNLP的Jenkins代理通过TCP端口50000与Jenkins主站进行通信。 |
-v jenkins-data:/var/jenkins_home | /var/jenkins_home目录下映射到宿主机的本地文件系统上/var/lib/docker/volumes/jenkins-data | |
-v /var/run/docker.sock:/var/run/docker.sock | 表示Docker守护程序通过其监听的基于Unix的套接字。 该映射允许 jenkinsci/blueocean 容器与Docker守护进程通信, 如果 jenkinsci/blueocean 容器需要实例化其他Docker容器,则该守护进程是必需的。 | |
jenkinsci/blueocean | Docker镜像本身。 | 如果此镜像尚未下载,则此 docker run 命令 将自动为您下载镜像 |
3.1.3 镜像操作
查看运行中的镜像
docker ps
进入镜像
docker exec -it 镜像实例ID(镜像实例name) /bin/bash
3.1.4 解锁JENKINS
1、通过该路径找到对应的jenkins的初始化密码。
cat /var/jenkins_home/secrets/initialAdminPassword
2、访问Jenkins管理界面
通过浏览器访问http://192.168.31.31:8080,密码为步骤1查询出来的密码长度为32位字符串,例如:09d8838e2b06422a8b5094182451335b
3.1.5 安装推荐插件
根据jenkins的推荐,建议选择安装推荐的插件。
如果有插件安装失败,不用紧张,安装结束之后会有"Retry”重试选项,点击重试即可或者请记录失败插件之后通过jenkins管理界面上在次进行手动安装。
7、查看日志
docker logs 镜像实例id/镜像实例name
在宿主机上可以通过命令查看docker在安装过程中出现的异常情况,命令如下:
docker logs jenkins-name
1、安装完成后
配置用户名、密码、邮件等信息,点击Save And Finish,即可完成初始化配置。
3.2 JENKINS结构目录说明
JENKINS_HOME说明
目录名称 | 简介 |
---|---|
config.xml | jenkins 的核心配置文件 |
hudson.tasks.Maven.xml | Maven 的安装细节 |
....xml: | 其它各种工具的配置信息 |
fingerprints | 跟踪人工操作的痕迹 |
jobs | 构建作业的配置细节,及构建产物和数据 |
Jobs/workspace | jenkins 对当前作业进行构建的地方,包含 jenkins 检验过的源码、构建本身生成的所有文件 |
Jobs/builds | 包含当前作业的构建历史 |
Jobs/config.xml | 存放当前作业的所有配置细节 |
Jobs/nextBuildNumber | 下一次构建的 number |
Jobs/lastStable | 最后一个稳定构建的链接(成功的构建) |
Jobs/lastSuccessful | 最近成功的构建链接(没有任何编译错误) |
plugins | 存放所有已安装的插件更新 jenkins 不需要重新安装插件 |
users | 当使用 jenkins 本地用户数据库时,用户信息会存放在这个目录下 |
updates | 存放可用的插件更新 |
userContent | 存放用户自己为 jenkins 服务器定制化的一些内容 |
war | 存放扩展的 web 应用程序,当以单机应用程序的形式运行 jenkins 时,会把 web 应用程序解压到这个目录。 |
3.3 JENKINS系统配置
模块 | 参数说明 |
---|---|
Jenkins URL | Jenkins 管理界面地址 |
系统管理邮件地址 | 管理员的邮箱地址 |
Github模块 | 系统中使用的gitlab 无需配置 |
Pipeline Model Definition | 流水线作业 无需配置 |
3.4 JENKINS全局工具配置
3.4.1 JDK配置
访问jenkins所在的docker环境没有JDK,可访问Jenkins管理界面后,通过Jenkins中的全局工具配置,可以安装JDK。在安装JDK之前如果没有oracle账号,需注册一个oracle账号,在安装过程中需要填写账号信息。
点击新增JDK输入对应的JDK别名,选择对应的JDK版本就可以成功安装。
安装成功后通过在镜像中通过java -version就可以查看JDK安装版本。
3.4.2 MAVEN配置
访问Jenkins管理界面后,通过Jenkins中的全局工具配置,可以安装MAVEN插件。
点击
点击下面的应用既可完成maven的安装配置。
3.5 JENKINS安全配置
JENKINS的安全设置在系统配置中的全局安全配置。
在全局安全配置中
模块 | 参数简介 | 备注 |
---|---|---|
启用安全 | 安全策略的启动 | 如果Jenkins暴露在公网环境,你最好启用此项.Jenkins如果在一个不安全的环境下可能会遭到黑客的攻击. |
安全域 | 允许jenkins用户注册 | |
授权策略 | 项目矩阵授权策略 | 在这种授权模型中,你可以通过一个大的表格来配置什么用户可以做什么事. |
标记格式器 | 选择job description写的html代码是显示代码还是显示html源码。 | 选择raw HTML的时候,显示的是自己写的源代码。选择escaped HTML的时候,显示的是html的源码 |
代理端口 | 默认代理端口50000 | 暂时无用,未做到jenkins集群 |
跨站请求伪造保护 | 开启对于jenkins的保护 | 它是一种利用你的身份通过未经授权的第三方手段在网站上执行操作.对于Jenkins进行删除任务,构建或者更改配置. 当启用此项,Jenkins会检查临时生成的值,以及任何导致Jenkins服务器改变的请求.这包括任何形式的提交和远程API调用. |
API Token | 接口交互鉴权 | |
Enable Slave → Master Access Control | 允许子节点控制父节点,具体有哪些权限可以被子节点控制。可以在一个通过点击rules can be tweaked here 这句话中的here来设置。 | |
SSHD port | 默认采用禁用的方式 |
3.6 JENKINS插件安装说明
3.6.1 自动安装
插件管理在jenkins中的系统配置的子目录下,进入可以观察到已经安装、可更新、可选插件。
在可选插件中选择对应插件,点击下方的”直接安装”可以将对应插件整合在jenkins中。
3.6.2 手动安装
1、进入到jenkins的插件管理中点击高级,
2、选择对应的程序包进行上传即可,将对应插件安装到jenkins中。
3.7 JENKINS邮件通知配置
参数名称 | 参数含义 | 测试值 | 备注 |
---|---|---|---|
SMTP SEVER | 邮件服务器地址 | smtp.mxhichina.com | |
Default user E-mail suffix | 邮件邮箱后缀 | @wealthypower.cn | |
User Name | 发件人的邮箱 | guoxy@wealthypower.cn | 此处邮件需和系统管理员邮件地址保持一致 |
Password | 发件人的密码 | ******* | |
Use SSL | Ssl加密不建议采用 | ||
SMTP Port | 邮件端口号 | 25 | |
Charaset | 字符集 | UTF-8 | |
Default Content Type | 邮件内容格式 | HTML | 邮件内容格式 |
Default Recipients | 默认收件人 | guoxy@wealthypower.cn,ruixl@wealthypower.cn | |
Reply To List | 回复列表 | guoxy@wealthypower.cn | 回复列表 |
Emergency reroute | 紧急道路 | ||
Allowed Domains | 允许的域 | ||
Excluded Recipients | 排除的收件人 | 默认无 | |
Default Subject | 默认主题 | $PROJECT_NAME - Build # $BUILD_NUMBER - $BUILD_STATUS! | |
Maximum Attachment Size | 最大邮件大小 | 此处对于邮件无限制 | |
Default Content | 默认内容 | 为邮件模板 |
3.8 JENKINS构建作业创建
3.8.1 创建构建任务
在Jenkins首页新建任务,目前项目开发过程中采用maven构建,收入项目名称,确认创建构建任务。
3.8.2 构建配置
1、构建任务的描述说明可选参数
2、构建环境中采用gitlab进行管理,源码来源为git接着,填写对应的git上对应的URL和账号信息,以及对应的分支。
3、构建触发可以使用cron表达式来实现定时作业,当发现有变化时开始构建操作。
4、构建前置作业配置
5、构建作业指令配置
5、构建过程中也可以添加邮件告知
6、构建后作业,构建完成后选择邮件告知操作。
7、构建后作业,创建完成后点击应用完成构建。
3.9 Jenkins集成sonar
3.9.1 插件安装
访问jenkins后台在插件管理中点击搜索该插件SonarQube Scanner for Jenkins。搜索后点击下载安装。
3.9.2 配置sonar
访问jenkins管理后台,由系统管理切换至系统配置。
1、配合sonar服务端
2、配置token信息
3.10 时区配置(jenkins)
\1. 进入容器
docker exec -it -u root jenkins-image /bin/bash
\2. 查看容器时区
cat /etc/timezone
Etc/UTC
\3. 修改容器时区
echo 'Asia/Shanghai' > /etc/timezone
exit
\4. 重启容器
docker restart jenkins-image
第4章 构建作业
4.1 作业创建
1、在jenkins导航栏,点解”新建任务”创建构建任务。
2、输入构建任务名称,由于ppa项目是maven项目,所以选择对应的maven构建作业任务。
4.2 作业配置
4.2.1 总体的模块
主要设置该次构建的主要目的是用来做什么的备注信息,以及gitlab的连接配置。
4.2.2 源码管理模块
根据源码的管理组件,选择对应的源码管理插件目前支持的 Git、Subversion、Mercurial ,PPA项目采用的是gitlab进行源码管理的,需配置源码的URL和gitlab的账号,如果使用ssh的路径用户和token的方式进行鉴权,如果使用的http协议的话,请采用用户名和密码的方式进行鉴权。
4.2.3 构建触发
触发模式有以下方式:触发远程构建、定时构建、其他工程构建后触发、轮询SCM等方。Ppa项目采用cron表达实现轮训时触发,当代码有变动时,重新构建作业。
4.2.4 构建环境设置
构建环境设置
1、在生成开始之前删除工作区
2、使用机密文本或文件功能帮助:使用机密文本或文件
3、如果构建被卡住,请中止它
4、向控制台输出添加时间戳
5、使用ssh在远程主机上执行shell脚本帮助功能:使用ssh在远程主机上执行shell脚本
6、生成发行说明
7、检查生成日志以获取已发布的渐变生成扫描
8、准备Sonaqube扫描仪环境功能帮助:准备Sonaqube扫描仪环境
9、和ANT一起
4.2.5 构建前置操作
构建前置作业可选择如下动作
该作业使用sonar插件进行代码扫描。Additional arguments -X表示可以输出debug日志信息。
参数 | 含义 | 备注 |
---|---|---|
sonar.login | Sonar账户 | |
sonar.password | Sonar密码 | |
sonar.projectKey | 项目名称 | |
sonar.language | 使用的语言 | Soanr可以扫描多种语言 |
sonar.java.source | JDK版本 | Jdk版本 |
sonar.sourceEncoding | 字符编码 | 源码中的编码 |
sonar.modules | 多个模块以逗号隔开 | |
itemproject.sonar.projectName | 子项目模块 | |
itemproject.sonar.sources | 子项目代码块 | |
sonar.java.binaries | 指向包含与源文件对应的已编译字节码文件的目录的逗号分隔路径。可以使用通配符 | ${workspace}/**/target/classessonar.java.binaries (required) Comma-separated paths to directories containing the compiled bytecode files corresponding to your source files. |
sonar.login=admin
sonar.password=admin
sonar.projectKey=wp-ppa
sonar.language=java
sonar.java.source=1.8
sonar.sourceEncoding=UTF-8
sonar.modules=wp-ppa-application-edge,wp-ppa-web,wp-common-core,wp-ppa-dao,wp-ppa-extension,wp-ppa-model,wp-ppa-scheduler,wp-ppa-service
wp-ppa-application-edge.sonar.projectName=wp-ppa-application-edge
wp-ppa-application-edge.sonar.sources=src
wp-ppa-web.sonar.projectName=wp-ppa-web
wp-ppa-web.sonar.sources=src
wp-common-core.sonar.projectName=wp-common-core
wp-common-core.sonar.sources=src
wp-ppa-dao.sonar.projectName=wp-ppa-dao
wp-ppa-dao.sonar.sources=src
wp-ppa-extension.sonar.projectName=wp-ppa-extension
wp-ppa-extension.sonar.sources=src
wp-ppa-model.sonar.projectName=wp-ppa-model
wp-ppa-model.sonar.sources=src
wp-ppa-scheduler.sonar.projectName=wp-ppa-scheduler
wp-ppa-scheduler.sonar.sources=src
wp-ppa-service.sonar.projectName=wp-ppa-service
wp-ppa-service.sonar.sources=src
sonar.java.binaries=${workspace}/**/target/classes
4.2.6 构建
Maven项目是pom.xml来管理项目。构建需要执行的命令
① maven常用命令
② mvn clean 清空产生的项目( target里)
③ mvn compile 编译源代码
④ mvn install 在本地repository中安装jar(包含mvn compile,mvn package,然后上传到本地仓库)
⑤ mvn deploy 上传到私服(包含mvn install,然后,上传到私服)
⑥ mvn package 打包
⑦ mvn test 运行测试
⑧ mvn site 产生site
⑨ mvn test-compile 编译测试代码
⑩ mvn -Dtest package 只打包不测试
⑪ mvn jar:jar 只打jar包
⑫ mvn test -skipping compile -skipping test-compile 只测试而不编译,也不测试编译
⑬ mvn deploy
⑭ mvn source.jar 源码打包
4.2.7 构建后置作业
当构建成功后,通过脚本将可执行文件发送到对应服务器上。脚本单独说明。
采用邮件告知的方式进行开发者本次构建任务的结果。
4.3 部署jar
4.3.1 脚本文件
PPa项目主要部署2个jar 文件,wp-ppa-web.jar,wp-ppa-application-edge.jar。请参考脚本注释进行文档的理解。
4.3.2 设置免密访问
因为目前测试服务器上使用的openvpn,用来验证用户是否合法,因此jenkins的容器上也需要安装openvpn客户端。
4.3.2.1 vpn的安装
容器使用的基础是镜像是什么版本,决定使用什么命令。
centos肯定有yum,ubuntu那即是apt-get,alpine那即是apk。
Ø 安装vpn
apk add openvpn
4.3.2.2 SSH免密配置
SSH免密配置就是2个linux 系统互相彼此知道对方的公钥,然后可以进行互相访问,不需要数据密码。
Ø 生成容器密钥(客户端)
客户端生成密钥的方法很简单,只需要使用ssh-keygen命令。
ssh-keygen -t rsa
生成密钥过程中,建议采用默认值,只需要按三次回车之后,就会再~/.ssh目录下生成密钥文件,其中,id_rsa为私钥,id_rsa.pub为公钥。
Ø 服务端配置
服务器的~/.ssh/authorized_keys文件保存可快速连接的客户端的公钥。只需把客户端生成的id_rsa.pub文件的内容拷贝到authorized_keys文件的末尾。拷贝的方法有:
\1. 直接拷贝。由于id_rsa.pub和authorized_keys都是文本文件,可通过拷贝命令直接拷贝。
\2. 把id_rsa.pub上传到服务器,然后再把内容添加到authorized_keys文件中。 在客户端把文件上传到服务器的用户目录的操作命令如下:
scp ~/.ssh/id_rsa.pub root@服务器ip:
在服务器操作的命令如下:
cat id_rsa.pub >> ~/.ssh/authorized_keys
4.3.2.3 启动vpn
1. 上传证书
docker cp 本机保存文件的全路径 container_id:docker容器内的文件全路径,这里我将所有的证书文件已经上传至宿主机的/opt/openvpn目录下。
docker cp /opt/openvpn jenkins-image:/opt
证书信息已经复制到容器
2. 启动vpn
使用如下命令进行启动
openvpn --config /opt/openvpn/client_vpn.ovpn --log-append /var/log/openvpn.log &
报错排查
ERROR: Cannot open TUN/TAP dev /dev/net/tun: No such file or directory (errno=2)
加载tun模块后,系统没能自动创建/dev/net/tun (应该是没使用udev的原因) 手工搞一下: mkdir /dev/net mknod /dev/net/tun c 10 200
chmod 666 /dev/net/tun
再次启动
来源:oschina
链接:https://my.oschina.net/2018rxl/blog/3210104