美文网首页
构建更小的Java docker 镜像

构建更小的Java docker 镜像

作者: 大帅的大帅 | 来源:发表于2020-05-17 13:12 被阅读0次

    今天看到一篇文章,说是基础镜像‘Apline’ 有坑,闭坑,多阶段构建更小的镜像。 之前写《Spring组件之Eureka》 这篇文章的时候,介绍过如何使用把打包的java 的jar的包封装成一个docker 镜像。
    今天看完文章后,再来个优化版。 让打好的镜像更小。

    写在前面

    在大多数的平台下,Java打包有两种大家熟悉的格式: JDK 和 JRE。

    JRE 是 Java 运行时环境(Java Runtime Environment):包含了运行 Java 程序所需要的环境,即 JVM。
    JDK 即 Java 开发工具包(Java Development Kit),既包含了 JRE,也包含了开发 Java 程序所需的工具,即 Java 编译器。

    在JRE里环境里,就能跑jar的包,但是不能编译Java程序。
    我们常用到的编译的基础镜像 都是JDK的,运行时的基础镜像是JRE的。 这样可以让镜像更小。

    基于jar构建dockerFile

    如果是单一的Java代码,我们可以分两个步骤,分阶段构建镜像。参见后面。
    在这里,我们是基于Spring 框架构建的项目,包含了很多依赖关系。我们更倾向于用打完jar 后直接运行。

    没优化前

    之前步骤是,把基于Spring的项目,打包后,用 openjdk:8 作为基础镜像,封装我们的jar包。 dockerFile 文件如下:

    FROM openjdk:8
    COPY target/demo-0.0.1-SNAPSHOT.jar app.jar
    EXPOSE 8761
    CMD java  -jar app.jar
    

    原生的 openjdk:8 这个镜像可不小,有500M。

    openjdk                                         8                   0d54b885dc70        6 weeks ago         510MB
    

    docker build 后,大小如下:

    eurekaserverjdk                                    v0.1                6a241b43b1d9        22 minutes  ago         559MB
    

    对于本地mac OS的SSD 来说,寸土寸金。我打算为镜像瘦身。

    优化后

    优化的方案也非常简单。我们的基础镜像选择openjdk:8-jre-alpine 这个镜像更小, 90M都不到。

    openjdk                                         8-jre-alpine        f7a292bbb70c        12 months ago       84.9MB
    

    dockerFile 也很好写,把原来openjdk:8的基础镜像,替换为openjdk :8-jre-alpine。就可以了:

    FROM openjdk:8-jre-alpine
    COPY demo-0.0.1-SNAPSHOT.jar app.jar
    EXPOSE 8761
    CMD java  -jar app.jar
    

    我们build 一下。

    docker build  -f DockerfileLow -t eurekaserverjdkalpine .
    Sending build context to Docker daemon  49.54MB
    Step 1/4 : FROM openjdk:8-jre-alpine
     ---> f7a292bbb70c
    Step 2/4 : COPY demo-0.0.1-SNAPSHOT.jar app.jar
     ---> 9537ce606603
    Step 3/4 : EXPOSE 8761
     ---> Running in 33951dd86879
    Removing intermediate container 33951dd86879
     ---> 6ff3c14caa3f
    Step 4/4 : CMD java  -jar app.jar
     ---> Running in 29180e188129
    Removing intermediate container 29180e188129
     ---> 9142e469b396
    Successfully built 9142e469b396
    

    看看大小 这个镜像 134M ,也比原来小很多了。

    eurekaserverjdkalpine                                           latest              9142e469b396        22 minutes ago      134MB
    

    基于Java Class 构建镜像

    写在前面我们也说了,这里构建的镜像,够是基于jar构建的,那么我们写出来了Java的源码,可以在docker 里用JDK 编译,后运行吗?答案是肯定的。我们用jar 比较省事而已。

    例如写一个数组循环,为了方便来演示,我们引入了一个String[]数据。 注意这个class文件不要加包名!

    public class testDocker {
        public static void main(String[] args) {
            String[] worlds = {"I","love","world"};
            for (String i : worlds){
                System.out.println("-->" + i);
            }
        }
    }
    
    

    基础版

    DockerFile 可以这么写,dockerFile 文件路径要和testDocker.java 在一个目录。

    FROM openjdk:8
    COPY testDocker.java .   
    RUN javac testDocker.java
    FROM openjdk:8-jre
    COPY --from=0 testDocker.class .
    CMD exec java -cp . testDocker
    

    build 一下,并 docker run .

    $docker build -f DockerFile -t testdocker . 
    Sending build context to Docker daemon  10.75kB
    Step 1/6 : FROM openjdk:8
     ---> 0d54b885dc70
    Step 2/6 : COPY testDocker.java .
     ---> 636d06180d97
    Step 3/6 : RUN javac testDocker.java
     ---> Running in 2084d3abd242
    Removing intermediate container 2084d3abd242
     ---> 22e56e8de462
    Step 4/6 : FROM openjdk:8-jre
     ---> 1c5f6cd937b5
    Step 5/6 : COPY --from=0 testDocker.class .
     ---> 71409231c882
    Step 6/6 : CMD exec java -cp . testDocker
     ---> Running in 39e4f8f37dee
    Removing intermediate container 39e4f8f37dee
     ---> 7261f19915ef
    Successfully built 7261f19915ef
    Successfully tagged testdocker:latest
    
     $docker run -ti testdocker  
    -->I
    -->love
    -->world
    
    

    看下build 后的镜像,大概在265M 左右。

    testdocker                                      latest              7261f19915ef        3 minutes ago       265MB
    

    优化版

    又来用apline 这个多阶段加载了这个小镜像了。
    DockerFile 这么写

    FROM openjdk:8
    COPY testDocker.java .
    RUN javac testDocker.java
    FROM openjdk:8-jre-alpine
    COPY --from=0 testDocker.class .
    CMD exec java -cp . testDocker
    

    build 一下,run 一把也没问题。

    dockerbuild -f dockerFileApline -t testdockerbaseapline . 
    docker run -ti testdockerbaseapline
    -->I
    -->love
    -->world
      
    ···
    镜像大小,不到90M,小的有点过分了啊。真激动,释放了不少磁盘空间。 
    ```shell
    testdockerbaseapline                            latest              594f58eba821        33 seconds ago      84.9MB
    

    写在最后

    总结,对于docker 镜像,坚持原则就是多阶段、最后用基础Apline 镜像构建。这样是最小的。
    放一个github的一个地址,里面有各种语言版本的编译环境的DockerFile. 希望对你有帮助。

    相关文章

      网友评论

          本文标题:构建更小的Java docker 镜像

          本文链接:https://www.haomeiwen.com/subject/eqgjohtx.html