Рубрики
Без рубрики

Создайте самый маленький образ Docker с помощью JHipster 6 и Java 11+

В этой статье будет объяснено, как создать наименьший возможный образ Docker с помощью JHipster 6 и Java… Помеченный docker, java, angular.

В этой статье будет объяснено, как создать наименьший возможный образ Docker с помощью JHipster 6 и Java 11+.

Обязательно сначала прочтите “Лучшую, более быструю и легкую Java с Java 12 и JHipster 6” Мэтта Райбла.

Сегодня (понедельник, 13 мая 2019 года) Мохаммед Абуллайт (из Devoxx Morocco) выступил с потрясающим докладом на тему “Контейнеры Docker и java: Что бы я хотел, чтобы мне сказали!” с большим количеством интересной информации. Не забудьте проверить его слайд-деку.

Вы можете пропустить эту часть, если на вашем компьютере для разработки уже запущена Java 11.

SDKman – отличный инструмент для установки нескольких версий Java. Этот инструмент также позволяет вам очень легко переключаться между различными версиями java. # Должен иметь

После установки вы можете перечислить все доступные версии Java SDK.

$ sdk list java Вы можете выбрать (и установить) версию Java 11 SDK следующим образом:

$ sdk использует java 11.0.3-зулу Теперь мы можем изменить maven pom.xml java.версия от 1.8 до 11.

11

Файлы SDK расположены в скрытом каталоге .sdkman, что немного затрудняет повторное использование в IDEA. Добавление символической ссылки – это прагматичное решение:

$ cd /Library/Java/JavaVirtualMachines

$ sudo ln -s /Users/stephan/.sdkman/candidates/java/11.0.3-zulu 11.0.03-zulu

Теперь вы можете добавить SDK 11 к своей ИДЕЕ.

JHipster предоставляет файл Dockerfile, который находится в src/main/docker:

FROM openjdk:11-jre-slim-stretch

ENV SPRING_OUTPUT_ANSI_ENABLED=ALWAYS \
    JHIPSTER_SLEEP=0 \
    JAVA_OPTS=""

# Add a jhipster user to run our application so that it doesn't need to run as root
RUN adduser -D -s /bin/sh jhipster

WORKDIR /home/jhipster

ADD entrypoint.sh entrypoint.sh
RUN chmod 755 entrypoint.sh && chown jhipster:jhipster entrypoint.sh
USER jhipster

ENTRYPOINT ["./entrypoint.sh"]

EXPOSE 8080

ADD *.war app.war

У меня есть несколько проблем с этим файлом Dockerfile, главная из которых… это не работает 😂

Обязательно прочтите дополнение, почему файл Dockerfile поврежден.

1) Команда adduser выдает ошибку при создании образа Docker.

Option d is ambiguous (debug, disabled-login, disabled-password)
Option s is ambiguous (shell, system)
adduser [--home DIR] [--shell SHELL] [--no-create-home] [--uid ID]
[--firstuid ID] [--lastuid ID] [--gecos GECOS] [--ingroup GROUP | --gid ID]
[--disabled-password] [--disabled-login] [--add_extra_groups] USER
   Add a normal user


adduser --system [--home DIR] [--shell SHELL] [--no-create-home] [--uid ID]
[--gecos GECOS] [--group | --ingroup GROUP | --gid ID] [--disabled-password]
[--disabled-login] [--add_extra_groups] USER
   Add a system user


adduser --group [--gid ID] GROUP
addgroup [--gid ID] GROUP
   Add a user group


addgroup --system [--gid ID] GROUP
   Add a system group


adduser USER GROUP
   Add an existing user to an existing group


general options:
  --quiet | -q      don't give process information to stdout
  --force-badname   allow usernames which do not match the
                    NAME_REGEX configuration variable
  --help | -h       usage message
  --version | -v    version number and copyright
  --conf | -c FILE  use FILE as configuration file

Команда ‘/bin/sh -c adduser -D -s/bin/sh jhipster’ вернула ненулевой код: 1

2) Файл Dockerfile должен добавлять файл JAR, а не файл war (см. maven pom.xml поле упаковки файла).

В entrypoint.sh сценарий также должен использовать jar-файл вместо war.

#!/bin/sh

echo "The application will start in ${JHIPSTER_SLEEP}s..." && sleep ${JHIPSTER_SLEEP}
exec java ${JAVA_OPTS} -noverify -XX:+AlwaysPreTouch -Djava.security.egd=file:/dev/./urandom -jar "${HOME}/app.war" "$@"

DockerFile V2
FROM openjdk:11-jre-slim-stretch

ENV SPRING_OUTPUT_ANSI_ENABLED=ALWAYS \
    JHIPSTER_SLEEP=0 \
    JAVA_OPTS=""

# Add a jhipster user to run our application so that it doesn't need to run as root
RUN adduser --home /home/jhipster --disabled-password jhipster

