SpringCloud+Docker+Jenkins+GitLab+Maven实现自动化构建与部署实战
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配置
- SpringBoot和Docker依赖的jar配置
<dependencies>
<!-- Springboot依赖的Jar包 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!-- Springboot热部署jar-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<scope>runtime</scope>
<optional>true</optional>
</dependency>
<!--yml配置文件提示插件-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-configuration-processor</artifactId>
<optional>true</optional>
</dependency>
<!-- spring-boot测试jar -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<finalName>springboot</finalName>
<!-- 一定要声明如下配置 打包xml 到Jar包 -->
<!-- <resources>
<resource>
<directory>src/main/java</directory>
是否替换资源中的属性
<filtering>false</filtering>
</resource>
</resources>
<sourceDirectory>${project.basedir}/src/main/java</sourceDirectory>
-->
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<!-- 默认支持jdk1.8编译 -->
<configuration>
<source>1.8</source>
<target>1.8</target>
</configuration>
</plugin>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<executions>
<execution>
<goals>
<goal>repackage</goal>
</goals>
</execution>
</executions>
</plugin>
<!--docke rmaven编译插件-->
<plugin>
<groupId>com.spotify</groupId>
<artifactId>docker-maven-plugin</artifactId>
<version>0.4.12</version>
<configuration>
<dockerDirectory>${project.basedir}</dockerDirectory>
<resources>
<resource>
<targetPath>/</targetPath>
<directory>${project.build.directory}</directory>
<include>${project.build.finalName}.jar</include>
</resource>
</resources>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<configuration>
<archive>
<manifest>
<mainClass>com.flong.SpringbootApplication</mainClass>
</manifest>
</archive>
</configuration>
</plugin>
</plugins>
</build>
4.2.2 no main manifest attribute错误解决
- 配置工程主入口
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<configuration>
<archive>
<manifest>
<mainClass>com.flong.SpringbootApplication</mainClass>
</manifest>
</archive>
</configuration>
</plugin>
4.2.3 env环境变量文件
- 用于设置环境动态参数,文件是以.env为格式
JAVA_OPTS_DEFAULT=-Xmx512m
4.2.4 Dockerfile打包工程镜像细讲
- 以开发环境的Dockerfile为例,如果是测试环境则,把所有路径包含springboot_dev改成springboot_test
FROM frolvlad/alpine-oraclejdk8:slim
MAINTAINER jilongliang@sina.com
RUN ln -sf /usr/share/zoneinfo/Asia/Shanghai /etc/localtime
RUN mkdir -p /home/devsoft/springboot_dev
WORKDIR /home/devsoft/springboot_dev
EXPOSE 7011
ADD ./target/springboot.jar ./
CMD java ${JAVA_OPTS_DEFAULT} -Djava.security.egd=file:/dev/./urandom -jar springboot.jar
- 参数说明
- WORKDIR 工作目录说明进入容器此时会有一个.jar是在Dockerfile的ADD添加进去
docker exec -it 容器名称或容器id /bin/sh
或要使用sh和bash要看COMMAND,-it
docker exec -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_dev
IMG_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" != "" ]; then
echo " .......进入删除 Container & Images 操作 ......."
# 清理虚悬镜像,释放磁盘空间
#docker images|grep none|awk '{print $3 }'|xargs docker rmi
# 获取容器ID
CONTAINER_ID=`docker ps -a | grep $IMG_NAME | awk '{ print $1 }'`
# 获取镜像ID
IMAGE_ID=`docker images | grep $IMG_NAME | awk '{ print $3 }'`
# 判断是否存在删除开发容器
if [[ "$CONTAINER_ID" != "" ]]; then
docker rm -f $CONTAINER_ID
fi
# 判断是否存在删除开发镜像
if [[ "$IMAGE_ID" != "" ]]; then
docker rmi -f $IMAGE_ID
fi
# $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" ];then
echo "已经存在:"$IMG_PATH
else
mkdir -p $IMG_PATH
fi
# 保存编译之后镜像文件存放到指定路径
docker save $IMG_NAME -o $IMG_TAR_GZ_PATH/$IMG_NAME.tar.gz
echo " .......进入Runing操作 ....."
docker run -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_VERSION
echo " .......Build & Run Finish Success~...."
else
echo " .......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 tag
和docker push
命令是一起结合使用,先tag后push,每个镜像名和版本是以冒号区分,而docker pull根据情况使用.
# 将镜像打一下标签,然后安照标签进行推送到私服里面,标签名就以服务名即可
docker tag 镜像名:版本号 私服路径/镜像名:版本号
# 推镜像到私服里面
docker push私服路径/镜像名:版本号
- 查看镜像
浏览器验证docker push推送上私服的镜像
4.2.7 虚悬镜像
- 在docker编译不成功会或者是新版本覆盖旧版本归类为虚悬镜像,生成这个个镜像既没有仓库名,也没有标签,均为
<none>
。一般来说,虚悬镜像已经失去了存在的价值,是可以随意删除的。
4.2.8 不同环境的配置文件
配置参数
不同环境配置参数内容
server:
port: 7011
runEvn: '开发环境'
server:
port: 7011
runEvn: '测试环境'
4.2.9 Controller测试代码
@RestController
public class SimpleController {
//读取配置动态参数
@Value("${runEvn}")
private String runEvn;
@GetMapping("/test")
public String test() {
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设置
- 其中SSH Server Name就是在
http://jenkins地址:端口/jenkins/configure
设置好进行选择 - Transfer Set Source file传输文件的路径,可以使用参数构建的占位符
${serverPath}
获取 - Remote directory远程文件目录,同理也参数构建的占位符
${serverPath}
获取 - docker_server1表示与Jenkins部署同一个宿主机,使用脚本有远程机器shell脚本操作免登陆操作。
- docker_server1 Shell脚本
#!/bin/bash
表示告诉终端使用bash解析器进行执行,而且只有第一行bash才有效。
#!/bin/bash
# 打印信息
echo "用户名${userName}"
echo "服务器${server}"
echo "服务器目录${serverPath}"
# 远程创建存放远程上传的代码目录路径
ssh $server mkdir -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自动构建镜像与部署服务应用,整个学习流程与搭建会有点小曲折,并不会那么顺利,也希望你看了此文章或者通过找资料进行亲身经历学习效果会更好。
SpringCloud+Docker+Jenkins+GitLab+Maven实现自动化构建与部署实战的更多相关文章
- 使用Docker搭建Jenkins+Docker持续集成环境(自动化构建发布部署)
本文介绍如何通过Jenkins的docker镜像从零开始构建一个基于docker镜像的持续集成环境,包含自动化构建.发布到仓库\并部署上线. 0. 前置条件 服务器安装docker,并启动docker ...
- Jenkins+Git+Maven搭建自动化构建平台
http://blog.csdn.net/xlgen157387/article/details/50353317
- SpringCloud微服务实战——搭建企业级开发框架(三十四):SpringCloud + Docker + k8s实现微服务集群打包部署-Maven打包配置
SpringCloud微服务包含多个SpringBoot可运行的应用程序,在单应用程序下,版本发布时的打包部署还相对简单,当有多个应用程序的微服务发布部署时,原先的单应用程序部署方式就会显得复杂且 ...
- 解放双手 | Jenkins + gitlab + maven 自动打包部署项目
前言 记录 Jenkins + gitlab + maven 自动打包部署后端项目详细过程! 需求背景 不会偷懒的程序员不是好码农,传统的项目部署,有时候采用本地手动打包,再通过ssh传到服务器部署运 ...
- jenkins+git+maven搭建自动化部署项目环境
简介 折腾了两个晚上,趁着今晚比较有空,把jenkins+git+maven搭建自动化部署项目环境搭建的过程记录一下,这里我把github作为git的远程仓库(https://github.co ...
- jenkins+Gitlab+maven+tomcat实现自动集成、打包、部署
一.前言 首先出于提高自己技术水平和琢磨能做点什么能提高工作效率,上线工作实在无聊.重复(手动编译.打包,传包,重启),于是就想到了jenkins,jenkins持续集成已经不是什么新鲜的话题,网上文 ...
- Jenkins+SVN+Maven+shell 自动化部署实践
JAVA环境中利用Jenkins+svn+maven进行自动化部署实践 一. 前言2 1.介绍jenkins2 1.本地项目打包2 2.通过secureCRT工具,手动传输到服务器2 3.然后 ...
- 基于 Docker 和 GitLab 的前端自动化部署实践笔记
基于 Docker 和 GitLab 的前端自动化部署 实践笔记 随着接触的项目越来越多,在部署测试流程上重复耗时工作也越来越多,所以对前端工作的CI/CD实现愈发迫在眉睫. 前端开发由于三大框架的崛 ...
- 边缘化搭建 DotNet Core 2.1 自动化构建和部署环境(上)
写在前面 写这篇文章的缘由是由于笔者的对新兴技术方向有所追求,但个人资产有限,只能容许购买一台阿里云低配1核2G服务器.服务器上搭建了 Centos7 & Docker & Jenki ...
随机推荐
- IO系列测试源码
//IO系列测试源码(需要自取) using System; using System.CodeDom; using System.Collections.Generic; using System. ...
- 浅谈Java的诞生和现状
昨天在旅途中登录一下很久没用的boss直聘,看看行情,一天的时间,已经有20+家公司给我发出了面试邀请,先跟大家谈谈Java的诞生和现状. 传说,在二十世纪90年代,一个叫Sun的公司,成立了一个项目 ...
- [敏杰开发]Beta阶段测试报告
[敏杰开发]Beta阶段测试报告 这是一篇软工课程博客 项目 内容 课程:北航-2020-春-软件工程 博客园班级博客 作业要求 Beta阶段测试报告 我们在这个课程的目标是 测试项目 这个作业在哪个 ...
- 30.Stream流
5.Stream流 5.1体验Stream流[理解] 案例需求 按照下面的要求完成集合的创建和遍历 创建一个集合,存储多个字符串元素 把集合中所有以"张"开头的元素存储到一个新的集 ...
- [Java]数据分析--聚类
距离度量 需求:计算两点间的欧几里得距离.曼哈顿距离.切比雪夫距离.堪培拉距离 实现:利用commons.math3库相应函数 1 import org.apache.commons.math3.ml ...
- 列出系统上的存储库,状态是enabled [root@blog ~]# dnf repolist
DNF 和 YUM 均是 rpm 软件包管理工具,但是 DFN 替代 YUM 的说法由来已久,因为 YUM 包管理工具有一些问题长期得不到解决. 这些问题包括性能低下.内存占用高以及依赖包解决方案不佳 ...
- Linux 系统定时任务:crontab,anacron
Linux 系统定时任务:crontab,anacron 一.Cron 服务 1. 启动服务 service cron start 2. 关闭服务 service cron stop 3. 重启服务 ...
- 使用chrony安装chrony
yum install chrony -y 使用chrony安装chrony 使用root用户登录~]# yum install chrony 默认的chrony进程位置/usr/sbin/c ...
- 6.2 gzip:压缩或解压文件
gzip命令 用于将一个大的文件通过压缩算法(Lempel-Ziv coding(LZ77))变成一个小的文件.gzip命令不能直接压缩目录,因此目录需要先用tar打包成一个文件,然后tar再调用gz ...
- Linux 系统日志和系统信息常用命令介绍
日志文件 日 志 文 件 说 明 /var/log/message 系统启动后的信息和错误日志,是Red Hat Linux中最常用的日志之一 /var/log/secure 与安全相关的日志信息 / ...