1

Jib使用小结(Maven插件版)

 1 year ago
source link: https://blog.51cto.com/zq2599/5754918
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

欢迎访问我的GitHub

这里分类和汇总了欣宸的全部原创(含配套源码): https://github.com/zq2599/blog_demos

  • 近期在用Jib插件将Java工程构建成Docker镜像,使用时遇到过一些小问题,今天对这些问题做个小结;

关于Jib插件

  • Jib是用于构建Docker镜像的Maven插件,其基本用法请参考《Docker与Jib(maven插件版)实战》;
  • 本文由以下几部分组成:
  1. 小结一:三种构建参数
  2. 小结二:镜像的时间问题
  3. 小结三:多次构建后,积累的无用镜像问题
  4. 小结四:提升构建速度
  5. 小结五:将jib与mvn构建的生命周期绑定
  6. 小结六:父子结构的maven工程如何构建
  1. 操作系统:CentOS Linux release 7.6.1810
  2. docker:1.13.1
  3. jdk:1.8.0_191
  4. maven:3.6.0
  5. jib插件:1.3.0
  • 本次实战用到的源码是个简单的maven工程,可以从GitHub上下载本次实战的源码,地址和链接信息如下表所示:
名称 链接 备注
项目主页  https://github.com/zq2599/blog_demos 该项目在GitHub上的主页
git仓库地址(https)  https://github.com/zq2599/blog_demos.git 该项目源码的仓库地址,https协议
git仓库地址(ssh)  [email protected]:zq2599/blog_demos.git 该项目源码的仓库地址,ssh协议
  • 这个git项目中有多个文件夹,本章的源码在hellojib文件夹下,如下图红框所示:
    Jib使用小结(Maven插件版)_kubernetes

小结一:三种构建参数

  • 对于一个已在pom.xml中配置了jib插件的java工程来说,下面是个标准的构建命令:
mvn compile jib:dockerBuild
  • 注意上面的 dockerBuild 参数,该参数的意思是将镜像存入当前的镜像仓库,这样的参数一共有三种,列表说明:
    | 参数名 | 作用 |
    |–|–|
    | dockerBuild | 将镜像存入当前镜像仓库,该仓库是当前docker客户端可以连接的docker daemon,一般是指本地镜像仓库 |
    | build | 将镜像推送到远程仓库,仓库位置与镜像名字的前缀有关,一般是hub.docker.com,使用该参数时需要提前登录成功 |
    | buildTar | 将镜像生成tar文件,保存在项目的target目录下,在任何docker环境执行 docker load --input xxx.tar即可导入到本地镜像仓库 |

小结二:镜像的时间问题

  • 在使用命令 mvn compile jib:dockerBuild 构建本地镜像时,会遇到创建时间不准的问题:
  • 如下所示, bolingcavalry/hellojib 是刚刚使用jib插件构建的镜像,其生成时间(CREATED字段)显示的是 49 years ago
[root@maven hellojib]# docker images
REPOSITORY               TAG                 IMAGE ID            CREATED             SIZE
bolingcavalry/hellojib   0.0.1-SNAPSHOT      ef96fdd4473a        49 years ago        505 MB
  • 上面显示的镜像生成时间显然是不对的,改正此问题的方法是修改pom.xml,在jib插件的container节点内增加 useCurrentTimestamp 节点,内容是true,如下所示:
<plugin>
                <groupId>com.google.cloud.tools</groupId>
                <artifactId>jib-maven-plugin</artifactId>
                <version>1.3.0</version>
                <configuration>
                    <!--from节点用来设置镜像的基础镜像,相当于Docerkfile中的FROM关键字-->
                    <from>
                        <!--使用openjdk官方镜像,tag是8-jdk-stretch,表示镜像的操作系统是debian9,装好了jdk8-->
                        <image>openjdk:8u212-jdk-stretch</image>
                    </from>
                    <to>
                        <!--镜像名称和tag,使用了mvn内置变量${project.version},表示当前工程的version-->
                        <image>bolingcavalry/hellojib:${project.version}</image>
                    </to>
                    <!--容器相关的属性-->
                    <container>
                        <!--jvm内存参数-->
                        <jvmFlags>
                            <jvmFlag>-Xms4g</jvmFlag>
                            <jvmFlag>-Xmx4g</jvmFlag>
                        </jvmFlags>
                        <!--要暴露的端口-->
                        <ports>
                            <port>8080</port>
                        </ports>
                        <!--使用该参数将镜像的创建时间与系统时间对其-->
                        <useCurrentTimestamp>true</useCurrentTimestamp>
                    </container>
                </configuration>
            </plugin>

  • 修改保存后再次构建,此时新的镜像的创建时间已经正确,显示 15 seconds ago
