• Java教程:如何使用Jib插件容器化SpringBoot应用?


    一、序言

    ​ 近几年,微服务已经成为Java主流的技术方向,随着微服务化的流行,应用容器化部署也是必不可少的。应用容器化用抽象的话来说就是:将应用程序部署到容器当中作为独立的应用程序部署单元运行,并作为实现高级别资源隔离的机制。常见的容器化技术就是docker,所以简单来说就是将微服务程序打包成镜像,在容器中运行,但这样做有一个关键问题,就是docker镜像越大,部署的效率越低,希望通过本文为你容器化部署提供效率。

    二、 使用原始的方式构建一个docker镜像

    我们先用原始的方式制作一个Spring boot应用程序镜像,体会一下目前流行的容器化部署方式。

    1. 创建spring boot应用

    我们编写一个简单的应用程序,只有一个hello的controller即可

    在这里插入图片描述

    如果你不想创建该项目,可以从这里看到源码

    打开浏览器简单测试一下:

    在这里插入图片描述

    2. 打包

    root@ubuntu:docker-image-demo$ mvn package
    
    • 1

    3.编写Dockerfile

    #Dockerfile 这里我们选用 jre环境 减少镜像的体积
    FROM openjdk:8-jre-alpine
    #镜像内部创建一个app目录 用来存放jar包
    RUN mkdir /app
    #复制jar包 到app目录下
    COPY target/docker-image-demo-0.0.1-SNAPSHOT.jar /app/app.jar
    #暴露端口
    EXPOSE 8080/tcp
    #默认启动程序
    ENTRYPOINT java -jar /app/app.jar
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    4. 创建镜像

    #创建镜像
    root@ubuntu:docker-image-demo$ docker build -t docker-image-demo:0.0.1 .
    
    #查询镜像
    root@ubuntu:docker-image-demo$ docker images
    
    • 1
    • 2
    • 3
    • 4
    • 5

    在这里插入图片描述

    5. 推送镜像到registry仓库

    #将镜像推送到镜像仓库 这里我们选择阿里云的镜像仓库 
    #登录的步骤 请自行查阅阿里云镜像仓库
    
    root@ubuntu:docker-image-demo$ docker tag docker-image-demo:0.0.1 registry.cn-hangzhou.aliyuncs.com/jk1123/docker-jib-test:0.0.1
    
    #推送
    root@ubuntu:docker-image-demo$ docker push registry.cn-hangzhou.aliyuncs.com/jk1123/docker-jib-test:0.0.1 
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    在这里插入图片描述

    在阿里云仓库查看镜像

    在这里插入图片描述

    三、原始方式的不足

    1. 需要编写Dockerfile

    镜像的打包部署本身属于运维工作,但是需要开发人员的介入,解放应用开发人员的双手,不要将运维的工作引入到开发人员的工作流中

    2. 制作镜像耗时

    使用springboot的项目打包而成的jar包是一个fat jar(就是该jar中包含该应用程序需要一切依赖).导致docker镜像制作过程当中需要复制该jar到容器中

    稍微大一点应用程序打成fat jar 高达一两百MB,其实最主要还是依赖的sprring全家桶的jar太多

    3. 推送镜像到仓库和拉取镜像耗时

    微服务的使用便于快速迭代服务,所以发版的频率十分频繁.每次推送镜像/拉取镜像十分耗时,因为每次发版我们的fat jar都会发生细微的改变.导致docker无法利用其缓存机制,每次都要拉取镜像中的fat jar 那层.导致推送和拉取十分消耗网络资源和时间

    四、 使用Google jib工具

    1. 简介

    在这里插入图片描述

    Jib 是谷歌公司推出的开源 Java 镜像构建工具,它可以将一个 Java 应用构建成 OCI 镜像或者是 Docker 镜像,目前最新的 Relaese 版本为 3.2.1

    JIB 具有以下特点:

    1. Jib 使用 Java 开发,并作为 Maven 或 Gradle 的一部分运行.你不需要编写 Dockerfile 或 安装Docker 环境,甚至无需创建包含所有依赖的大 JAR 包,就可以构建出镜像,并将镜像推送到镜像仓库。因为 Jib 与 Java 构建过程紧密集成,所以它可以访问到打包应用程序所需的所有信息。在后续的容器构建期间,它将自动选择 Java 构建过的任何变体。

    2. JIB 构建出的应用镜像,具有分层结构, 利用镜像分层和注册表缓存来实现快速、增量的构建,提高构建镜像、推送镜像的性能,减少镜像存储空间。

    3. 幂等性,Jib 支持根据 Maven 和 Gradle 的构建元数据进行声明式的容器镜像构建,只要输入保持不变,就可以通过配置重复创建相同的镜像。

    下图是官方给出的性能测试

    在这里插入图片描述

    在这里插入图片描述

    2.使用

    如此强大的工具使用起来相当的简单

    2.1 导入插件依赖

    
    <plugin>
        <groupId>com.google.cloud.toolsgroupId>
        <artifactId>jib-maven-pluginartifactId>
        <version>3.2.0version>
    plugin>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    2.2 配置插件

    <plugin>
        <groupId>com.google.cloud.toolsgroupId>
        <artifactId>jib-maven-pluginartifactId>
        <version>3.2.0version>
        <configuration>
            <from>
                
                <image>openjdk:8-jre-alpineimage>
            from>
            <to>
                <image>registry.cn-hangzhou.aliyuncs.com/jk1123/docker-jib-testimage>
                <tags>
                    <tag>0.0.2tag>
                tags>
                
                
                
                
                
            to>
            <container>
                
                <mainClass>com.jk1123.docker.DockerImageDemoApplicationmainClass>
                <creationTime>USE_CURRENT_TIMESTAMPcreationTime>
                <jvmFlags>
                    <jvmFlag>-Dmy.property=example.valuejvmFlag>
                    <jvmFlag>-Xms512mjvmFlag>
                    <jvmFlag>-Xmx2048mjvmFlag>
                jvmFlags>
                <ports>
                    <port>8080port>
                ports>
                <labels>
                    <org.label-schema.schema-version>1.0org.label-schema.schema-version>
                    <org.label-schema.name>docker-image-testorg.label-schema.name>
                    <org.label-schema.vendor>jk1123org.label-schema.vendor>
                    <org.label-schema.license>GPLv2org.label-schema.license>
                    <org.label-schema.build-date>${maven.build.timestamp}org.label-schema.build-date>
                    <org.opencontainers.image.title>docker-image-test Imageorg.opencontainers.image.title>
                    <org.opencontainers.image.vendor>jk1123org.opencontainers.image.vendor>
                    <org.opencontainers.image.licenses>GPL-2.0-onlyorg.opencontainers.image.licenses>
                    <org.opencontainers.image.created>${maven.build.timestamp}org.opencontainers.image.created>
                labels>
            container>
            <allowInsecureRegistries>trueallowInsecureRegistries>
        configuration>
        <executions>
            <execution>
                <phase>packagephase>
                <goals>
                    
                    
                    
                    <goal>buildgoal>
                goals>
            execution>
        executions>
    plugin>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62

    2.3.执行构建

    root@ubuntu:docker-image-demo$ mvn package jib:build
    
    • 1

    在这里插入图片描述

    五、 JIB原理分析

    1. docker镜像缓存

    docker的镜像是由一层层构成的

    在这里插入图片描述

    如上头所示,我们如果采用原始方式打包镜像,镜像分层如图.在这种情况下,如果我们的代码有变化,就会重新制作一个springboot的fat jar,这个jar中即时只有一行代码改变了,生成的新的jar也与原来的文件也变化,docker制作镜像的时候 该层发生了变化就需要重新制作,而一个fat jar非常的大,无法利用镜像的缓存功能.

    2. jib构建镜像分层

    Jib 在编译 springboot应用的时候考虑到的docker镜像的缓存功能,能利用缓存尽量的利用镜像的缓存.

    通过分析我们会发现如下规律:

    1.应用代码是最容易发生变化的,但是代码文件实际占用并不是太高(相对于引入jar包大小而言)

    2.应用的配置文件也容易发生变化,但是变化频率相对于代码要低一些

    3.应用依赖的其他的公共子模块也容易发生变化,但是变化频率相对于代码要更低一些

    4.应用依赖的一些快照jar包也容易发生变化,频率更低

    5.应用依赖的常规jar,例如spring系列的jar包,变化频率不大,试想谁会天天换spring版本号呢

    综上所述,jib的作者充分考虑到这些规律,将镜像分成好几层,充分利用的docker镜像缓存机制和资源的变化频率的特性,接下来我们来看看使用jib制作的镜像的层级关系图

    首先我们先看看我们的项目结构

    在这里插入图片描述

    接下来我们来看看镜像的层级结构图
    在这里插入图片描述
    在这里插入图片描述

    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述

    可见jib充分考虑和利用的docker镜像缓存的机制,来帮我们制作镜像.这样当我们的应用重新发版的时候,可以减少镜像的push和pull的速度。

    注:

    上图分析工具使用dive工具

    关于dive工具的使用请参照这里:

    github:https://github.com/wagoodman/dive

    gitee:https://gitee.com/mirrors/Dive

    六、 结束语

    通过如上的分析,相信大家对jib插件有个清晰的认知:

    jib就是根据应用的不同资源的变化频率和docker镜像的缓存机制,充分利用docker镜像的分层机制.提高镜像的制作和发布性能.

    最后,希望各位读者早日用上jib来打包您的应用,减少镜像的体积,减少打包消耗,减少传输消耗,畅享绿色生活!!!

  • 相关阅读:
    [思维模式-5]:《如何系统思考》-1- 认识篇 - 总体结构与知识框架
    1、项目准备与新建
    用强化学习玩《超级马里奥》
    ldap简单理解
    springboot整合canal
    护理教育学重点
    Web自动化测试进阶:网页中难点之等待机制 —— 强制等待,隐式等待
    基于STM32的OLED多级菜单GUI实现(简化版智能手表)
    一个关于proto 文件的经验分享 :gRPC 跨语言双端通信显示错误码:12 UNIMPLEMENTED (附赠gRPC错误码表)
    如何在CentOS中合理划分磁盘空间以优化系统性能
  • 原文地址:https://blog.csdn.net/cz_00001/article/details/126177259