基于jenkins+maven+docker实践springboot项目的CI/CD 自动化构建

背景

很多开发同学都忙于写代码,但是对项目发布的整个流程不是很清楚,本文基于CI/CD的思想,结合Jenkins,docker,maven搭建一个自动化的发布流程,并加入代码质量检测,希望通过这个流程,能给开发小伙伴一个大概的CI/CD概览,同时也反过来思考怎么去写好代码。

目标

本次demo的目标输出结果为

  1. 本地推送代码后自动触发jenkins构建流程
  2. Jenkins展示javadoc, jxr, projectinfo等site阶段常规文档
  3. Jenkins展示测试结果
  4. Jenkins展示测试覆盖率
  5. Jenkins展示 Checkstyle结果
  6. Sonar server展示结果
  7. 服务在docker 容器中自动启动

大家可以对着这些目标验证自己是否成功。

前期准备

知识准备

  1. 基本了解docker的基本操作,用于搭建环境,我会把所有代码都贴出来,但是为了方便排查问题,至少过一遍官网的quick start.
  2. 熟悉maven,包括pom标签,lifecycle, dependency机制等,这部分对于理解整个流程是最重要的
  3. jenkins界面操作,这个可以等搭建完成后自己先点点看
    如果没有上面的知识储备,理论上只要照着做,也能成功,但出了问题可能无法解决,可以在下方留言寻求帮助

硬件要求

实验环境为2台2核2G linux centos,SonarQube 和Jenkins对系统负载有点要求,所以将这俩分开来搭建。即现有2核2G server-a, server-b两服务器,下面以此代称。
注:如果选择都装在同一台服务器上,后面执行sonar分析的时候会遇到容器内网络访问问题,下面也会进行补充说明,但是对于docker不熟悉的同学还是建议分开来,避免学习成本。

软件安装

  1. docker(server-a, server-b 都需安装)
sudo yum install -y yum-utils \
  device-mapper-persistent-data \
  lvm2
sudo yum-config-manager \
 --add-repo \
https://download.docker.com/linux/centos/docker-ce.repo
sudo yum install docker-ce docker-ce-cli containerd.io

此部分为单纯安装docker,和官网上是一样的,有问题可以看下官网。

service docker start

启动守护线程
2.Jenkins(server-a安装,可以和下面的SonarQube搭建同时进行,节省时间)

docker run -p 9010:8080 -p 50000:50000 -u root -d \
 -v $(which docker):/usr/bin/docker \
 -v /opt/data/jenkins-data/home:/var/jenkins_home \
 -v /var/run/docker.sock:/var/run/docker.sock jenkins/jenkins:lts

设置web访问端口9010,-v volume挂载命令,将容器内资源映射到host。第1个v和第3个v的目的是将host docker映射到容器内部,这样在jenkins内启动服务容器时实际上是启动在host上的。
启动后进入Jenkins验证页面,使用docker ps 查看已启动的容器,
使用 docker查看容器日志命令查看 jenkins日志获取密码,

docker logs <jenkins-container-id>

或者

docker exec -it <jenkins-container-id> bash

进入容器内部,再按照页面提示的文件路径,cat 命令查看文件内容,输入密码,然后安装推荐插件完成Jenkins初始化,安装估计要点时间,可以先放着进行下一步。

  1. SonarQube(server-b安装)
 docker run -d --name sonarqube \
    -p 9012:9000 \
    -v sonarqube_data:/opt/sonarqube/data \
    -v sonarqube_extensions:/opt/sonarqube/extensions \
    -v sonarqube_logs:/opt/sonarqube/logs \
    sonarqube:latest

设置web端口9012,初始登录账号密码均为admin。

  1. 插件安装
    Jenkins正常启动后,进入左上角Jenkins->manage Jenkins-> manage plugins插件中心,搜索安装以下插件:
    1. Config File Provider Plugin
    2. JaCoCo plugin
    3. Warnings Next Generation Plugin
    4. Maven Integration plugin

Jenkins配置构建过程

  • 基础配置
    打开Jenkins->manage Jenkins->Global Tool Configuration
    配置git和maven


    Screen Shot 2020-04-07 at 00.05.05.png
Screen Shot 2020-04-07 at 00.04.59.png
  • 配置 Config File Provider Plugin 插件
    该插件目的在于添加自定义的配置文件,这里我们用来解决sonar server的host地址问题,maven里sonar插件的机制是请求其它搭建了sonarqube的server来进行分析,sonar server的host地址需要配置。
    打开Jenkins->manage Jenkins->managed files,
    点击add new config,
    选择type 为 global maven settings.xml,
    点击提交,然后左边菜单栏点击config files,
    进入页面后点击笔记本图标,
    更改name 为 sonar-maven,
    在下方content中 更改pluginGroups标签为
  <pluginGroups>
    <!-- pluginGroup
     | Specifies a further group identifier to use for plugin lookup.
    <pluginGroup>com.your.plugins</pluginGroup>
    -->
     <pluginGroup>org.sonarsource.scanner.maven</pluginGroup>
  </pluginGroups>

在profiles标签中添加

    <profile>
      <id>sonar</id>
      <activation>
        <activeByDefault>true</activeByDefault>
      </activation>
      <properties>
        <!-- Optional URL to server. Default value is http://localhost:9000 -->
        <sonar.host.url>
          http://<your-server-b-ip>:9012
        </sonar.host.url>
      </properties>
    </profile>

注意更换<your-server-b-ip>
注:如果只有一个server,<your-server-b-ip>填 server-ip是不行,这里变成了同一个docker下的container之间的通信,要借助docker network,执行:
docker network create sonar -- 创建name为sonar的network
docker network connect sonar <jenkins-container-id> -- 连接 Jenkins
docker network connect sonar <sonar-container-id> -- 连接 sonar
上方的 <your-server-b-ip> 改成 sonar的容器names(命令行最后一列NAMES)即可

