0%

jib 更快的构建java容器镜像

简介

Jib 是 Google 开发的可以直接构建 Java 应用的 Docker 和 OCI 镜像的类库,以 Maven 和 Gradle 插件形式提供。

通过 Jib,Java 开发者可以使用他们熟悉的 Java 工具来构建容器。Jib 是一个快速而简单的容器镜像构建工具,它负责处理将应用程序打包到容器镜像中所需的所有步骤。它不需要你编写 Dockerfile 或安装 Docker,而且可以直接集成到 Maven 和 Gradle中 —— 只需要将插件添加到构建中,就可以立即将 Java 应用程序容器化。

构建

docker打包流程

docker设计缺陷

  • docker架构CS设计存在缺陷,打包镜像时候会存在额外开销,会把dockerfile同级目录下不需要的文件copy给docker deamon,我们生产实际存在过node应用打包,缓存很多残留文件在dockerfile同级的目录下,导致整个copy过程很慢。
  • 传统springBoot打包没有办法最大利用镜像分层缓存技术,即使开发只改动一行代码,但是镜像层缓存的还是整个应用的bootJar,这个在镜像下载和推送的时候也是一个开销。

jib打包

jib打包不需要docker deamon,基于gradle插件一行命令就能打包生成镜像,并推送镜像到镜像仓库。而且打包产生的文件jar、class、resouces是分离的。这样docker镜像分层更细致,这样改动文件越少传输越快。
打包命令:

 gradle jib \
     -Djib.from.image=${jibFromImage} \
     -Djib.to.image=${harborUrl}/library/${appName}:${tag} \
     -Djib.container.entrypoint='java','-server','-cp','/app/resources:/app/classes:/app/libs/*',${jibContainerMainClass},'-agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=0.0.0.0:1088'
                              

通过实际业务应该改造后,可以实现如果只改动几个类,单次打包可以从3分钟缩短到30秒内。

踩坑

  1. gradle要升级到5以上,gradle升级后会有一些插件不支持,需要手动修改。

比如:
lommbok插件引入改造,需要改为:

    compileOnly 'org.projectlombok:lombok'
    annotationProcessor 'org.projectlombok:lombok'
    testCompileOnly 'org.projectlombok:lombok'
    testAnnotationProcessor 'org.projectlombok:lombok'   
    

sonar插件升级:

 org.sonarsource.scanner.gradle:sonarqube-gradle-plugin:2.5   
 升级到3.0(org.sonarsource.scanner.gradle:sonarqube-gradle-plugin:3.0)
 

2.有些应用改造后原来的jar包冲突会暴露出来,需要gradle dependencies去分析依赖

3.运来dockerfile 的ENTRYPOINT中传入的环境变量读取不了,比如原先我们采用的是:

java $JAVA_OPS -jar /root/deploy/$appname.jar --spring.profiles.active=$SPRING_ENV --spring.cloud.config.uri=$CONFIG_SERVER

命令来启动java容器,jvm启动参数$JAVA_OPS设置到环境变量中。但是接入jib,$JAVA_OPS等环境变量是读取不了的,会被当做字符串运行在命令中,官网给的解决方案是运用JAVA_TOOL_OPTIONS环境变量来配置启动参数,但是要注意,JAVA_TOOL_OPTIONS会导致每一个启动在容器中的java进程都会读取该jvm参数,可能会导致后面的jvm进程启动冲突而启动不起来,这时候可以在容器内执行shell前先unset JAVA_TOOL_OPTIONS该环境变量,unset只会存在当前登录窗口的生命周期