WORKDIR /home/jhipster

ADD entrypoint.sh entrypoint.sh
RUN chmod 755 entrypoint.sh && chown jhipster:jhipster entrypoint.sh
USER jhipster

ENTRYPOINT ["./entrypoint.sh"]

EXPOSE 8080

ADD *.jar app.jar

Это создает образ Docker размером 340 МБ, но можем ли мы сделать его меньше?

Файл JHipster Dockerfile использует образ среды выполнения OpenJDK 11, основанный на Debian, что частично объясняет, почему размер образа составляет 340 МБ. Переход на Alpine Linux – лучшая стратегия!

Мохаммед из DevoxxMA предложил рассмотреть еще меньшую возможность, используя “Бездисковые” изображения Docker от Google. # Нужно Больше Времени Для Расследования

ПОДСКАЗКА: Подумайте о том, чтобы посмотреть эту очень интересную презентацию Voxxed Days Zurich 2019 от Мэтью Гиллиарда о контейнерах Java. Он берет пример Hello World и развертывает его, используя различные стратегии, включая собственные изображения.

Azul предоставляет дистрибутив Alpine Linux OpenJDK для Java 11, лучшее из обоих миров!

Среда выполнения Azul интегрирует и изначально поддерживает библиотеку musl, что делает интеграцию более эффективной (с точки зрения занимаемой площади и производительности во время выполнения).

Смотрите также проект Portola – Цель этого проекта – предоставить порт JDK для дистрибутива Alpine Linux и, в частности, библиотеки musl C.

Теперь, когда мы (наконец-то) перешли на Java 9+, мы можем воспользоваться преимуществами системы Java modules. Это означает, что мы можем создать пользовательскую JVM, которая включает в себя только модули Java, используемые нашим приложением.

Чтобы выяснить, какие модули используются, мы можем использовать jdeps для самоанализа нашего jar-файла проекта.

$ jdeps --list-deps myapp-1.0.0.jar

java.base
java.logging
java.sql

Похоже, для приложения требуется всего 3 модуля Java. К сожалению, это неверно, подробнее об этом позже.

Следующий шаг – создать пользовательскую JVM с помощью j link и добавить 3 необходимых модуля:

$ jlink --output myjdk --module-path $JAVA_HOME/jmods --add-modules java.base,java.sql,java.logging

Приведенная выше команда создает каталог my jdk, в который включено все необходимое для запуска нашего jar-файла.

После запуска приложения JHipster на рабочей машине я заметил, что для запуска веб-приложения Spring Boot с использованием Java 11 по-прежнему не хватает нескольких модулей.

java.desktop       // For Java Beans getter's and setters
java.management    // JMX 
jdk.management     // JDK-specific management interfaces for the JVM
java.naming        // JNDI
jdk.unsupported    // Sun.misc.Unsafe
jdk.crypto.ec      // SSL
java.net.http      // HTTP

Очевидно, что в зависимости от функциональности вашего проекта вам потребуется добавить больше модулей.

Теперь, когда мы знаем, какие модули Java требуются, мы можем создать следующий файл Dockerfile.

Часть 1: Возьмите jvm Azul zulu OpenJDK и создайте пользовательскую JVM в каталоге/jlinked.

Часть 2

Используйте Alpine linux и скопируйте связанный JDK в/opt/jdk и запустите java-приложение. Undertow вынудил меня запустить Spring Boot от имени root, потому что в противном случае он мог бы не открывать некоторые сокеты. Необходимо дальнейшее расследование, предложения всегда приветствуются.

#
# Part 1
#

FROM azul/zulu-openjdk-alpine:11 as zulu

RUN export ZULU_FOLDER=`ls /usr/lib/jvm/` \
    && jlink --compress=1 --strip-debug --no-header-files --no-man-pages \
    --module-path /usr/lib/jvm/$ZULU_FOLDER/jmods \
    --add-modules java.desktop,java.logging,java.sql,java.management,java.naming,jdk.unsupported,jdk.management,jdk.crypto.ec,java.net.http \
    --output /jlinked

#
# Part 2
#

FROM alpine:latest

COPY --from=zulu /jlinked /opt/jdk/

