1987WEB视界-分享互联网热点话题和事件

您现在的位置是:首页 > WEB开发 > 正文

WEB开发

SpringCloud+Docker+Jenkins+GitLab+Maven实现自动化构建与部署实战

1987web2023-10-06WEB开发56

点击上方Java小组,选择星标

IT技术文章第一时间送达!

作者:寅务

jianshu.com/p/bdb0642b7495

1、前言与初衷

本文章会涉及Docker常见命令基础知识点结合不同场景实操一起使用。

本文章会涉及结合工作过程中部署不同环境服务器的项目案例场景为初心进行实际细讲。

本文章主要讲述Docker、Jenkins、GitLab、Git、JDK、SpringBoot、Maven等技术结合实现自动化运维部署(DevOps)应用工程,适合SpringCloud部署。

初衷想法:在学习过程中遇到比较有趣的问题、然而花了点心血和时间去整理,然而进行梳理出来一份文章比较完整有知识体系的DevOps自动化构建与部署工程文章,技术知识内容比较多,而且文章内容较长,然而分了几个章程来讲述

2、什么是DevOps?

DevOps(Development和Operations的组合词)是一组过程、方法与系统的统称,用于促进开发(应用程序/软件工程)、技术运营和质量保障(QA)部门之间的沟通、协作与整合,它是一种重视软件开发人员(Dev)和IT运维技术人员(Ops)之间沟通合作的文化、运动或惯例。透过自动化软件交付和架构变更的流程,来使得构建、测试、发布软件能够更加地快捷、频繁和可靠。

它的出现是由于软件行业日益清晰地认识到:为了按时交付软件产品和服务,开发和运营工作必须紧密合作。

3 涉及软件环境搭建内容

  • 如何在Centos7安装JDK1.8-u121详解

  • 如何在Centos7安装Maven3.6.1详解

  • 如何在Centos7安装Git详解

  • 如何在CentOS7与Git配置免密码登陆详解

  • 如何在Docker安装GitLab详解

  • 如何在Docker创建NetWork网络详解

  • 如何在Docker安装Registry私服详解

  • 如何在Docker安装Jenkins详解

见附录

特别说明

1、如何使用Maven结合Docker把SpringBoot应用编译成可用的镜像进行部署。

2、其中JDK和Maven是传统方式进行安装,由于本人Centos操作系统是有其他软件依赖它们,有时候传统方式安装软件会更好,这里不过多的阐述。有些软件在Docker安装过程与使用过程并没传统方式的简单,比如:Jenkins。

4、需要准备的工作有哪些

4.1 工程结构

  • 打开IDEA或Eclipse新建一个SpringBoot的应用.

环境配置特别说明

注意事项:其中Gitlab、Registry、Jenkins都安装在node1机器上面,也就是node1作为主机(master),node2作为slave(从机或副机),机器名起有意义或能区分即可,推荐起master和slave,这里就不作过多的阐述,为了避免看文章有疑问,请看清单列表.

4.2、SpringBoot配置和代码详解

4.2.1工程的pom.xml配置
<dependencies><dependency><groupId>org.springframework.bootgroupId><artifactId>spring-boot-starterartifactId>dependency><dependency><groupId>org.springframework.bootgroupId><artifactId>spring-boot-starter-webartifactId>dependency><dependency><groupId>org.springframework.bootgroupId><artifactId>spring-boot-devtoolsartifactId><scope>runtimescope><optional>trueoptional>dependency><dependency><groupId>org.springframework.bootgroupId><artifactId>spring-boot-configuration-processorartifactId><optional>trueoptional>dependency><dependency><groupId>org.springframework.bootgroupId><artifactId>spring-boot-starter-testartifactId><scope>testscope>dependency>dependencies><build><finalName>springbootfinalName><plugins><plugin><groupId>org.apache.maven.pluginsgroupId><artifactId>maven-compiler-pluginartifactId><configuration><source>1.8source><target>1.8target>configuration>plugin><plugin><groupId>org.springframework.bootgroupId><artifactId>spring-boot-maven-pluginartifactId><executions><execution><goals><goal>repackagegoal>goals>execution>executions>plugin><plugin><groupId>com.spotifygroupId><artifactId>docker-maven-pluginartifactId><version>0.4.12version><configuration><dockerDirectory>${project.basedir}dockerDirectory><resources><resource><targetPath>/targetPath><directory>${project.build.directory}directory><include>${project.build.finalName}.jarinclude>resource>resources>configuration>plugin><plugin><groupId>org.apache.maven.pluginsgroupId><artifactId>maven-jar-pluginartifactId><configuration><archive><manifest><mainClass>com.flong.SpringbootApplicationmainClass>manifest>archive>configuration>plugin>plugins>build>
4.2.2 no main manifest attribute错误解决
  • 配置工程主入口

