用Google的Jib构建springboot项目docker镜像

Jib

Jib 是google开源的用于对java项目进行容器化打包的工具。主要特点:

Whereas traditionally a Java application is built as a single image layer with the application JAR, Jib’s build strategy separates the Java application into multiple layers for more granular incremental builds. When you change your code, only your changes are rebuilt, not your entire application. These layers, by default, are layered on top of a distroless base image. For more information, check out the official blog post or watch this talk (slides).

传统的java项目打包方式,是将整个java应用相关的资源打包到一个层(layer)。Jib的构建策略是,将java应用的相关资源拆分成多个层(比如:依赖的jar和构建生成的class分层),这样rebuild的时候可以更快,因为可能只需要重新生成部分层的内容。

配置

Jib提供了maven和gradle插件,本文主要介绍 jib-maven-plugin 的使用方法。
将以下内容复制到maven项目的pom.xml中:

1
2
3
4
5
6
7
8
9
10
11
12
13
<plugin>
<groupId>com.google.cloud.tools</groupId>
<artifactId>jib-maven-plugin</artifactId>
<version>0.9.8</version>
<configuration>
<from>
<image>openjdk:8-jre-alpine</image>
</from>
<to>
<image>lf/${project.artifactId}:${project.version}</image>
</to>
</configuration>
</plugin>

说明:

  • from.image 指定使用的带java环境的基础镜像
    • 如上的配置是到registry.hub.docker.com下载,这里选择openjdk8的jre-alpine作为基础镜像
    • 未指定时默认值 gcr.io/distroless/java,这个是在google的服务器上,一般人连不上
    • 如果有内部的registry服务或mirror,可以这样指定:{registry-host}:5000/library/openjdk:8-jre-alpine
  • to.image 指定你要生成的镜像tag,镜像名称是 lf/${project.artifactId}
    • 可以去除”${project.version}”,这样版本默认就是latest

如果from.image使用的registry服务不支持https,需要修改配置如下(使用内部registry mirror服务):

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
<plugin>
<groupId>com.google.cloud.tools</groupId>
<artifactId>jib-maven-plugin</artifactId>
<version>0.9.8</version>
<configuration>
<!-- 允许使用http与registry连接 -->
<allowInsecureRegistries>true</allowInsecureRegistries>
<from>
<image>172.16.14.73:5000/library/openjdk:8-jre-alpine</image>
</from>
<to>
<image>lf/${project.artifactId}</image>
</to>
</configuration>
</plugin>

构建

生成镜像tar

配置好之后,打开shell窗口,执行如下命令即可自动构建生成镜像的tar文件

1
mvn compile jib:buildTar

镜像tar默认生成路径:target\jib-image.tar

自动构建镜像到本地docker

如果你本地装有docker环境,且daemon已启动,那么执行如下命令,可自动将镜像构建到本地的docker daemon

1
mvn compile jib:dockerBuild

注意:docker命令路径需要配置到系统的path目录,否则Jib会找不到

构建镜像并上传registry

如果想构建镜像后自动上传到registry,可以执行如下命令:

1
mvn compile jib:build

由于to.image未指定registry服务器地址,默认将上传到registry.hub.docker.com。

为了上传到内部的registry,需要在to.image上指定registry服务地址,如果服务开启了权限验证,还需要配置上有push权限的账号密码。以下以使用docker官方的registry镜像搭建的服务为例,配置如下

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
<plugin>
<groupId>com.google.cloud.tools</groupId>
<artifactId>jib-maven-plugin</artifactId>
<configuration>
<allowInsecureRegistries>true</allowInsecureRegistries>
<from>
<image>172.16.14.73:5000/library/openjdk:8-jre-alpine</image>
</from>
<!-- 修改的配置 -->
<to>
<image>{registry.mydomain.com}:5000/lf/${project.artifactId}</image>
<auth>
<username>{my_username}</username>
<password>{my_password}</password>
</auth>
</to>
</configuration>
</plugin>

在maven package时自动构建镜像

增加配置如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
<plugin>
<groupId>com.google.cloud.tools</groupId>
<artifactId>jib-maven-plugin</artifactId>
<!-- 增加的配置 -->
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>dockerBuild</goal>
</goals>
</execution>
</executions>
<!-- 之前的配置 -->
<configuration>
......
</configuration>
</plugin>

配置好之后,执行如下命令就会自动构建镜像到本地docker

1
mvn package

配置容器参数

jvm参数

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
<plugin>
<groupId>com.google.cloud.tools</groupId>
<artifactId>jib-maven-plugin</artifactId>
<configuration>
<container>
<jvmFlags>
<jvmFlag>-Xms512m</jvmFlag>
<jvmFlag>-Xmx1024m</jvmFlag>
<jvmFlag>-XX:+UseParNewGC</jvmFlag>
<jvmFlag>-XX:+UseConcMarkSweepGC</jvmFlag>
<jvmFlag>-XX:+DisableExplicitGC</jvmFlag>
<jvmFlag>-Xdebug</jvmFlag>
</jvmFlags>
</container>
<!-- 之前的配置 -->
......
</configuration>
</plugin>

java程序入口mainClass

Jib默认会自动扫描寻找main class,如果你的项目中有多个main class,就需要显示声明:

1
2
3
4
5
6
7
8
9
10
11
<plugin>
<groupId>com.google.cloud.tools</groupId>
<artifactId>jib-maven-plugin</artifactId>
<configuration>
<container>
<mainClass>mypackage.MyApp</mainClass>
</container>
<!-- 之前的配置 -->
......
</configuration>
</plugin>

容器端口 EXPOSE

1
2
3
4
5
6
7
8
9
10
11
12
13
14
<plugin>
<groupId>com.google.cloud.tools</groupId>
<artifactId>jib-maven-plugin</artifactId>
<configuration>
<container>
<ports>
<port>6565</port>
<port>8080</port>
</ports>
</container>
<!-- 之前的配置 -->
......
</configuration>
</plugin>

镜像创建时间

Jib默认不设置镜像创建时间,这样就是1970-01-01。如果要镜像创建时间,则增加配置如下

1
2
3
4
5
6
7
8
9
10
11
<plugin>
<groupId>com.google.cloud.tools</groupId>
<artifactId>jib-maven-plugin</artifactId>
<configuration>
<container>
<useCurrentTimestamp>true</useCurrentTimestamp>
</container>
<!-- 之前的配置 -->
......
</configuration>
</plugin>

镜像格式

构建的镜像默认是Docker格式,还可以指定为OCI格式

1
2
3
4
5
6
7
8
9
10
11
<plugin>
<groupId>com.google.cloud.tools</groupId>
<artifactId>jib-maven-plugin</artifactId>
<configuration>
<container>
<format>OCI</format>
</container>
<!-- 之前的配置 -->
......
</configuration>
</plugin>