RUN apk update
RUN rm -rf /var/cache/apk/*

ENV CFP_JAVA_OPTS="-Xmx512m"
ENV CFP_PERFORMANCE_OPTS="-Dspring.jmx.enabled=false -Dlog4j2.disableJmx=true"

CMD /opt/jdk/bin/java $CFP_JAVA_OPTS $CFP_PERFORMANCE_OPTS -XX:+UseContainerSupport \
                           -noverify -XX:+AlwaysPreTouch -Djava.security.egd=file:/dev/./urandom -jar /app.jar

ADD target/*.jar /app.jar

EXPOSE 80

Приведенный выше пример в значительной степени вдохновлен ALF.io предоставленный файл Dockerfile Теперь у нас есть 180-мегабайтный образ Docker, который мы можем развернуть в рабочей среде 😎 💪🏻

В моем списке дел – изучить Общий доступ к данным класса приложений (CDS), при правильной настройке время запуска приложения может быть на 25% быстрее!

CDS была единственной коммерческой функцией Oracle JDK начиная с версии 7, но она также была доступна в OpenJ9 и теперь включена в OpenJDK начиная с версии 10.

Другая стратегия для исследования – использовать разнесенный файл jar, не уверен, что это даст какое-либо заметное увеличение времени запуска?

Абсолютно!

Представьте, что JHipster мог бы создать проект Quark u s и/или Micronaut на основе вашего JDL. Это означало бы, что мы могли бы создать собственный образ благодаря GraalVM.

Создание еще меньшего изображения Docker и потрясающий быстрый запуск … великолепная комбинация с Google Cloud Run!

Комментарии и предложения очень приветствуются!

Овации,

Стефан

Часть 2 этой серии статей теперь доступна @ Часть 2 этой серии статей теперь доступна @

Кливер

Немедленный ответ на мою статью пришел от Кристофа, спасибо за отзыв!

Похоже, что JHipster теперь использует Jib вместо предоставленного Dockerfile. Нужно будет выяснить, как выглядит Dockerfile и предоставляет ли он изображение меньшего размера?!

Jib создает оптимизированные образы Docker и OCI для ваших Java-приложений без демона Docker и без глубокого знания лучших практик Docker. Он доступен в виде плагинов для Maven и Gradle, а также в виде библиотеки Java.

./mvnw package -Pprod verify jib:dockerBuild
More details @ https://www.jhipster.tech/docker-compose/#-building-and-running-a-docker-image-of-your-application

Другой ответ на статью сообщил мне, что команда Hipster перешла на OpenJDK 11 с использованием Alpine 3 дня назад. Вот что мне нравится в хипстерах, они на вершине своей игры!

Мой друг из Марокко Devoxx Мохаммед (и чемпион Docker) предложил в ответе в Твиттере взглянуть на изображения docker без дистрибутивов Google. Выглядит действительно очень многообещающе, нужно больше времени для расследования 😄

Spring Boot использует Undertow и зависит от jboss XNIO-NIO. В результате Java 11 выдаст предупреждение: незаконная операция отражающего доступа.

Переключение на причал вместо подводного течения может решить эту проблему?

WARNING: An illegal reflective access operation has occurred

[dvbe19-cfp-app-64676889d-4g8nv dvbe19-app] WARNING: Illegal reflective access by org.xnio.nio.NioXnio$2 (jar:file:/app.jar!/BOOT-INF/lib/xnio-nio-3.3.8.Final.jar!/) to constructor sun.nio.ch.EPollSelectorProvider()

[dvbe19-cfp-app-64676889d-4g8nv dvbe19-app] WARNING: Please consider reporting this to the maintainers of org.xnio.nio.NioXnio$2

[dvbe19-cfp-app-64676889d-4g8nv dvbe19-app] WARNING: Use --illegal-access=warn to enable warnings of further illegal reflective access operations

[dvbe19-cfp-app-64676889d-4g8nv dvbe19-app] WARNING: All illegal access operations will be denied in a future release

И еще одно рефлексивное предупреждение. Но для этого у нас нет альтернативы (пока).

[INFO] --- maven-war-plugin:2.2:war (default-war) @ cfp ---
WARNING: An illegal reflective access operation has occurred
WARNING: Illegal reflective access by com.thoughtworks.xstream.core.util.Fields (file:/Users/stephan/.m2/repository/com/thoughtworks/xstream/xstream/1.3.1/xstream-1.3.1.jar) to field java.util.Properties.defaults
WARNING: Please consider reporting this to the maintainers of com.thoughtworks.xstream.core.util.Fields
WARNING: Use --illegal-access=warn to enable warnings of further illegal reflective access operations
WARNING: All illegal access operations will be denied in a future release
References
https://developer.okta.com/blog/2019/04/04/java-11-java-12-jhipster-oidc
https://spring.io/blog/2018/12/12/how-fast-is-spring
https://blog.gilliard.lol/2018/11/05/alpine-jdk11-images.html
https://docs.oracle.com/en/java/javase/11/vm/class-data-sharing.html
Docker containers & java: What I wish I've been told! https://docs.google.com/presentation/d/1d2L6O6WELVT6rwwhiw_Z9jBnFzVPtku4URPt4KCsWZQ/edit#slide=id.g5278af057a_0_124
"Docker containers & java: What I wish I've been told!" Video @ https://www.docker.com/dockercon/2019-videos?watch=docker-containers-java-what-i-wish-i-had-been-told

Оригинал: “https://dev.to/stephan007/create-the-smallest-docker-image-using-jhipster-6-and-java-11-35m7”