为什么 Java 11 基础 Docker 镜像这么大?(openjdk:11-jre-slim)

2022-08-31 06:23:58

Java 11被宣布为最新的LTS版本。因此,我们正试图基于此 Java 版本启动新服务。

但是,Java 11 的基本 Docker 映像比 Java 8 的等效映像大得多:

(我只考虑官方的OpenJDK和每个Java版本最轻量级的图像。

深入挖掘发现了以下“东西”:

  • openjdk:11-jre-slim image 使用 base image 。这带来了2个问题:debian:sid-slim

    • 这比alpine:3.8

    • Debian sid 版本是不稳定的

  • 映像中安装的包比(在正在运行的 Docker 容器中)大 3 倍openjdk-11-jre-headlessopenjdk8-jre

    • openjdk:8-jre-alpine:

      / # du -hs /usr/lib/jvm/java-1.8-openjdk/jre/lib/
      57.5M   /usr/lib/jvm/java-1.8-openjdk/jre/lib/
      
    • openjdk:11-jre-slim:

      # du -sh /usr/lib/jvm/java-11-openjdk-amd64/lib/
      179M    /usr/lib/jvm/java-11-openjdk-amd64/lib/
      

      更深入地了解了这种沉重感的“根源” - 它是JDK的文件:modules

      # ls -lhG /usr/lib/jvm/java-11-openjdk-amd64/lib/modules
      135M    /usr/lib/jvm/java-11-openjdk-amd64/lib/modules
      

所以,现在出现了问题:

  • 为什么不再用作 Java 11 精简映像的基础映像?alpine

  • 为什么不稳定的 sid 版本用于 LTS Java 映像?

  • 为什么OpenJDK 11的超薄/无头/JRE封装与类似的OpenJDK 8封装相比如此之大?

    • 这个模块文件是什么,它带来了135 MB在OpenJDK 11?

UPD:作为应对这些挑战的解决方案,可以使用这个答案:Java 11应用程序作为docker映像


答案 1

为什么不再用作 Java 11 精简映像的基础映像?alpine

这是因为,可悲的是,目前还没有官方稳定的OpenJDK 11版本用于Alpine。

Alpine使用musl libc,而不是大多数Linuxes使用的标准glibc,这意味着JVM必须与musl libc兼容以支持vanilla Alpine。Musl OpenJDK端口是在OpenJDK的Portola项目下开发的。

OpenJDK 11 页面上总结了当前状态:

此页面上以前可用的 Alpine Linux 版本在 JDK 11 GA 中已被删除。它不是生产就绪的,因为它尚未经过足够彻底的测试,无法被视为 GA 版本。请使用早期访问的 JDK 12 Alpine Linux 版本来代替它。

目前,Alpine唯一稳定的OpenJDK版本是IcedTea项目提供的7和8。

但是 - 如果您愿意考虑官方OpenJDK以外的其他因素,Azul的Zulu OpenJDK提供了一个引人注目的替代方案:

  • 它支持Alpine musl上的Java 11(截至撰写本文时的版本11.0.2);
  • 它是经过认证的OpenJDK构建,使用OpenJDK TCK合规性套件进行验证;
  • 它是免费的,开源的,并且准备好了Docker(Dockerhub)。

有关支持可用性和路线图,请参阅 Azul 支持路线图

更新,3/6/19:截至昨天,在阿尔卑斯存储库中可用!它可以在Alpine上通过以下方式获得:openjdk11

apk --no-cache add openjdk11

该软件包基于OpenJDK分支以及Portola项目中的移植修复程序,随以下PR引入。荣誉和巨大的感谢阿尔卑斯团队。jdk11u

为什么不稳定的 sid 版本用于 LTS Java 映像?

这是一个公平的问题/要求。实际上有一个在稳定的 Debian 发行版上提供 Java 11 的开放票证:
https://github.com/docker-library/openjdk/issues/237

更新,26/12/18:问题已得到解决,现在OpenJDK 11 slim映像基于最近可用的OpenJDK 11(PR链接)。stretch-backports

为什么OpenJDK 11的超薄/无头/JRE封装与类似的OpenJDK 8封装相比如此之大?这个模块文件是什么,它带来了135 MB在OpenJDK 11?

Java 9 引入了模块系统,与 jar 文件相比,这是一种新的改进的包和资源分组方法。Oracle的这篇文章非常详细地介绍了这个功能:
https://www.oracle.com/corporate/features/understanding-java-9-modules.html

该文件捆绑了 JRE 附带的所有模块。模块的完整列表可以用 打印。 确实是一个非常大的文件,并且如前所述,它包含所有标准模块,因此非常臃肿。modulesjava --list-modulesmodules

然而,需要注意的一件事是,它取代了并且被弃用了,因此,当考虑与9之前的OpenJDK构建相比时的大小时,应该减去和的大小(它们应该占用大约80MB的总和)。rt.jartools.jarmodulesrt.jartools.jar


答案 2

如果您只考虑官方图像,并且您的目标目标是使用可用的较小的JRE图像,我建议您查看官方OpenJDK图像,该图像仅为69.2 MB。openjdk:11-jre-slim-buster


推荐