<plugin><groupId>org.apache.maven.pluginsgroupId><artifactId>maven-jar-pluginartifactId><configuration><archive><manifest><mainClass>com.flong.SpringbootApplicationmainClass>manifest>archive>configuration>plugin>
4.2.3 env环境变量文件
  • 用于设置环境动态参数,文件是以.env为格式

JAVA_OPTS_DEFAULT=-Xmx512m
4.2.4 Dockerfile打包工程镜像细讲
  • 以开发环境的Dockerfile为例,如果是测试环境则,把所有路径包含springboot_dev改成springboot_test

FROMfrolvlad/alpine-oraclejdk8:slimMAINTAINERjilongliang@sina.comRUNln -sf /usr/share/zoneinfo/Asia/Shanghai /etc/localtimeRUNmkdir -p /home/devsoft/springboot_devWORKDIR/home/devsoft/springboot_devEXPOSE7011ADD./target/springboot.jar ./CMDjava${JAVA_OPTS_DEFAULT}-Djava.security.egd=file:/dev/./urandom -jar springboot.jar
  • 参数说明

  • WORKDIR 工作目录说明进入容器此时会有一个.jar是在Dockerfile的ADD添加进去

dockerexec-it 容器名称或容器id /bin/sh

或要使用sh和bash要看COMMAND,-it

dockerexec-it 容器名称或容器id/bin/bash
4.2.5 build.sh文件shell脚本详解

注意点1:经过测试动态变量的【等号】不能有空格和tab键置位,否则获取不了值,而且在shell脚本代码里面不支持空格格式化,支持tab置位格式化。在终端(ssh软件端)或Jenkins客户端shell命令,『位置变量』的参数以空格隔开。

如:sh build.sh 192.168.1.235 springboot 0.0.1 7011 /home/jenkins/workspace/springboot_dev

$IMG_NAME:$IMG_VERSION这个IMG_VERSION版本(tag)参数不指定默认latest

注意点2:通常情况下Docker是默认执行Dockerfile,但是可以自定义后缀文件进行编译,前提必须要-f(force)强制指定文件进行运行