[root@maven hellojib]# docker images
REPOSITORY               TAG                 IMAGE ID            CREATED             SIZE
bolingcavalry/hellojib   0.0.1-SNAPSHOT      ee5ba19a8016        23 seconds ago      505 MB
<none>                   <none>              ef96fdd4473a        49 years ago        505 MB

小结三:多次构建后,积累的无用镜像

  • 如下所示,构建多次后,本地会遗留多个名为<none>,tag也是<none>的镜像:
[root@maven hellojib]# docker images
REPOSITORY               TAG                 IMAGE ID            CREATED              SIZE
bolingcavalry/hellojib   0.0.1-SNAPSHOT      a9fd91d8ad8c        17 seconds ago       505 MB
<none>                   <none>              a0cadeb9febd        About a minute ago   505 MB
<none>                   <none>              ee5ba19a8016        2 minutes ago        505 MB
<none>                   <none>              ef96fdd4473a        49 years ago         505 MB
  • 这些都是上一次构建的结果,在经历了新一轮的构建后,其镜像名和tag被新镜像所有,所以自身只能显示名为<none>,tag也是<none>,清理这些镜像的命令是 docker image prune ,然后根据提示输入"y",镜像即可被清理:
[root@maven hellojib]# docker image prune
WARNING! This will remove all dangling images.
Are you sure you want to continue? [y/N] y
Deleted Images:
deleted: sha256:7aa104e20b8a08bac3255f2627ac90f10021c6630370ce7a84ba33f89404b153
deleted: sha256:7dd7376ae00c2df0411bac1eded4b3c79dd1528f5711057fe11a4f4121504486
deleted: sha256:e71ced47e80a7fccfea1710f1e5a257d4e16fc3e96b05616007e15829e71a7b2
deleted: sha256:55bed58453479c2accfc08fabc929aece7d324af0df94335dd46333db9da1d23
deleted: sha256:ef96fdd4473a7ca9d39a50e0feae50131de083cee4f11060ad8bee1bc853b2b5

Total reclaimed space: 0 B
[root@maven hellojib]# docker images
REPOSITORY               TAG                 IMAGE ID            CREATED              SIZE
bolingcavalry/hellojib   0.0.1-SNAPSHOT      3afd4165b6b6        About a minute ago   505 MB

小结四:提升构建速度

  • 在使用命令 mvn compile jib:dockerBuild 构建本地镜像时,每次构建的过程中都会提示以下信息:
[INFO] Containerizing application to Docker daemon as bolingcavalry/hellojib:0.0.1-SNAPSHOT...
[INFO] The base image requires auth. Trying again for openjdk:8-jdk-stretch...
[INFO] Executing tasks:
[INFO] [=========                     ] 30.0% complete
[INFO] > pulling base image manifest
  • 每次构建都会显示上面的内容,也就是说每次都去远程拉取base镜像的manifest(pulling base image manifest),这部分时间导致整体构架时间变长,以下是构建结果,可见用了10秒:
[INFO] Built image to Docker daemon as bolingcavalry/hellojib:0.0.1-SNAPSHOT
[INFO] Executing tasks:
[INFO] [==============================] 100.0% complete
[INFO] 
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time:  10.722 s
[INFO] Finished at: 2019-09-01T08:55:09+08:00
[INFO] ------------------------------------------------------------------------
  • 首先想到的是执行命令 docker pull openjdk:8-jdk-stretch 将base镜像下载到本地仓库,再尝试构建,遗憾的是jib依旧会远程获取base镜像的manifest,还是很慢;

  • 如果能避免远程拉取base镜像的manifest,镜像构建速度应该会快一些;基于此推论,优化构建速度的步骤如下:

  1. 在本机创建registry(docker镜像仓库服务);
  2. 将base镜像openjdk:8-jdk-stretch放入本机registry;
  3. 修改pom.xml中base镜像的配置,改为本机registry的镜像;
  4. 如此一来,每次都会从本机registry取得base镜像的manifest,不走远程请求响应,构建时间会有提升;
  • 接下按照上述步骤进行操作:
  • 确认当前电脑的IP地址,我这里是 192.168.121.131
  • 设置本地docker服务支持http:修改docker配置文件:/etc/docker/daemon.json,在json中增加内容 “insecure-registries”: [“192.168.121.131:5000”]
  • 重启docker使配置生效:
systemctl restart docker
  • 在本地创建一个镜像仓库服务:
docker run --name docker-registry -d -p 5000:5000 registry
  • 查看本地镜像 openjdk:8-jdk-stretch 的ID为 08ded5f856cc
  • 用tag命令将本地镜像 openjdk:8-jdk-stretch 改名,命令如下所示,"192.168.121.131"是当前电脑的IP地址:
docker tag 08ded5f856cc 192.168.121.131:5000/openjdk:8-jdk-stretch
  • 再次查看镜像,发现多了个 192.168.121.131:5000/openjdk:8u212-jdk-stretch
[root@maven hellojib]# docker tag 08ded5f856cc 192.168.121.131:5000/openjdk:8-jdk-stretch
[root@maven hellojib]# docker images
REPOSITORY                     TAG                 IMAGE ID            CREATED             SIZE
bolingcavalry/hellojib         0.0.1-SNAPSHOT      6601ef5a767d        3 minutes ago       505 MB
192.168.121.131:5000/openjdk   8-jdk-stretch       08ded5f856cc        2 weeks ago         488 MB
docker.io/openjdk              8-jdk-stretch       08ded5f856cc        2 weeks ago         488 MB
  • 192.168.121.131:5000/openjdk:8-jdk-stretch 推送到远程仓库,命令如下所示,由于镜像名前缀是 192.168.121.131:5000 ,镜像会被推送到我们刚刚创建的registry:
docker push 192.168.121.131:5000/openjdk:8-jdk-stretch
  • 修改java工程的pom.xml,将base镜像由之前的 openjdk:8-jdk-stretch 改为 192.168.121.131:5000/openjdk:8-jdk-stretch
  • 修改java工程的pom.xml,增加 allowInsecureRegistries ,使jib插件支持http协议连接镜像仓库(安全起见,默认是关闭的),整个插件的配置信息如下:
<plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>

            <!--使用jib插件-->
            <plugin>
                <groupId>com.google.cloud.tools</groupId>
                <artifactId>jib-maven-plugin</artifactId>
                <version>1.3.0</version>
                <configuration>
                    <!--from节点用来设置镜像的基础镜像,相当于Docerkfile中的FROM关键字-->
                    <from>
                        <!--使用openjdk官方镜像,tag是8-jdk-stretch,表示镜像的操作系统是debian9,装好了jdk8-->
                        <image>192.168.121.131:5000/openjdk:8-jdk-stretch</image>
                    </from>
                    <to>
                        <!--镜像名称和tag,使用了mvn内置变量${project.version},表示当前工程的version-->
                        <image>bolingcavalry/hellojib:${project.version}</image>
                    </to>
                    <!--容器相关的属性-->
                    <container>
                        <!--jvm内存参数-->
                        <jvmFlags>
                            <jvmFlag>-Xms4g</jvmFlag>
                            <jvmFlag>-Xmx4g</jvmFlag>
                        </jvmFlags>
                        <!--要暴露的端口-->
                        <ports>
                            <port>8080</port>
                        </ports>
                        <useCurrentTimestamp>true</useCurrentTimestamp>
                    </container>
                    <allowInsecureRegistries>true</allowInsecureRegistries>
                </configuration>
            </plugin>
        </plugins>

  • 再次执行命令 mvn compile jib:dockerBuild ,如下所示,时间从之前的10秒缩减到3.9秒:
[INFO] Built image to Docker daemon as bolingcavalry/hellojib:0.0.1-SNAPSHOT
[INFO] Executing tasks:
[INFO] [==============================] 100.0% complete
[INFO] 
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time:  3.949 s
[INFO] Finished at: 2019-09-01T10:51:50+08:00
[INFO] ------------------------------------------------------------------------
  • 以上就是通过registry服务提升jib构建速度的方法,在多人开发的时候,registry可以配置为一个公共的,多人都可使用,毕竟pom.xml代码存在公共代码仓库,每个人都去修改成自己的registry的地址是不合适的,一旦提交上去会影响其他人的使用,我们这里的做法是将registry的地址写成host,本地维护好host和IP的映射就可以了。
    使用本地registry服务,除了提速,在服务器无法连接中央仓库取得openjdk:8-jdk-stretch的manifest时,这种方式能保证构建依旧能够成功;

小结五:将jib与mvn构建的生命周期绑定

  • 前面的实战中构建命令是 mvn compile jib:dockerBuild ,实际上可以做到仅用 mvn compile 就完成镜像构建,这是maven插件的通用特性;
  • 修改pom.xml增加 executions 节点,里面设置compile触发jib:dockerBuild,整个插件的内容如下所示:
<plugin>
                <groupId>com.google.cloud.tools</groupId>
                <artifactId>jib-maven-plugin</artifactId>
                <version>1.3.0</version>
                <configuration>
                    <!--from节点用来设置镜像的基础镜像,相当于Docerkfile中的FROM关键字-->
                    <from>
                        <!--使用openjdk官方镜像,tag是8-jdk-stretch,表示镜像的操作系统是debian9,装好了jdk8-->
                        <image>192.168.121.131:5000/openjdk:8-jdk-stretch</image>
                    </from>
                    <to>
                        <!--镜像名称和tag,使用了mvn内置变量${project.version},表示当前工程的version-->
                        <image>bolingcavalry/hellojib:${project.version}</image>
                    </to>
                    <!--容器相关的属性-->
                    <container>
                        <!--jvm内存参数-->
                        <jvmFlags>
                            <jvmFlag>-Xms4g</jvmFlag>
                            <jvmFlag>-Xmx4g</jvmFlag>
                        </jvmFlags>
                        <!--要暴露的端口-->
                        <ports>
                            <port>8080</port>
                        </ports>
                        <useCurrentTimestamp>true</useCurrentTimestamp>
                    </container>
                    <allowInsecureRegistries>true</allowInsecureRegistries>
                </configuration>
                <executions>
                  <execution>
                    <phase>compile</phase>
                    <goals>
                      <goal>dockerBuild</goal>
                    </goals>
                  </execution>
                </executions>
            </plugin>
  • 执行命令 mvn compile -DskipTests ,如下所示,可以成功构建镜像,与前面的命令结果一致:
[root@maven hellojib]# mvn compile -DskipTests
[INFO] Scanning for projects...
[INFO] 
[INFO] ---------------------< com.bolingcavalry:hellojib >---------------------
[INFO] Building hellojib 0.0.1-SNAPSHOT
[INFO] --------------------------------[ jar ]---------------------------------
[INFO] 
[INFO] --- maven-resources-plugin:3.1.0:resources (default-resources) @ hellojib ---
[INFO] Using 'UTF-8' encoding to copy filtered resources.
[INFO] Copying 1 resource
[INFO] Copying 0 resource
[INFO] 
[INFO] --- maven-compiler-plugin:3.8.1:compile (default-compile) @ hellojib ---
[INFO] Nothing to compile - all classes are up to date
[INFO] 
[INFO] --- jib-maven-plugin:1.3.0:dockerBuild (default) @ hellojib ---
[WARNING] Setting image creation time to current time; your image may not be reproducible.
[INFO] 
[INFO] Containerizing application to Docker daemon as bolingcavalry/hellojib:0.0.1-SNAPSHOT...
[INFO] 
[INFO] Container entrypoint set to [java, -Xms4g, -Xmx4g, -cp, /app/resources:/app/classes:/app/libs/*, com.bolingcavalry.hellojib.HellojibApplication]
[INFO] 
[INFO] Built image to Docker daemon as bolingcavalry/hellojib:0.0.1-SNAPSHOT
[INFO] Executing tasks:
[INFO] [==============================] 100.0% complete
[INFO] 
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time:  3.721 s
[INFO] Finished at: 2019-09-01T11:43:23+08:00
[INFO] ------------------------------------------------------------------------
[root@maven hellojib]# docker images
REPOSITORY                     TAG                 IMAGE ID            CREATED             SIZE
bolingcavalry/hellojib         0.0.1-SNAPSHOT      5e3f62d13a73        35 seconds ago      505 MB
192.168.121.131:5000/openjdk   8-jdk-stretch       08ded5f856cc        2 weeks ago         488 MB
docker.io/openjdk              8-jdk-stretch       08ded5f856cc        2 weeks ago         488 MB
docker.io/registry             latest              f32a97de94e1        5 months ago        25.8 MB

小结六:父子结构的maven工程如何构建

  • 假设当前maven工程是父子结构的,有两个子工程A和B,其中A是二方库,提供一个jar包,里面是接口类和Bean类,B是springboot应用,并且B的源码中用到了A提供的接口和Bean;

  • 上述父子结构的maven工程是常见的工程结构,此时如果要将B构建成Docker镜像,在B的目录下执行 mvn compile jib:dockerBuild 显然是不行的,因为没有编译构建A,会导致B的编译失败;

  • 此时最好的做法就是将jib与mvn构建的生命周期绑定,修改B的pom.xml文件,加入executions节点;

  • 在父工程目录下执行 mvn compile ,此时maven会先编译构建整个工程,然后再将B工程的构建结果制作成镜像;

  • 以上就是我在近期使用Jib插件时遇到的问题小结,希望这些小技巧可以给您提供一些参考,助您解决问题;

欢迎关注51CTO博客:程序员欣宸

 学习路上,你不孤单,欣宸原创一路相伴…


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK