Почему базовый образ Docker для Java 11 такой большой? (OpenJDK: 11-JRE-тонкий)

Java 11 объявлена самой последней версией LTS. Итак, мы пытаемся запустить новые сервисы на основе этой версии Java.

Однако базовый образ Docker для Java 11 намного больше, чем эквивалент для Java 8:

(Я рассматриваю только официальный OpenJDK и самые легкие изображения для каждой версии Java.)

При более глубоком копании были обнаружены следующие "вещи":

  • изображение openjdk:11-jre-slim использует базовое изображение debian:sid-slim. Это приносит 2 проблемы:

    • это на 60 МБ больше, чем у alpine:3.8

    • версии sid Debian нестабильны

  • openjdk-11-jre-headless, установленный в образе, в 3 раза больше, чем 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/
      

      Пройдя глубже, я обнаружил "корень" этой тяжести - файл modules JDK:

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

Итак, теперь вопросы, которые пришли:

  • Почему alpine не используется в качестве базового образа для изображений Java 11 slim?

  • Почему нестабильная версия sid используется для образов LTS Java?

  • Почему пакет slim/headless/JRE для OpenJDK 11 такой большой по сравнению с аналогичным пакетом OpenJDK 8?

    • Что это за файл модулей, который приносит 135 МБ в OpenJDK 11?

UPD: в качестве решения этих проблем можно использовать этот ответ: приложение Java 11 как образ докера

Ответ 1

Почему alpine не используется в качестве базового образа для изображений Java 11 slim?

Это потому, что, к сожалению, в настоящее время нет официальной стабильной сборки OpenJDK 11 для Alpine.

Alpine использует musl libc, в отличие от стандартного glibc, используемого большинством Linux-систем, что означает, что JVM должна быть совместима с musl libc для поддержки vanilla Alpine. Порт musJ OpenJDK разрабатывается в рамках проекта OpenJDK Portola.

Текущий статус представлен на странице OpenJDK 11:

  • Сборка Alpine Linux, ранее доступная на этой странице, была удалена с JDK 11 GA. Он не готов к производству, потому что он не был достаточно тщательно протестирован, чтобы считаться сборкой GA. Пожалуйста, используйте раннюю сборку JDK 12 Alpine Linux вместо нее.

Единственными стабильными версиями OpenJDK для Alpine в настоящее время являются 7 и 8, предоставленные проектом IcedTea.

Тем не менее - если вы готовы рассмотреть иное, нежели официальный OpenJDK, Azul Zulu OpenJDK предлагает убедительную альтернативу:

  • Он поддерживает Java 11 на Alpine musl (версия 11.0.2 на момент написания статьи);
  • Это сертифицированная сборка OpenJDK, проверенная с использованием пакета соответствия OpenJDK TCK;
  • Это бесплатно, с открытым исходным кодом и Docker готов (Dockerhub).

Информация о доступности и планах поддержки приведена в разделе Схема поддержки Azul.

Обновление от 06.03.19: со вчерашнего дня openjdk11 доступен в репозиториях Alpine! Это может быть получено на Alpine с помощью:

apk --no-cache add openjdk11

Пакет основан на jdk11u OpenJDK и портированных исправлениях из проекта Portola, представленных в следующем PR. Слава и огромное спасибо альпийской команде.

Почему нестабильная версия sid используется для образов LTS Java?

Это честный вопрос/запрос. На самом деле есть открытый билет для предоставления Java 11 в стабильной версии Debian:
https://github.com/docker-library/openjdk/issues/237

Обновление, 26/12/18: проблема была решена, и теперь тонкий образ OpenJDK 11 основан на stretch-backports OpenJDK 11, который недавно был доступен (ссылка для связи с общественностью).

Почему пакет slim/headless/JRE для OpenJDK 11 такой большой по сравнению с аналогичным пакетом OpenJDK 8? Что это за файл модулей, который приносит 135 МБ в OpenJDK 11?

Java 9 представила систему модулей, которая представляет собой новый и улучшенный подход для группировки пакетов и ресурсов по сравнению с файлами JAR. Эта статья от Oracle дает очень подробное введение в эту функцию:
https://www.oracle.com/corporate/features/understanding-java-9-modules.html

Файл modules объединяет все модули, поставляемые с JRE. Полный список модулей можно распечатать с помощью java --list-modules. modules действительно очень большой файл, и, как прокомментировано, он содержит все стандартные модули, и поэтому он довольно раздутый.

Однако следует отметить, что он заменяет rt.jar и tools.jar которые, помимо прочего, устарели, поэтому при учете размера modules сравнению с сборками OpenJDK до 9, размеров rt.jar и tools.jar должна быть вычтена (они должны занимать около 80 МБ вместе взятых).

Ответ 2

по состоянию на 07.2019 https://adoptopenjdk.net/ имеет официальную поддержку Alpine для Java 11:

Тем не менее, модули (jmods, jlink) по-прежнему должны учитываться при сборке минимального приложения.

Примечание. Тонкие изображения не содержат некоторые модули (например, java.sql) - они исключаются явно (https://github.com/AdoptOpenJDK/openjdk-docker/blob/21b8393b9c23f94d6921a56cce27b026537c6ca2/11/jdk/alpine/slim-java. ш # L233)