前言与初衷

本文章会波及Docker常见命令根底知识点联合不同场景实操一起应用。本文章会波及联合工作过程中部署不同环境服务器的我的项目案例场景为初心进行理论细讲。

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

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

什么是DevOps?

DevOps(Development和Operations的组合词)是一组过程、办法与零碎的统称,用于促成开发(应用程序/软件工程)、技术经营和品质保障(QA)部门之间的沟通、合作与整合,它是一种器重“软件开发人员(Dev)”和“IT运维技术人员(Ops)”之间沟通单干的文化、静止或常规。透过自动化“软件交付”和“架构变更”的流程,来使得构建、测试、公布软件可能更加地快捷、频繁和牢靠。更多对于DevOps的介绍可参阅:超赞!阿里云外部超全K8s/ECS/RDS/OSS/DevOps/DTS实战手册,提供下载!

它的呈现是因为软件行业日益清晰地意识到:为了按时交付软件产品和服务,开发和经营工作必须严密单干。

波及软件环境搭建内容

  • 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。

须要筹备的工作有哪些

工程构造

关上IDEA或Eclipse新建一个SpringBoot的利用.

环境配置特地阐明

注意事项:其中Gitlab、Registry、Jenkins都装置在node1机器下面,也就是node1作为主机(master),node2作为slave(从机或副机),机器名起有意义或能辨别即可,举荐起master和slave,这里就不作过多的论述,为了防止看文章有疑难,请看清单列表.另外,关注民工哥技术之路公众号,回复“Java全栈常识体系”,送你一份40000字超强总结,Java 开发全栈技术常识体系.PDF手册!

SpringBoot配置和代码详解
  • 工程的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>
  • 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> 
  • env环境变量文件

用于设置环境动静参数,文件是以.env为格局

JAVA_OPTS_DEFAULT=-Xmx512m
  • Dockerfile打包工程镜像细讲

以开发环境的Dockerfile为例,如果是测试环境则,把所有门路蕴含springboot_dev改成springboot_test。

FROM frolvlad/alpine-oraclejdk8:slimMAINTAINER jilongliang@sina.comRUN ln -sf /usr/share/zoneinfo/Asia/Shanghai /etc/localtimeRUN mkdir -p /home/devsoft/springboot_devWORKDIR /home/devsoft/springboot_devEXPOSE 7011ADD ./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

  • 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
  • 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推送上私服的镜像

  • 虚悬镜像

在docker编译不胜利会或者是新版本笼罩旧版本归类为虚悬镜像,生成这个个镜像既没有仓库名,也没有标签,均为 <none>。一般来说,虚悬镜像曾经失去了存在的价值,是能够随便删除的。另外,关注民工哥技术之路公众号,回复“Java全栈常识体系”,送你一份40000字超强总结,Java 开发全栈技术常识体系.PDF手册!

  • 不同环境的配置文件

配置参数

不同环境配置参数内容

server:  port: 7011runEvn: '开发环境'server:  port: 7011runEvn: '测试环境'4.2.9 Controller测试代码@RestControllerpublic class SimpleController {   //读取配置动静参数    @Value("${runEvn}")    private String runEvn;        @GetMapping("/test")    public String test() {        return "this spring boot " + runEvn +" date long "        + System.currentTimeMillis();    }}

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

特地阐明

以开发环境为例子进行阐明:开发环境部署指标机器是与Jenkins机器同一台机器,个别状况,Jenkins是独自一台机器,这里为了节俭本身电脑内存,故放在同一台机器进行演示与学习。

新建maven工程

点击Jenkins的新建工作菜单

参数化构建过程阐明
  • 增加参数

  • 参数阐明以开发环境为案例

  • 源码治理

  • Build编译设置

示意疏忽测试单元类进行编译

clean install -U -Dmaven.test.skip=true
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}
    构建与编译部署我的项目

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

构建&运行&&部署后果
  • 构建过程

  • 部署后果

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

特地阐明

以测试环境为例子进行阐明:步骤流程简直一样,惟一是在SSH Publishers 和源码寄存门路不一样,测试环境部署指标机器是与Jenkins机器不同一台机器。

新建maven工程

点击Jenkins的新建工作菜单

参数化构建过程阐明
  • 增加参数

  • 参数阐明以测试环境为案例

  • 源码治理

  • Build编译设置

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}
构建与编译部署我的项目

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

构建&运行&部署后果
  • 构建过程

  • 部署后果

总结&倡议

1、此文章仅供提供参考学习指引,如须要零碎得学习能够依据本身找材料去学习。

2、以上问题都是依据集体理论学习过程中遇到的问题进行一个一个问题进行梳理与总结整顿,除了技术问题查很多网上材料通过进行学习之后整顿与分享。

3、在学习过程中也遇到很多艰难和疑点,如有问题或正点,望各位老司机多多指出或者提出倡议。自己会驳回各种好倡议和正确形式不断完善现况,人在成长过程中的须要优质的养料。

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

5、倡议看官网手册更权威,因为随着技术的倒退与迭代,通常官网的文档更新较快,国内的网站材料更新较慢。

6、计算机是一门『做中学』的学科,不是会了再去做,而是做了才会。多练,常言道游刃有余。

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

8、心愿此文章能帮忙你更好理解什么(DevOps)是自动化构建镜像与部署,如何在Docker+Jenkins+GitLab+Maven+SpringBoot&SpringCloud主动构建镜像与部署服务利用,整个学习流程与搭建会有点小波折,并不会那么顺利,也心愿你看了此文章或者通过找材料进行亲身经历学习效果会更好。

作者:寅务 链接:jianshu.com/p/bdb0642b7495