写点什么

GitLab CI 构建 SpringBoot-2,rabbitmq 原理及作用

作者:Java高工P7
  • 2021 年 11 月 09 日
  • 本文字数:3208 字

    阅读完需:约 11 分钟

<name>dockerlayerdemo</name>


<description>Demo project for Spring Boot layer docker image</description>


<properties>


<java.version>1.8</java.version>


</properties>


<dependencies>


<dependency>


<groupId>org.springframework.boot</groupId>


<artifactId>spring-boot-starter-web</artifactId>


</dependency>


<dependency>


<groupId>org.springframework.boot</groupId>


<artifactId>spring-boot-starter-test</artifactId>


<scope>test</scope>


<exclusions>


<exclusion>


<groupId>org.junit.vintage</groupId>


<artifactId>junit-vintage-engine</artifactId>


</exclusion>


</exclusions>


</dependency>


</dependencies>


<build>


<plugins>


<plugin>


<groupId>org.springframework.boot</groupId>


<artifactId>spring-boot-maven-plugin</artifactId>


<version>2.3.0.RELEASE</version>


<configuration>


<layers>


<enabled>true</enabled>


</layers>


</configuration>


</plugin>


</plugins>


</build>


</project>


  1. java 代码并非重点,在 application 类中加了个 http 接口:


package com.bolingcavalry.dockerlayerdemo;


import org.springframework.boot.SpringApplication;


import org.springframework.boot.autoconfigure.SpringBootApplication;


import org.springframework.web.bind.annotation.RequestMapping;


import org.springframework.web.bind.annotation.RestController;


import java.util.Date;


@SpringBootApplication


@RestController


public class DockerlayerdemoApplication {


public static void main(String[] args) {


SpringApplication.run(DockerlayerdemoApplication.class, args);


}


@RequestMapping(value = "/hello")


public String hello(){


return "hello " + new Date();


}


}


  1. pom.xml 所在目录增加文件夹.m2,里面放入 settings.xml,这是 maven 的配置文件,可以设置您的特殊的 maven 信息;

  2. pom.xml 所在目录增加 Dockerfile 文件,用于制作镜像:

指定基础镜像,这是分阶段构建的前期阶段

FROM openjdk:8u212-jdk-stretch as builder

执行工作目录

WORKDIR application

配置参数

