快捷制定基于spring boot项目的应用镜像

119 阅读2分钟

在我们springboot项目容器化改造过程中,调研制作镜像的方式多有以下几种,

  • 研发同学自己写dockerfile(包含使用dockerfle-maven-plugin的情况),这种情况下缺点是把整个jar包作为镜像单独层,无法充分利用镜像的分层机制共享基础层,而且研发同学需要了解部分容器知识,相当于把问题乘以研发人数.
  • 使用 spring-boot-maven-plugin 内置的 build-image.这个情况需要使用Buildpacks, 解决方案比较全面,这里不再阐述,不过需要一些gcr.io的一些镜像,国内使用不方便.
  • 使用 Google 的 jib-maven-plugin,这个方案针对研发同学友好,同时充分利用镜像层共享机制,不过,在我们使用过程发现,此方案生成的镜像启动类加载顺序和spring boot原生方式加载顺序不一致,一些情况下会报异常,虽然是开发规范问题,但是因为问题难以定位且应用数量众多,还是得依靠调整构建流程解决.

附带一份容器镜像制作工具比较表

这里我们分享另一种基于spirngboot layertoolsbuildah的快速制作镜像的一种实现方式.以下为脚本信息

#!/usr/bin/env bash
set -ex
# 构建项目并打印项目依赖
mvn -e -B -U -DskipTests -pl=./ clean dependency:tree package

# 清理构建遗留目录和文件
rm -rf target/dependencies/ target/spring-boot-loader/ target/snapshot-dependencies/ target/application/ target/Dockerfile target/idfile.txt target/idfile.txt

#使用springboot,自带解压工具解压jar包
java -Duser.dir=$(realpath target) -Djarmode=layertools -jar $(realpath $(find target/*.jar)) extract

#处理文件时间,以便共享镜像基础层,此处时间会影响镜像层内容.
find target/dependencies/ -exec touch -t 197001010000.00 {} ;
find target/spring-boot-loader/ -exec touch -t 197001010000.00 {} ;
find target/snapshot-dependencies/ -exec touch -t 197001010000.00 {} ;
find target/application/ -exec touch -t 197001010000.00 {} ;

#生成dockerfile
cat <<EOF >target/Dockerfile
FROM repo.dstealer.com:18080/library/jre-8u202-alpine:20221017
COPY dependencies/ /app
COPY spring-boot-loader/ /app
COPY snapshot-dependencies/ /app
COPY application/ /app
WORKDIR /app
CMD ["tini", "--", "java", "org.springframework.boot.loader.JarLauncher"]
EOF

#生成镜像标签
IMAGE_TAG=repo.dstealer.com:18080/library/$(mvn help:evaluate -Dexpression=project.artifactId -q -DforceStdout):$(mvn help:evaluate -Dexpression=project.version -q -DforceStdout)-$(TZ='Asia/Shanghai' date +'%y%m%d%H%M%S')

#生成镜像,此处可以考虑用附带git信息作为镜像label,方便辨别镜像
buildah build --iidfile=target/idfile.txt target

#推送镜像
buildah push --rm --digestfile=target/digestfile $(cat target/idfile.txt) docker://$IMAGE_TAG

#保存已推送的仓库信息
cat $IMAGE_TAG@$(cat target/digestfile) > target/digestfile

#清理本地镜像
buildah rmi $(cat target/idfile.txt)

参考:

docs.spring.io/spring-boot…