按这个方法打java17的镜像,大小直接减少70%

2023年 8月 29日 101.5k 0

  大家好,我是Coder哥,前两天写了一篇文章java17+gradle+k8s构建Springboot保姆教程, 看到有小伙伴留言想要里面的jre17镜像的构建方法,授人以鱼不如授人以渔,那我们本篇文章就来详细的聊一下,本文不只是Java 其他的语言也可以按这个思路来,旨在抛砖引玉。如果觉得有帮助,别忘了点赞收藏!

  不知道大家平时在打java项目镜像的时候用的基础镜像是啥,反正这么多年我遇到的java项目基础镜像基本都是基于jdk的,因为业务开发很少会注意镜像大小以及镜像优化这一点,导致一个镜像好几百兆大小,但是我们运行Java项目其实只需要运行时环境就可以了,其他的好多软件根本没啥用,它唯一的作用就是拖慢你的部署速度。那么我们以java 8,和java17为例,一步步来进行镜像的优化。

为什么选择java8和java17:

因为这两个版本是比较典型的长期支持版本,java8可以说是最牛钉子户,没有之一(不多说,懂的都懂),在这个节点上,如果java8的开发者要升级,第一选择就是java17, 性能强悍免费又稳定,官方力推。

我们在打镜像之前得先简单了解一下JDK,JRE的区别,那么我们从如下几个内容出发。

  • 了解一下JDK、JRE的简单区别。
  • Java8 版本Dockerfile的镜像优化
  • Java17 JRE版本Dockerfile的编写。
  • 了解一下JDK、JRE的简单区别

    JDK: Java Development Kit,是Java的标准开发工具包(普通用户只需要安装 JRE来运行 Java 程序。而程序开发者必须安装JDK来编译、调试程序)。它提供了编译、运行Java程序所需的各种工具和资源,包括Java编译器、Java运行环境JRE,以及常用的Java基础类库等,是整个JAVA的核心。

    JRE: Java Runtime Environment,是java运行时的环境,包含了java虚拟机,java基础类库,是使用java语言编写的程序运行所需要的软件环境。

    简单来讲JRE是Java运行环境,并不是一个开发环境,所以没有包含任何开发工具(如编译器和调试器),只是针对于使用Java程序的用户。而JDK不仅仅提供了运行环境,还提供了Java的全套开发工具(如编译器和调试器等)。

    Java8 版本Dockerfile的镜像优化

    想要打包Java8版本的基础镜像,那么首先就需要下载对应系统的java版本,然后编写Dockerfile, 最后打包镜像测试。我们按流程来看一下,由于我们是在LInux版本上用的,所以需要选Linux版本的。

    Java8基础镜像的打包流程

  • 下载Java版本
  • 我们先到Oracle的官网(www.oracle.com/java/techno…

    jdk81.png

  • 编写Dockerfile
  • FROM centos:7
    # 作者
    MAINTAINER todocoder.com
    # 在构建镜像时,指定镜像的工作目录,之后的命令都是基于此工作目录,如果不存在,则会创建该目录
    WORKDIR /servers
    # 将jdk安装包复制到镜像中(ADD与COPY的区别:ADD复制并解压,COPY仅复制)
    ADD jdk-8u381-linux-x64.tar.gz .
    #配置环境变量
    ENV JAVA_VERSION=8u381
    ENV JAVA_HOME=/servers/jdk1.8.0_381
    ENV CLASSPATH=.:$JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tools.jar
    ENV PATH=$JAVA_HOME/bin:$JAVA_HOME/jre/bin:$PATH
    

    注意:Dockerfile需要和下载的JDK压缩包在同一个目录下

  • 打包
  • docker build -t todocoder/jdk:8u381 .

    打包完后我们查看一下镜像大小: docker images | grep jdk

    jdk82.png

    可以看到这个版本的镜像下来 547M

    这个大小确实也有点大了,那么我们如果要优化的话,从哪几个方面入手呢?

    Java8镜像简单优化

    我们先考虑一下占用量大的都哪些? 1. 基础镜像。2. JDK的大小。3. Dockerfile脚本的复杂度。

    所以如果要优化的话也是从这三个方面入手:

  • 基础镜像我们看看能否换成小点的。
  • 如果我只是运行jar包的项目,是否需要JDK这么全量的工具包,理论上我们换成jre就可以了。
  • Dockerfile 脚本的话,其实我们的并不是很复杂暂时先不用考虑。
  • 替换表如下:

    替换前 替换后
    centos:7(72MB) ubuntu(28.17MB)
    jdk-8u381(解压后328MB) jre-8u381(解压后258M)

    注意:这里的基础镜像如有兴趣可以用 alpine 镜像(alpine镜像比ubuntu的还要小,5M以内),这个在JDK环境没怎么在生产上用过,Go语言环境用的比较多。

    还是到Oracle的官网(www.oracle.com/java/techno…

    jre81.png

    对应的Dockerfile 如下:

    FROM ubuntu
    # 作者
    MAINTAINER todocoder.com
    # 在构建镜像时,指定镜像的工作目录,之后的命令都是基于此工作目录,如果不存在,则会创建该目录
    WORKDIR /servers
    # 将jdk安装包复制到镜像中(ADD与COPY的区别:ADD复制并解压,COPY仅复制)
    ADD jre-8u381-linux-x64.tar.gz .
    # 删除一些运行jar包不用的一些特性
    RUN rm -rf jre1.8.0_381/lib/plugin.jar 
               jre1.8.0_381/lib/ext/jfxrt.jar 
               jre1.8.0_381/bin/javaws 
               jre1.8.0_381/lib/javaws.jar 
               jre1.8.0_381/lib/desktop 
               jre1.8.0_381/plugin 
               jre1.8.0_381/lib/deploy* 
               jre1.8.0_381/lib/*javafx* 
               jre1.8.0_381/lib/*jfx* 
               jre1.8.0_381/lib/amd64/libdecora_sse.so 
               jre1.8.0_381/lib/amd64/libprism_*.so 
               jre1.8.0_381/lib/amd64/libfxplugins.so 
               jre1.8.0_381/lib/amd64/libglass.so 
               jre1.8.0_381/lib/amd64/libgstreamer-lite.so 
               jre1.8.0_381/lib/amd64/libjavafx*.so 
               jre1.8.0_381/lib/amd64/libjfx*.so
    #配置环境变量
    ENV JAVA_VERSION=8u381
    ENV JAVA_HOME=/servers/jre1.8.0_381
    ENV PATH=$JAVA_HOME/bin:$PATH
    

    打包

    docker build -t todocoder/jre:8u381 .

    打包完后我们查看一下镜像大小: docker images | grep jre

    jre82.png

    看到剩余347M了,当然了这不是极限,有兴趣可以把基础镜像换成 alpine的,jre里面的一些包再精简一下。

    至此Java8版本的镜像生成也聊的差不多了,接下来我们看看jre17的要怎么打。

    jre17没有独立下载的地方,是和JDK17在同一个包中,我们需要基于JDK单独的生产jre包

    Java17 JRE版本Dockerfile的编写

    Java17没有独立的JRE版本,我们先下载JDK17版本,到Oracle的官网(www.oracle.com/java/techno…

    jdk17.png

    jre制作

    jdk1.8及以前的版本,都是有jre的,但是jdk9以后的版本不在提供jre需要自己制作。jlink是通过按模块打包的,但是由于目前很多库还不是按模块打包的,所以我们无法知道项目里面都用了那些模块。只好将所有的模块进行打包。这样避免以后出现缺失模块导致应用报错的问题。

    解压 tar.gz后的目录在 jdk-17.0.8 目录下执行命令生成 jre17

     bin/jlink --module-path jmods --add-modules ALL-MODULE-PATH  --compress=2 --strip-debug --output jre
    

    jre171.png

    可以看到jdk目录下多了一个jre的文件夹,那么我们可以基于这个文件夹生成镜像:

    FROM ubuntu:latest
    MAINTAINER todocoder.com
    
    COPY ./jre /usr/local/jre17
    #授执行权限
    RUN chmod -R 750 /usr/local/jre17/bin
    
    #setup java env
    ENV JAVA_HOME=/usr/local/jre17
    ENV PATH=$PATH:$JAVA_HOME/bin
    ENV CALSSPATH=$JAVA_HOME/jre/lib/rt.jar:$JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tools.jar
    

    打包

    docker build -t todocoder/jre:17.0.8 .

    打包完后我们查看一下镜像大小: docker images | grep jre

    jre172.png

    可以看到,只有167M。

    从开始的JDK 547M 到现在的jre 167M ,节省了 70%的空间,当然了你还可以继续的基于alpine 优化,并且继续的删减jre中没用的工具。

    总结

      本文主要通过介绍JDK和JRE的简单区别,并从Java1.8 和Java17两个重要的版本来切入,帮助各位业务开发者以及运维人员来了解Java基础镜像的构建过程。希望能给各位开发者带来帮助。

    感谢各位能看到这里,觉得文章有用的话记得关注一下,别忘了点赞收藏哦,最后打个小广告

    微信工号搜: TodoCoder

    会不定时分享 Java,Go,Docker,k8s等 技术文章,公号无广告,无推荐,纯分享

    **本项目涉及的代码和部署文件都在文章中列出,如果想要源文件可以发你,V: todocodercom 或者公号: todocoder **

    相关文章

    服务器端口转发,带你了解服务器端口转发
    服务器开放端口,服务器开放端口的步骤
    产品推荐:7月受欢迎AI容器镜像来了,有Qwen系列大模型镜像
    如何使用 WinGet 下载 Microsoft Store 应用
    百度搜索:蓝易云 – 熟悉ubuntu apt-get命令详解
    百度搜索:蓝易云 – 域名解析成功但ping不通解决方案

    发布评论