ARG JAR_FILE=target/*.jar

将编译构建得到的 jar 文件复制到镜像空间中

COPY ${JAR_FILE} application.jar

通过工具 spring-boot-jarmode-layertools 从 application.jar 中提取拆分后的构建结果

RUN java -Djarmode=layertools -jar application.jar extract

正式构建镜像

FROM openjdk:8u212-jdk-stretch


WORKDIR application

前一阶段从 jar 中提取除了多个文件,这里分别执行 COPY 命令复制到镜像空间中,每次 COPY 都是一个 layer

COPY --from=builder application/dependencies/ ./


COPY --from=builder application/spring-boot-loader/ ./


COPY --from=builder application/snapshot-dependencies/ ./


COPY --from=builder application/application/ ./


ENTRYPOINT ["java", "org.springframework.boot.loader.JarLauncher"]


  1. pom.xml 所在目录增加.gitlab-ci.yml 文件,这就是 CI 时的 pipeline 脚本:


image: maven:3.6.3-jdk-8


variables:


MAVEN_CLI_OPTS: "-s .m2/settings.xml --batch-mode"


MAVEN_OPTS: "-Dmaven.repo.local=.m2/repository"

定义缓存

如果 gitlab runner 是 shell 或者 docker,此缓存功能没有问题

如果是 k8s 环境,要确保已经设置了分布式文件服务作为缓存

cache:


key: dockerlayerdemo-ci-cache


paths:


  • .m2/repository/

  • target/*.jar

本次构建的阶段:build package

stages:


  • package

  • build

生产 jar 的 job

make_jar:


image: maven:3.6.3-jdk-8


stage: package


tags:


  • k8s


script:


  • echo "=============== 开始编译源码,在 target 目录生成 jar 文件 =======


《Android学习笔记总结+最新移动架构视频+大厂安卓面试真题+项目实战源码讲义》
浏览器打开:qq.cn.hn/FTe 免费领取
复制代码


========"


  • mvn $MAVEN_CLI_OPTS clean compile package -Dmaven.test.skip=true

  • echo "target 文件夹" ls target/

生产镜像的 job

make_image:


image: docker:latest


stage: build


tags:


  • k8s


script:


  • echo "从缓存中恢复的 target 文件夹" ls target/

  • echo "=============== 登录 Harbor ==============="

  • docker login 192.168.50.43:5888 -u admin -p Harbor12345

  • echo "=============== 打包 Docker 镜像 : " gitlabci-java-demo:$CI_COMMIT_SHORT_SHA "==============="

  • docker build -t 192.168.50.43:5888/common/gitlabci-java-demo:$CI_COMMIT_SHORT_SHA .

  • echo "=============== 推送到镜像仓库 ==============="

  • docker push 192.168.50.43:5888/common/gitlabci-java-demo:$CI_COMMIT_SHORT_SHA

  • echo "=============== 登出 ==============="

  • docker logout

  • echo "清理掉本次构建的 jar 文件"

  • rm -rf target/*.jar


关于以上 pipeline 脚本,有下面五点需要注意:


第一:关于 cache,如果您的 gitlab runner 是 shell 或者 docker 类型就无需关注,cache 是直接生效的,但如果您的 gitlab runner 是 K8S 那就要注意了,需要在 gitlab runner 中填写 cache 相关的配置,让分布式文件服务作为 cache 的底层实现;


第二:一共定义了两个 stage:package 和 build,顺序是先 package 再 build,注意生成 jar 的 job 一定要是 package,使用 jar 构建镜像的 job 要是 build,这样在构建镜像的时候才能顺利从缓存中取得 jar;


第三:make_image 这个 job 的脚本中,会执行登录私有镜像仓库的操作,为了操作方便,登录的账号密码都是直接写在脚本里面的,实际使用时请不要这样做,建议使用 Harbor 的机器人账号密码,并且写入 GitLab CI 的环境变量配置页面,而不是直接写在 pipeline 脚本中


第四:tags 参数用来和已有的 GitLab Runner 匹配,请按照您自己的 runner 的情况设置;


第五:生成 docker 镜像的 tag 等于 $CI_COMMIT_SHORT_SHA,这是本次提交的 commit id,因此,每次提交都会导致镜像仓库中多一个镜像,其 tag 等于 commit id;


  1. 最终整个工程的内容如下:



至此,所有开发工作已经完成,接下来验证执行情况;

验证 CI

  1. 将所有内容提交到 GitLab,如果 CI 环境配置 OK 的话会立即触发构建,下图是构建成功的效果:



  1. 先来看 make_jar 的执行情况,如下图,SpringBoot 工程成功构建出 jar 文件:



  1. 再看 make_image 执行情况,如下图:



  1. 镜像制作成功后,开始推送到 harbor:



  1. 最终完成推送,并且清理残留文件:



  1. 最后看看 pipeline 的整体情况,如下图:



  1. 从上图可知 commit id 是 02307851,因此 Harbor 中应该有 tag 等于 02307851 的镜像,登录 Harbor 查看,如下图红框:


在 K8S 环境验证

接下来要在 K8S 环境验证之前的镜像可以正常运行:


  1. SSH 登录 K8S 环境,执行以下命令,用最新的镜像创建 deployment:


kubectl create deployment dockerlayerdemo \


--image=192.168.50.43:5888/common/gitlabci-java-demo:02307851


  1. 执行以下命令创建 NodePort 类型的 service:


kubectl create service nodeport \


dockerlayerdemo --tcp 8080:8080


  1. 浏览器访问 http://192.168.50.135:31685/hello ,其中 192.168.50.135 是 K8S 宿主机的 IP 地址,如下图,可以正常访问 SpringBoot 服务:


GitLab CI 的价值

文章看到这里,咱们 pipeline 脚本也写了,镜像有了,K8S 上部署的服务也验证了,这就结束了吗?


—还没有,咱们来感受一下从修改代码到 K8S 环境上生效的流程:


  1. 修改 java 代码,如下图:



  1. 提交代码:



  1. 顺利生成镜像:



  1. 在 K8S 环境执行以下命令即可完成镜像更新:


kubectl set image deployment dockerlayerdemo \


gitlabci-java-demo=192.168.50.43:5888/common/gitlabci-java-demo:8735c78d


  1. 上述命令中的 gitlabci-java-demo 来自 kubectl describe deployment dockerlayerdemo 结果中,显示的容器名称,如下图红框:



  1. 系统提示更新成功:



  1. 再次用浏览器访问相同的地址,如下图红框,修改的代码已经生效:



可见借助 GitLab CI,编码到部署之间的过程已被简化,可以更加专注的撸码了;

体验 CD?

除了持续集成(CI),还可以把持续部署(CD)也加入到 pipeline 脚本中,这样我们只需提交代码,对应的镜像会被自动部署到 K8S 环境;


  1. 打开.gitlab-ci.yml,增加一个 stage 定义 deploy,如下所示,现在一共有三个 stage 了:


stages:

用户头像

Java高工P7

关注

还未添加个人签名 2021.11.08 加入

还未添加个人简介

评论

发布
暂无评论
GitLab CI构建SpringBoot-2,rabbitmq原理及作用