为什么 Java 11 基础 Docker 镜像如此之大?(openjdk:11-jre-slim) [英] Why is the Java 11 base Docker image so large? (openjdk:11-jre-slim)

查看:205
本文介绍了为什么 Java 11 基础 Docker 镜像如此之大?(openjdk:11-jre-slim)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

然而,Java 11 的基础 Docker 镜像比 Java 8 的等价镜像大得多:

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

深入挖掘发现了以下事情":

  • openjdk:11-jre-slim 镜像使用基础镜像 debian:sid-slim.这带来了两个问题:

    • 这比 alpine:3.8

    • 大 60 MB
    • Debian sid 版本不稳定

  • 安装在镜像中的openjdk-11-jre-headless包比openjdk8-jre3倍大(里面运行 Docker 容器):

    • 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/modules135M/usr/lib/jvm/java-11-openjdk-amd64/lib/modules

那么,问题来了:

  • 为什么 alpine 不再用作 Java 11 超薄图像的基础图像?

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

  • 为什么 OpenJDK 11 的 slim/headless/JRE 包与类似的 OpenJDK 8 包相比如此之大?

    • 在 OpenJDK 11 中带来 135 MB 的 modules 文件是什么?

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

解决方案

为什么 alpine 不再用作 Java 11 超薄图像的基础图像?

遗憾的是,这是因为目前没有针对 Alpine 的官方稳定版 OpenJDK 11.

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

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

<块引用>

从 JDK 11 GA 起,此页面上先前提供的 Alpine Linux 版本已被删除.它不是生产就绪的,因为它没有经过足够彻底的测试,无法被视为 GA 版本.请使用抢先体验的 JDK 12 Alpine Linux 版本代替.

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

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

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

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

更新,3/6/19:截至昨天,openjdk11 在 Alpine 存储库中可用!它可以在 Alpine 上使用:

apk --no-cache 添加 openjdk11

该软件包基于 jdk11u OpenJDK 分支以及来自项目 Portola 的移植修复,引入以下内容 公关.非常感谢 Alpine 团队.

<块引用>

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

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

更新,26/12/18: 问题已解决,现在 OpenJDK 11 超薄映像基于最近制作的 stretch-backports OpenJDK 11可用(公关链接).

<块引用>

为什么 OpenJDK 11 的 slim/headless/JRE 包与类似的 OpenJDK 8 包相比如此之大?在 OpenJDK 11 中带来 135 MB 的 modules 文件是什么?

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

modules 文件捆绑了 JRE 附带的所有模块.完整的模块列表可以用 java --list-modules 打印.modules 确实是一个非常大的文件,正如评论中所说,它包含所有标准模块,因此它非常臃肿.

但是需要注意的一件事是它替换了 rt.jartools.jar ,其中不推荐使用,因此在考虑 modules 与 9 之前的 OpenJDK 版本相比,rt.jartools.jar 的大小应该减去(它们应该占用大约 80MB).

Java 11 is announced to be the most recent LTS version. So, we're trying to start new services based on this Java version.

However, the base Docker image for Java 11 is much larger than the equivalent for Java 8:

(I'm considering only the official OpenJDK and the most lightweight images for each Java version.)

Deeper digging uncovered the following "things":

  • the openjdk:11-jre-slim image uses the base image debian:sid-slim. This brings 2 issues:

    • this is 60 MB larger than alpine:3.8

    • the Debian sid versions are unstable

  • the openjdk-11-jre-headless package installed in the image is 3 times larger than openjdk8-jre (inside running Docker container):

    • 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/
      

      Going deeper I discovered the "root" of this heaviness - it's the modules file of the JDK:

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

So, now the questions which came:

  • Why is alpine not used any more as a base image for Java 11 slim images?

  • Why is the unstable sid version used for LTS Java images?

  • Why is the slim/headless/JRE package for OpenJDK 11 so large compared to the similar OpenJDK 8 package?

    • What is this modules file which brings 135 MB in OpenJDK 11?

UPD: as a solutions for these challenges one could use this answer: Java 11 application as docker image

解决方案

Why is alpine not used any more as a base image for Java 11 slim images?

That's because, sadly, there is no official stable OpenJDK 11 build for Alpine currently.

Alpine uses musl libc, as opposed to the standard glibc used by most Linuxes out there, which means that a JVM must be compatible with musl libc for supporting vanilla Alpine. The musl OpenJDK port is being developed under OpenJDK's Portola project.

The current status is summarized on the OpenJDK 11 page:

The Alpine Linux build previously available on this page was removed as of JDK 11 GA. It’s not production-ready because it hasn’t been tested thoroughly enough to be considered a GA build. Please use the early-access JDK 12 Alpine Linux build in its place.

The only stable OpenJDK versions for Alpine currently are 7 and 8, provided by the IcedTea project.

However - if you're willing to consider other than the official OpenJDK, Azul's Zulu OpenJDK offers a compelling alternative:

  • It supports Java 11 on Alpine musl (version 11.0.2 as of the time of writing);
  • It is a certified OpenJDK build, verified using the OpenJDK TCK compliance suite;
  • It is free, open source and docker ready (Dockerhub).

For support availability and roadmap, see Azul support roadmap.

Update, 3/6/19: As of yesterday, openjdk11 is available in Alpine repositories! It could be grabbed on Alpine using:

apk --no-cache add openjdk11

The package is based on the jdk11u OpenJDK branch plus ported fixes from project Portola, introduced with the following PR. Kudos and huge thanks to the Alpine team.

Why is the unstable sid version used for LTS Java images?

That's a fair question / request. There's actually an open ticket for providing Java 11 on a stable Debian release:
https://github.com/docker-library/openjdk/issues/237

Update, 26/12/18: The issue has been resolved, and now the OpenJDK 11 slim image is based on stretch-backports OpenJDK 11 which was recently made available (PR link).

Why is the slim/headless/JRE package for OpenJDK 11 so large compared to the similar OpenJDK 8 package? What is this modules file which brings 135 MB in OpenJDK 11?

Java 9 introduced the module system, which is a new and improved approach for grouping packages and resources, compared to jar files. This article from Oracle gives a very detailed introduction to this feature:
https://www.oracle.com/corporate/features/understanding-java-9-modules.html

The modules file bundles all modules shipped with the JRE. The complete list of modules could be printed with java --list-modules. modules is indeed a very large file, and as commented, it contains all standard modules, and it is therefore quite bloated.

One thing to note however is that it replaces rt.jar and tools.jar which became deprecated, among other things, so when accounting for the size of modules when comparing to pre-9 OpenJDK builds, the sizes of rt.jar and tools.jar should be subtracted (they should take up some 80MB combined).

这篇关于为什么 Java 11 基础 Docker 镜像如此之大?(openjdk:11-jre-slim)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