Screen Shot 2020-04-07 at 00.08.39.png

  • Jenkins配置构建过程
    点击左上角Jenkins 选择 New Item, 构建一个maven项目,名字输入Jenkins-demo,确定。
    这时在我们主界面上会出现该项目
    Screen Shot 2020-04-07 at 00.19.52.png

点击进入项目,在左侧菜单栏中找到configure构建配置,进入。


Screen Shot 2020-04-07 at 00.20.04.png

上方的General等tab表示这个构建过程的阶段,下面将几个必要的点讲解一下

  1. Source Code Management
    源代码的地址配置,直接使用的github(有搭gitlab的可以把代码拉下来再上传到自己的)选择git,这里有写好的demo项目
    demo地址: https://github.com/JaphyFan/jenkins-parent.git
    大家可以直接用,拉到本地看下pom文件,代码我随意写的,主要是项目结构-多模块单体仓库(mono-repository),以及该结构下Pom里的配置,可以fork到自己的github仓库里,方便下面验证自动发布的时候修改代码,觉得有帮助的可以给个star。
    项目结构

    这里填写URL就行
    Screen Shot 2020-04-07 at 00.40.30.png
  2. build trigger
    触发build操作,为了全自动化,勾选poll scm,schedule里填写H/5 * * * *,代表每5分钟检测git 代码是否有变更,有的话自动构建。


    Screen Shot 2020-04-07 at 00.46.40.png
  3. Build Environment


    Screen Shot 2020-04-07 at 00.47.34.png

    这里我们主要是为了解决sonar server的问题,将刚开始我们创建的sonar-maven的配置文件放到构建环境中,如果你在 配置 Config File Provider Plugin 插件 中新建了文件,这个下拉框会显示出来,target填写settings.xml。
    注:设置SonarQube其实也有其它方式,例如命令参数等,这里不做细究。

  4. Build


    Screen Shot 2020-04-07 at 00.51.33.png

    真正的构建环节,设置maven执行命令:
    clean install site:site -Prelease -s settings.xml
    -P使用我们在pom 里定义的release profile,主要是生成文档,具体请看pom文件,-s settings.xml 引用我们在Build Environment里加入的maven 配置。

  5. Post-build Actions
    这里是我们添加各种报告展示的地方,点击 左下方的add post-build action, 然后添加
    1. aggregate downstream test results
    2. record jacoco coverage report
    3. record compiler warnings and static analysis results

aggregate downstream test results和record jacoco coverage report不需要填写,直接默认的就行,record compiler warnings and static analysis results在tool里选择 Checkstyle,javadoc,junit三个即可,选一个点下左下方的add tool,依次添加。


Screen Shot 2020-04-07 at 00.59.30.png

点击保存,至此构建配置完成了。

实验与结论

转换到项目主页面


项目主页面

点击左侧菜单的build now, 左下方会生成构建过程 #1,点击进入


Screen Shot 2020-04-07 at 01.03.38.png

点击console output查看构建日志,第一次构建速度比较慢,主要是下载maven依赖,构建成功后我们就可以验证文章开头设立的目标了。
  1. 本地推送代码后自动触发jenkins构建流程
  2. Jenkins展示javadoc, jxr, projectinfo等site阶段常规文档
  3. Jenkins展示测试结果
  4. Jenkins展示测试覆盖率
  5. Jenkins展示 Checkstyle结果
  6. Sonar server展示结果
  7. 服务在docker 容器中自动启动
  • 验证1:
    将项目代码fork到自己的github,更改代码,push上去,可以观察项目主页面右下方build history这里,我们设置的轮训时间是5分钟,最长5分钟会出现自动构建过程。
  • 验证2:
    在项目主页面,构建成功后有一个 maven-generated-site(上方图片里就有), 点击进入可看到项目信息以及javadoc和jxr生成的xref文档(提供源码和文档的交叉浏览)
  • 验证3:
    项目主页面 最新测试结果(上方图片里就有)运行了4个测试,没有失败。
  • 验证4:
    项目主页面 jacoco图表(上方图片里就有),可以点击表格查看更详细内容(sonar server里也默认附带了jacoco覆盖率)
  • 验证5:
    Warnings next generation在 项目主页面 插件生成了 Javadoc warnings, Junit wirings, Checkstyle wirings (上方图片里就有)
  • 验证6:
    登录server-b搭建的sonar server, 查看分析报告


    Screen Shot 2020-04-07 at 01.19.15.png
  • 验证7:
    java服务我们其实真实启动的是子模块order,我给order开了swagger,端口是9000,浏览器查看 server-a-ip:9000/swagger-ui.html,可以看到接口页面。
    同时在server-a下 使用docker ps 可以看到 order容器启动着。


    Screen Shot 2020-04-07 at 01.23.32.png

至此验证完毕。由于篇幅所限,pom文件反而没有多提,但其实pom才是最重要的,jenkins这种maven风格的构建方式全程借助maven的lifecycle,需要好好看下maven官网。另外,加强本地代码质量检测也很重要,像checkstyle, sonar,测试覆盖率这种idea都是有提供插件的。
希望本文对大家有所帮助,时间仓促,有需要优化或解释不清的地方欢迎留言讨论。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,271评论 5 476
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,275评论 2 380
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,151评论 0 336
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,550评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,553评论 5 365
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,559评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,924评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,580评论 0 257
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,826评论 1 297
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,578评论 2 320
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,661评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,363评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,940评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,926评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,156评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,872评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,391评论 2 342