您好, 欢迎来到 !    登录 | 注册 | | 设为首页 | 收藏本站

Java 11应用程序作为轻量级Docker映像

Java 11应用程序作为轻量级Docker映像

到目前为止,以简单的spring boot应用程序为例(只有一个REST端点),我能够找出以下解决方案(考虑到应用程序jar位于build/libs/spring-boot- demo.jarDocker构建之前):

__如果我们想 使用 绝地路径Debian 9 "Stretch"目前):

使用Docker多阶段构建

一个Docker构建阶段:

使用jlink工具为您的项目(又名JRE)编译Java最小发行版

从第1阶段将已编译的最小Java发行版复制到新映像

所以,最终Dockerfile看起来像这样

( ):

    # First stage: JDK 11 with modules required for Spring Boot
FROM debian:stretch-slim as packager

# source JDK distribution names
# update from https://jdk.java.net/java-se-ri/11
ENV JDK_VERSION="11.0.1"
ENV JDK_URL="https://download.java.net/java/GA/jdk11/13/GPL/openjdk-${JDK_VERSION}_linux-x64_bin.tar.gz"
ENV JDK_HASH="7a6bb980b9c91c478421f865087ad2d69086a0583aeeb9e69204785e8e97dcfd"
ENV JDK_HASH_FILE="${JDK_ARJ_FILE}.sha2"
ENV JDK_ARJ_FILE="openjdk-${JDK_VERSION}.tar.gz"
# target JDK installation names
ENV OPT="/opt"
ENV JKD_DIR_NAME="jdk-${JDK_VERSION}"
ENV JAVA_HOME="${OPT}/${JKD_DIR_NAME}"
ENV JAVA_MINIMAL="${OPT}/java-minimal"

# downlodad JDK to the local file
ADD "$JDK_URL" "$JDK_ARJ_FILE"

# verify downloaded file hashsum
RUN { \
        echo "Verify downloaded JDK file $JDK_ARJ_FILE:" && \
        echo "$JDK_HASH $JDK_ARJ_FILE" > "$JDK_HASH_FILE" && \
        sha256sum -c "$JDK_HASH_FILE" ; \
    }

# extract JDK and add to PATH
RUN { \
        echo "Unpack downloaded JDK to ${JAVA_HOME}/:" && \
        mkdir -p "$OPT" && \
        tar xf "$JDK_ARJ_FILE" -C "$OPT" ; \
    }
ENV PATH="$PATH:$JAVA_HOME/bin"

RUN { \
        java --version ; \
        echo "jlink version:" && \
        jlink --version ; \
    }

# build modules distribution
RUN jlink \
    --verbose \
    --add-modules \
        java.base,java.sql,java.naming,java.desktop,java.management,java.security.jgss,java.instrument \
        # java.naming - javax/naming/NamingException
        # java.desktop - java/beans/propertyeditorSupport
        # java.management - javax/management/MBeanServer
        # java.security.jgss - org/ietf/jgss/GSSException
        # java.instrument - java/lang/instrument/IllegalClassFormatException
    --compress 2 \
    --strip-debug \
    --no-header-files \
    --no-man-pages \
    --output "$JAVA_MINIMAL"

# Second stage, add only our minimal "JRE" distr and our app
FROM debian:stretch-slim

ENV JAVA_HOME=/opt/java-minimal
ENV PATH="$PATH:$JAVA_HOME/bin"

COPY --from=packager "$JAVA_HOME" "$JAVA_HOME"
COPY "build/libs/spring-boot-demo.jar" "/app.jar"

EXPOSE 8080
CMD [ "-jar", "/app.jar" ]
ENTRYPOINT [ "java" ]

* 最小JRE示例(`java.base,java.sql,java.naming,java.desktop,java.management,java.security.jgss,java.instrument`)中包含5个Java模块。我发现他们“手动”运行应用程序并修复`ClassNotFoundException`。等待更多的Spring Boot开发人员建议/指南,包括哪些Java模块以及何时包括,这与删除一些冗余依赖项(如)相同`java.desktop`,似乎仅用于`propertyeditorSupport`
* 如果您害怕错过某些模块-它们非常轻巧,并且所有模块加在一起大约增加2 MB的大小。获取`java.*`和`jdk.*`11个模块的完整列表:

java --list-modules | grep -E "^java\.[^@]*" | cut -d @ -f 1java --list-modules | grep -E "^jdk\.[^@]*" | cut -d @ -f 1

在我的情况下,最终的映像大小为 (最少7个Spring Boot模块),所有模块为 java.*

* 使用下载并提取的JDK预先构建映像,并将其用作第一阶段的基础映像
* 如果您每次都知道要包含哪些模块,请使用已编译的最小JRE和包含的模块预先构建基本映像

与Oracle Azul相反,Zulu JDK 11支持Alpine端口并具有各自的基础Docker映像

因此,如果尊重Zulu JVM / JDK,则Docker构建会简单得多:

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

RUN { \
        java --version ; \
        echo "jlink version:" && \
        jlink --version ; \
    }

ENV JAVA_MINIMAL=/opt/jre

# build modules distribution
RUN jlink \
    --verbose \
    --add-modules \
        java.base,java.sql,java.naming,java.desktop,java.management,java.security.jgss,java.instrument \
        # java.naming - javax/naming/NamingException
        # java.desktop - java/beans/propertyeditorSupport
        # java.management - javax/management/MBeanServer
        # java.security.jgss - org/ietf/jgss/GSSException
        # java.instrument - java/lang/instrument/IllegalClassFormatException
    --compress 2 \
    --strip-debug \
    --no-header-files \
    --no-man-pages \
    --output "$JAVA_MINIMAL"

# Second stage, add only our minimal "JRE" distr and our app
FROM alpine

ENV JAVA_MINIMAL=/opt/jre
ENV PATH="$PATH:$JAVA_MINIMAL/bin"

COPY --from=packager "$JAVA_MINIMAL" "$JAVA_MINIMAL"
COPY "build/libs/spring-boot-demo.jar" "/app.jar"

EXPOSE 8080
CMD [ "-jar", "/app.jar" ]
ENTRYPOINT [ "java" ]

生成的图像为 ,与剥离的Alpine发行版预期的一样。

java 2022/1/1 18:14:07 有642人围观

撰写回答


你尚未登录,登录后可以

和开发者交流问题的细节

关注并接收问题和回答的更新提醒

参与内容的编辑和改进,让解决方法与时俱进

请先登录

推荐问题


联系我
置顶