美文网首页
构建更小的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