!/usr/bin/env bash动态变量的【等号】不能有空格和tab键置位,否则获取不了值,而且在shell脚本代码里面不支持空格格式化,支持tab置位格式化。在终端(ssh软件端)或Jenkins客户端shell命令,参数以空格隔开。如:sh build.sh 192.168.1.235 springboot 0.0.1 7011 /home/jenkins/workspace/springboot_devIMG_SERVER="$1"IMG_NAME="$2"IMG_VERSION="$3"IMG_PORT="$4"RUN_EVN="$5"IMG_PATH="$6"echo"服务地址:$IMG_SERVER"echo"工程镜像名称:$IMG_NAME"echo"工程版本号:$IMG_VERSION"echo"工程端口:$IMG_PORT"echo"服务环境:$RUN_EVN"私服访问url路径和编译之后镜像文件存放到指定路径固定,不动态参数进行处理传值.REGISTRY_URL="192.168.1.235:5000"IMG_TAR_GZ_PATH="/home/img_tar_gz_path/"判断动态参数不为空字符串的时候才执行下面操作if ["$IMG_SERVER"!=""] && ["$IMG_NAME"!=""] && ["$IMG_VERSION"!=""] && ["$IMG_PORT"!=""]; thenecho" .......进入删除  Container & Images 操作 ......."清理虚悬镜像,释放磁盘空间docker images|grep none|awk {print $3 }|xargs docker rmi获取容器IDCONTAINER_ID=`docker ps -a | grep $IMG_NAME | awk{ print $1 }`获取镜像IDIMAGE_ID=`docker images | grep $IMG_NAME | awk{ print $3 }`判断是否存在删除开发容器if [["$CONTAINER_ID"!=""]]; thendocker rm -f $CONTAINER_IDfi判断是否存在删除开发镜像if [["$IMAGE_ID"!=""]]; thendocker rmi -f $IMAGE_IDfi$IMG_NAME:$IMG_VERSION 这个IMG_VERSION版本(tag)参数不指定默认latest,通过不同参数执行不同环境文件-f 表示强制指定Dockerfile文件进行编译echo" .......进入Building & Images 操作 ....... "方法1、指定不同文件存放默认的Dockerfile,使用-f进行强制编译docker build -t $IMG_NAME:$IMG_VERSION -f $IMG_PATH"env/"$RUN_EVN/Dockerfile $IMG_PATH方法2、跟据不同Dockerfile文件的后缀进行编译不同环境的文件docker build -t $IMG_NAME:$IMG_VERSION -f $IMG_PATH"env/"Dockerfile_$RUN_EVN $IMG_PATH将镜像打一下标签,然后安照标签进行推送到私服里面,标签名就以服务名即可docker tag $IMG_NAME:$IMG_VERSION $REGISTRY_URL/$IMG_NAME:$IMG_VERSION推镜像到私服里面docker push $REGISTRY_URL/$IMG_NAME:$IMG_VERSION判断是否存在文件夹if [ -d"$IMG_PATH"];thenecho"已经存在:"$IMG_PATHelsemkdir -p $IMG_PATHfi保存编译之后镜像文件存放到指定路径docker save $IMG_NAME -o $IMG_TAR_GZ_PATH/$IMG_NAME.tar.gzecho" .......进入Runing操作 ....."dockerrun-d --network default_network --restart=always --env-file=./.env  -e spring.profiles.active=$RUN_EVN--expose=$IMG_PORT--name=$IMG_NAME-p$IMG_PORT:$IMG_PORT$IMG_NAME:$IMG_VERSIONecho" .......Build & Run Finish Success~...."elseecho" .......Illegal Command Operation ......."fi
4.2.6 Docker (save、load、tag、push,pull)命令使用
  • 其中push,pull一个是推,一个是拉,在某种程度下,都是对在私服上面的镜像进行操作

  • docker save命令是保存编译的tar.gz或tar压缩文件,语法如:

docker save 镜像名 -o 路径/镜像名.tar.gz

docker save 镜像名 -o 路径/镜像名.tar

docker load 命令是用于导入使用docker save命令导出的镜像,此命令非常重要,由于有些客户要求项目工程要求部署在内网,此时这个命令在无网络的内网情况下部署项目的时候就体现它重要的地位了.语法docker load [OPTIONS],在加载的过程有点慢,因为文件有点大,其中显示Loady Layer [======]输出信息,证实镜像是分层关系。

docker load -i /home/img_tar_gz_path/springboot.tar.gz
  • 参数说明

  • docker tagdocker push命令是一起结合使用,先tag后push,每个镜像名和版本是以冒号区分,而docker pull根据情况使用.

将镜像打一下标签,然后安照标签进行推送到私服里面,标签名就以服务名即可docker tag 镜像名:版本号 私服路径/镜像名:版本号推镜像到私服里面docker push私服路径/镜像名:版本号
  • 查看镜像

浏览器验证docker push推送上私服的镜像

4.2.7 虚悬镜像
  • 在docker编译不成功会或者是新版本覆盖旧版本归类为虚悬镜像,生成这个个镜像既没有仓库名,也没有标签,均为。一般来说,虚悬镜像已经失去了存在的价值,是可以随意删除的。

4.2.8 不同环境的配置文件

配置参数

不同环境配置参数内容

server:port: 7011runEvn:开发环境
server:port: 7011runEvn:测试环境
4.2.9 Controller测试代码
@RestControllerpublicclassSimpleController{//读取配置动态参数@Value("${runEvn}")privateString runEvn;@GetMapping("/test")publicStringtest(){return"this spring boot "+ runEvn +" date long "+ System.currentTimeMillis();}}

5、非多台机器免密远程登录&Jenkins部署详解

5.1 特别说明

  • 以开发环境为例子进行说明

  • 开发环境部署目标机器是与Jenkins机器同一台机器,一般情况,Jenkins是单独一台机器,这里为了节省自身电脑内存,故放在同一台机器进行演示与学习。

5.2 新建maven工程

  • 点击Jenkins的新建任务菜单

5.3 参数化构建过程说明

5.3.1添加参数
5.3.2 参数说明以开发环境为案例
5.3.3 源码管理
5.3.4 Build编译设置

表示忽略测试单元类进行编译

clean install -U -Dmaven.test.skip=true

5.4 SSH Publishers设置

  • 其中SSH Server Name就是在http://jenkins地址:端口/jenkins/configure设置好进行选择

  • Transfer Set Source file传输文件的路径,可以使用参数构建的占位符${serverPath}获取

  • Remote directory远程文件目录,同理也参数构建的占位符${serverPath}获取

  • SSH Publishers shell脚本!/bin/bash表示告诉终端使用bash解析器进行执行,而且只有第一行bash才有效。

!/bin/bash创建目录mkdir -p${serverPath}切换目录cd${serverPath}运行脚本sh build.sh$server${appName}${version}${port}${env}${serverPath}

5.5 构建与编译部署项目

  • 截图的构建参数都是在参数化构建过程配置的参数

5.6 构建&运行&&部署结果

  • 构建过程

  • 部署结果

5、多台机器免密远程登录&Jenkins部署流程详解

6.1 特别说明

  • 以测试环境为例子进行说明

  • 步骤流程几乎一样,唯一是在SSH Publishers 和源码存放路径不一样,测试环境部署目标机器是与Jenkins机器不同一台机器

6.2 新建maven工程

  • 点击Jenkins的新建任务菜单

6.3 参数化构建过程说明

6.3.1添加参数
6.3.2 参数说明以测试环境为案例
6.3.3 源码管理
6.3.4 Build编译设置

6.4 SSH Publishers设置

  1. 其中SSH Server Name就是在http://jenkins地址:端口/jenkins/configure设置好进行选择

  2. Transfer Set Source file传输文件的路径,可以使用参数构建的占位符${serverPath}获取

  3. Remote directory远程文件目录,同理也参数构建的占位符${serverPath}获取

  4. docker_server1表示与Jenkins部署同一个宿主机,使用脚本有远程机器shell脚本操作免登陆操作。

  • docker_server1 Shell脚本!/bin/bash表示告诉终端使用bash解析器进行执行,而且只有第一行bash才有效。

!/bin/bash打印信息echo"用户名${userName}"echo"服务器${server}"echo"服务器目录${serverPath}"远程创建存放远程上传的代码目录路径ssh$servermkdir -p${targetServerPath}远程拷贝代码到目标机器指定路径scp -r${serverPath}/${userName}@${server}:${targetServerPath}
  • docker_server2表示要部署那台目标机器,所以它的脚本跟docker_server1不一样.

  • docker_server2 Shell脚本

!/bin/bash切换文件目录cd${serverPath}执行脚本sh build.sh${server}${appName}${version}${port}${env}${serverPath}

6.5 构建与编译部署项目

  • 截图的构建参数都是在参数化构建过程配置的参数

6.6 构建&运行&部署结果

  • 构建过程

  • 部署结果

7、总结&建议&学习

7.1总结与建议

1、此文章仅供提供参考学习指引,如需要系统得学习可以根据自身找资料去学习。

2、以上问题都是根据个人实际学习过程中遇到的问题进行一个一个问题进行梳理与总结整理,除了技术问题查很多网上资料通过进行学习之后整理与分享。

3、在学习过程中也遇到很多困难和疑点,如有问题或误点,望各位老司机多多指出或者提出建议。本人会采纳各种好建议和正确方式不断完善现况,人在成长过程中的需要优质的养料。

4、当遇到问题的时候建议多问『谷歌 、必应、stackoverflow、度娘』这些大神。

5、建议看官方手册更权威,由于随着技术的发展与迭代,通常官方的文档更新较快,国内的网站资料更新较慢。

6、计算机是一门『做中学』的学科,不是会了再去做,而是做了才会。多练,常言道熟能生巧。

7、建议学什么技术『先Know how,再Know Why』,意思就说先入门,搞一个HelloWorld,再深究的意思。

8、希望此文章能帮助你更好了解什么(DevOps)是自动化构建镜像与部署,如何在Docker+Jenkins+GitLab+Maven+SpringBoot&SpringCloud自动构建镜像与部署服务应用,整个学习流程与搭建会有点小曲折,并不会那么顺利,也希望你看了此文章或者通过找资料进行亲身经历学习效果会更好。另外,关注Java知音公众号,回复后端面试,送你一份面试题宝典!

7.2 学习&参考文章

  • https://docs.docker.com/engine/reference/commandline/docker/

  • https://yeasy.gitbooks.io/docker_practice/

  • https://github.com/spotify/docker-maven-plugin

  • https://dmp.fabric8.io/

  • https://github.com/jilongliang/springboot

  • https://cnblogs.com/kakaln/p/7872873.html

  • https://cnblogs.com/lucoo/p/10209892.html

附录

  • jianshu.com/p/dfaaedeb6817

  • jianshu.com/p/299eeef785f0

  • jianshu.com/p/a22577232977

  • jianshu.com/p/e4946edce9a4

  • jianshu.com/p/0bc9b4755082

  • jianshu.com/p/9784d63eff23

  • jianshu.com/p/7827e40aaa71

  • jianshu.com/p/72d05e43a8f3

如果看到这里,说明你喜欢这篇文章,请转发、点赞。同时标星(置顶)本公众号可以第一时间接受到博文推送。

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

本章我们使用Jenkins,结合Maven、Docker、Selenium和JMeter等工具,建立一个可持续交付的自动化设施。

持续交付工作流程

从代码提交开始,建立一个包括自动测试和自动部署的持续交付工作流程如图15-2所示。

这个工作流程的步骤如下所示:

(1)开发者向GitLab提交代码。

(2)GitLab使用 WebHook通知Jenkins有代码更新。

(3)Jenkins 从节点(Slave)拉取代码,打包并构建镜像。

(4)Jenkins使用从节点上构建的镜像运行测试用例。

(5)如果测试(Test)通过,则将镜像推送到镜像仓库。

(6)Jenkins在应用服务器上进行更新部署。

(7)Jenkins将构建报告以邮件方式通知开发者。

在开发者向代码库提交代码之后,整个流程都是自动进行的。如果中间某个环节出现错误,则中止流程的执行,并将结果通知相关人员。提交的代码不仅包括应用程序,还包括构建镜像的脚本、测试用例的脚本和部署的编排脚本等。

其中,各个步骤的操作可以使用插件或直接在命令行中使用各种工具来完成。

例如,拉取项目代码会用到Git插件;打包项目会用到 Maven;构建镜像和应用部署可直接通过命令行使用Docker或docker-compose;集成测试可通过命令行执行由Selenium、JMeter等生成的脚本。

下面,我们通过一个简单的案例,演示和说明Jenkins 的使用方法。

Jenkins的安装

下面的安装过程以MacOS为例进行说明。

因为Jenkins需要JVM的支持,所以请确保机器上已经安装了JDK 1.8或以上版本。为了完成后面的自动化演示,请确保机器中已经安装了Maven、Git客户端和 Docker等。

打开Jenkins官网,进入下载页面,选择左边的LTS稳定版中的Mac OSX版本进行下载,如图15-3所示。

下载完成后,单击安装包jenkins-2.89.1.pkg开始安装。

安装过程比较简单,直接单击继续按钮,按提示使用系统推荐使用的插件即可。安装完成后,通过下列网址打开本地的Jenkins控制台:

http://localhost:8080

第一次打开后会看到如图15-4所示页面。

按图15-4的提示打开管理员密码文件,把密码复制并粘贴到密码输入框中,单击右下角的Continue 按钮。如果密码验证成功,则会提示读者创建一个操作员用户。在创建用户之后,即可登录Jenkins控制台。新用户登录的欢迎界面如图15-5所示。

Jenkins的基本配置

由于要用到Maven编译和打包,所以单击欢迎界面的系统管理→全局工具配置选项,如图15-6所示,打开全局工具配置对话框。

在全局工具配置对话框中单击Maven安装选项,配置一个名字,并设置Maven的安装路径,如图15-7所示。

微服务架构实战:使用Jenkins实现自动化构建

使用Jenkins实现自动化构建