为什么基于Java 11的Docker映像这么大?(OpenJDK:11-JRE-SLIM)

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

然而,Java 11的基础Docker映像比Java 8的相应映像大得多:

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

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

  • openjdk:11-jre-slim图像使用基本图像debian:sid-slim。这带来了两个问题:

    • 这比alpine:3.8大60 MB

    • Debiansid版本不稳定

  • 镜像中安装

    openjdk-11-jre-headless3倍大,而不是openjdk8-jre(在运行的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/modules
      135M    /usr/lib/jvm/java-11-openjdk-amd64/lib/modules
      

所以,现在的问题是:

  • 为什么alpine不再用作Java11Slim映像的基础映像?

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

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

    • 这个在OpenJDK 11中带来135MB的模块文件是什么?

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

143860 次浏览

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).

as for 07.2019 https://adoptopenjdk.net/ has official Alpine support for Java 11:

However, modules (jmods, jlink) still shall be considered when one assembles minimal application.

Note: slim images don't contain some modules (like java.sql) - they are excluded explicitly (https://github.com/AdoptOpenJDK/openjdk-docker/blob/21b8393b9c23f94d6921a56cce27b026537c6ca2/11/jdk/alpine/slim-java.sh#L233)

https://hub.docker.com/_/openjdk?tab=tags&page=1&name=11.0.7-jre-slim

in docker openjdk repository, slim jre 11 image is less than 70mb

If you are considering only Official Images and your target achievement is to use the smaller JRE image available, I would suggest you to look at the official OpenJDK image openjdk:11-jre-slim-buster which is just 69.2 MB.