首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Java 11应用程序作为轻量级码头映像

Java 11应用程序作为轻量级码头映像
EN

Stack Overflow用户
提问于 2018-12-07 12:01:32
回答 5查看 75.4K关注 0票数 87

为什么Java 11基本码头映像如此之大?(openjdk:11-jre-slim)问题的启发,我发现这个主题在Java中仍然没有解决。

至于07 Dec 2018,有一些常见的问题/陷阱(在上面的票证中讨论过):

代码语言:javascript
复制
- In the same time current stable Debian versions still doesn't have [Java 11 packages](https://packages.debian.org/stable/java/) ([Ubuntu has Java 10 installed](https://packages.ubuntu.com/bionic/java/) under openjdk-11 packages), that's why unstable sid versions are used for base docker images

  • 当前可用的OracleOpenJDK-11映像构建未剥离的libjvm.so模块,该模块有数百兆字节,必须单独删除:
代码语言:javascript
复制
- [jlink runtime image size (specifically libjvm.so) created from openjdk is huge. Expected it to be much smaller.](https://github.com/docker-library/openjdk/issues/217)
- Solution: [https://github.com/docker-library/openjdk/issues/217#issuecomment-436079779](https://github.com/docker-library/openjdk/issues/217#issuecomment-436079779)

由于这些问题,即使是苗条的Oracle 11基映像也很重,并且被认为是不稳定的:/openjdk/

所以问题是:

什么是优化的或推荐以E 227构建和交付Java 11应用程序的方法

EN

回答 5

Stack Overflow用户

回答已采纳

发布于 2018-12-07 12:01:32

UPD来自07.2019https://stackoverflow.com/a/57145029/907576

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

  1. 绝地路径如果我们想在稳定的瘦Linux版本上使用官方的甲骨文OpenJDK发行版(目前是Debian 9 "Stretch"):
代码语言:javascript
复制
- use `debian:stretch-slim` (latest stable) base image
- use [Docker multi-stage build](https://docs.docker.com/develop/develop-images/multistage-build/)
代码语言:javascript
复制
    1. First Docker build stage: 
代码语言:javascript
复制
        - download and install `Oracle OpenJDK` archive on the first Docker build stage
        - compile Java minimal distribution for your project (aka JRE) using `jlink` tool

代码语言:javascript
复制
    1. Second Docker build stage:
代码语言:javascript
复制
        - copy compiled minimal Java distribution from stage 1 to the new image
        - configure path to access Java
        - copy application jar to the image

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

( VERSION**,实现JDK ** URL HASH value):

第一阶段: JDK 11,包含debian的Spring所需的模块:Extension-瘦作为包#源JDK发行名称# https://jdk.java.net/java-se-ri/11 ENV JDK_VERSION="11.0.1“ENV JDK_URL="bin.tar.gz”ENV https://jdk.java.net/java-se-ri/11 ENV JDK_HASH_FILE="${JDK_ARJ_FILE}.sha2“ENV JDK_ARJ_FILE="openjdk-${JDK_VERSION}.tar.gz”#目标JDK安装名称ENV OPT="/opt“ENV JKD_DIR_NAME="jdk-${JDK”_VERSION}“ENV JAVA_HOME=”${OPT}{JKD_DIR_NAME}“ENV JAVA_MINIMAL=”${OPT}/java-在本地文件中添加"$JDK_URL“"$JDK_ARJ_FILE”#校验下载的文件hashsum运行{\ echo验证下载的JDK文件$JDK_ARJ_FILE:&\ echo "$JDK_HASH $JDK_ARJ_FILE“> "$JDK_HASH_FILE”&\sha256sum -c "$JDK_HASH_FILE“;\}#提取JDK并添加到路径运行{\ echo“卸载下载的JDK到${JAVA_HOME}/:”&\ mkdir -p "$OPT“&& tar xf "$JDK_ARJ_FILE”-C "$OPT“;\} ENV PATH="$ PATH :$ java _HOME/bin”运行{\java-version;回显"jlink版本:“&& jlink -版本;#构建模块发行版运行jlink \--详细的\-附加模块\ java.base、java.sql、java.naming、java.desktop、java.management、java.security.jgss、java/lang/instrument/IllegalClassFormatException \# java.naming /命名/NamingException# java.desktop -java/bean/PropertyEditorSupport# java.management - javax/management/MBeanServer # java.security.jgss - org/ietf/jgss/GSSException # java.instrument -压缩2\-条形-调试\-无头文件-无-man-页面\-输出"$JAVA_MINIMAL“#第二阶段只添加我们最小的"JRE“发行版和我们来自debian的应用程序:拉伸-苗条ENV _HOME=/opt/java-最小ENV PATH="$PATH:$JAVA_HOME/bin”COPY - FROM =packager "$JAVA_HOME“"$JAVA_HOME”COPY“build/libs/spring demo.jar”"/app.jar“公开8080 CMD "-jar","/app.jar”ENTRYPOINT "java“

Note:

代码语言:javascript
复制
- there are 5 java modules included to the minimal JRE example (`java.base,java.sql,java.naming,java.desktop,java.management,java.security.jgss,java.instrument`). I found them "manually" running the application and fixing `ClassNotFoundException`. Waiting for some further Spring Boot developers recommendations/guides which Java modules to include and when, as same as removing some redundant dependencies, like `java.desktop`, which seems to be used only for `PropertyEditorSupport`
- if you are afraid to miss some modules - they are quite lightweight and all of them together give about 2 MB size increasing. Get a full list of `java.*` and `jdk.*` 11 modules:

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

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

在我的例子中,得到的映像大小是123 MB和最小7个Spring模块,125 MB和所有java.*模块

作为此构建工作流的可选改进

代码语言:javascript
复制
- Pre-build an image with downloaded and extracted JDK and use it as a base image for first stage
- if you know which modules to include every time - pre-build a base image with compiled minimal JRE and included modules

  1. 使用供应商的Open发行版的简单方法: 相对于甲骨文,阿祖尔的祖鲁JDK 11支持高山港,并有各自的基本码头形象

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

代码语言:javascript
复制
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" ]

得到的映像为73 MB,与剥离的高山发行版预期的一样。

票数 100
EN

Stack Overflow用户

发布于 2019-07-22 11:23:33

截至07.2019

(Note:第一级图像可以像你想的那样胖:你可以使用debian/ubuntu/什么,包括git/gradle/什么-这不会影响最终的图像大小,这完全是基于最后(第二阶段))

使用高山社区储存库

代码语言:javascript
复制
FROM alpine:latest as packager

RUN apk --no-cache add openjdk11-jdk openjdk11-jmods

ENV JAVA_MINIMAL="/opt/java-minimal"

# build minimal JRE
RUN /usr/lib/jvm/java-11-openjdk/bin/jlink \
    --verbose \
    --add-modules \
        java.base,java.sql,java.naming,java.desktop,java.management,java.security.jgss,java.instrument \
    --compress 2 --strip-debug --no-header-files --no-man-pages \
    --release-info="add:IMPLEMENTOR=radistao:IMPLEMENTOR_VERSION=radistao_JRE" \
    --output "$JAVA_MINIMAL"

FROM alpine:latest

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

COPY --from=packager "$JAVA_HOME" "$JAVA_HOME"
COPY build/libs/application.jar app.jar

ENTRYPOINT ["java","-jar","/app.jar"]

使用AdoptOpenJDK

代码语言:javascript
复制
FROM adoptopenjdk/openjdk11:x86_64-alpine-jdk-11.0.4_11 as packager

ENV JAVA_MINIMAL="/opt/java-minimal"

# build minimal JRE
RUN jlink \
    --verbose \
    --add-modules \
        java.base,java.sql,java.naming,java.desktop,java.management,java.security.jgss,java.instrument \
    --compress 2 --strip-debug --no-header-files --no-man-pages \
    --output "$JAVA_MINIMAL"

FROM alpine:latest

# magic to make Java binaries work in Alpine
# https://github.com/AdoptOpenJDK/openjdk-docker/blob/master/11/jdk/alpine/Dockerfile.hotspot.releases.slim#L24-L54
RUN apk add --no-cache --virtual .build-deps curl binutils \
    && GLIBC_VER="2.29-r0" \
    && ALPINE_GLIBC_REPO="https://github.com/sgerrand/alpine-pkg-glibc/releases/download" \
    && GCC_LIBS_URL="https://archive.archlinux.org/packages/g/gcc-libs/gcc-libs-9.1.0-2-x86_64.pkg.tar.xz" \
    && GCC_LIBS_SHA256="91dba90f3c20d32fcf7f1dbe91523653018aa0b8d2230b00f822f6722804cf08" \
    && ZLIB_URL="https://archive.archlinux.org/packages/z/zlib/zlib-1%3A1.2.11-3-x86_64.pkg.tar.xz" \
    && ZLIB_SHA256=17aede0b9f8baa789c5aa3f358fbf8c68a5f1228c5e6cba1a5dd34102ef4d4e5 \
    && curl -LfsS https://alpine-pkgs.sgerrand.com/sgerrand.rsa.pub -o /etc/apk/keys/sgerrand.rsa.pub \
    && SGERRAND_RSA_SHA256="823b54589c93b02497f1ba4dc622eaef9c813e6b0f0ebbb2f771e32adf9f4ef2" \
    && echo "${SGERRAND_RSA_SHA256} */etc/apk/keys/sgerrand.rsa.pub" | sha256sum -c - \
    && curl -LfsS ${ALPINE_GLIBC_REPO}/${GLIBC_VER}/glibc-${GLIBC_VER}.apk > /tmp/glibc-${GLIBC_VER}.apk \
    && apk add /tmp/glibc-${GLIBC_VER}.apk \
    && curl -LfsS ${ALPINE_GLIBC_REPO}/${GLIBC_VER}/glibc-bin-${GLIBC_VER}.apk > /tmp/glibc-bin-${GLIBC_VER}.apk \
    && apk add /tmp/glibc-bin-${GLIBC_VER}.apk \
    && curl -Ls ${ALPINE_GLIBC_REPO}/${GLIBC_VER}/glibc-i18n-${GLIBC_VER}.apk > /tmp/glibc-i18n-${GLIBC_VER}.apk \
    && apk add /tmp/glibc-i18n-${GLIBC_VER}.apk \
    && /usr/glibc-compat/bin/localedef --force --inputfile POSIX --charmap UTF-8 "$LANG" || true \
    && echo "export LANG=$LANG" > /etc/profile.d/locale.sh \
    && curl -LfsS ${GCC_LIBS_URL} -o /tmp/gcc-libs.tar.xz \
    && echo "${GCC_LIBS_SHA256} */tmp/gcc-libs.tar.xz" | sha256sum -c - \
    && mkdir /tmp/gcc \
    && tar -xf /tmp/gcc-libs.tar.xz -C /tmp/gcc \
    && mv /tmp/gcc/usr/lib/libgcc* /tmp/gcc/usr/lib/libstdc++* /usr/glibc-compat/lib \
    && strip /usr/glibc-compat/lib/libgcc_s.so.* /usr/glibc-compat/lib/libstdc++.so* \
    && curl -LfsS ${ZLIB_URL} -o /tmp/libz.tar.xz \
    && echo "${ZLIB_SHA256} */tmp/libz.tar.xz" | sha256sum -c - \
    && mkdir /tmp/libz \
    && tar -xf /tmp/libz.tar.xz -C /tmp/libz \
    && mv /tmp/libz/usr/lib/libz.so* /usr/glibc-compat/lib \
    && apk del --purge .build-deps glibc-i18n \
    && rm -rf /tmp/*.apk /tmp/gcc /tmp/gcc-libs.tar.xz /tmp/libz /tmp/libz.tar.xz /var/cache/apk/*

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

COPY --from=packager "$JAVA_HOME" "$JAVA_HOME"
COPY build/libs/application.jar app.jar

ENTRYPOINT ["java","-jar","/app.jar"]

还读了https://blog.gilliard.lol/2018/11/05/alpine-jdk11-images.html

票数 26
EN

Stack Overflow用户

发布于 2020-09-22 20:17:50

jdk 11图像按大小分列列表

代码语言:javascript
复制
openjdk:11.0.6-jre-buster
openjdk:11.0.6-jre
openjdk:11.0.6-jre-slim-buster
openjdk:11.0.6-jre-slim
openjdk:11.0.6-jre-stretch
adoptopenjdk:11.0.6_10-jre-openj9-0.18.1
adoptopenjdk:11.0.6_10-jre-hotspot
adoptopenjdk:11.0.6_10-jre-openj9-0.18.1-bionic
adoptopenjdk:11.0.6_10-jre-hotspot-bionic
adoptopenjdk/openjdk11:jre-11.0.6_10-ubuntu
adoptopenjdk/openjdk11:jre-11.0.6_10
adoptopenjdk/openjdk11:jre-11.0.6_10-ubi-minimal
adoptopenjdk/openjdk11:jre-11.0.6_10-ubi
adoptopenjdk/openjdk11:jre-11.0.6_10-debianslim
adoptopenjdk/openjdk11:jre-11.0.6_10-debian
adoptopenjdk/openjdk11:jre-11.0.6_10-centos
adoptopenjdk/openjdk11:jre-11.0.6_10-alpine
adoptopenjdk/openjdk11:x86_64-alpine-jre-11.0.6_10
adoptopenjdk/openjdk11:x86_64-debian-jre-11.0.6_10
adoptopenjdk/openjdk11:x86_64-debianslim-jre-11.0.6_10
adoptopenjdk/openjdk11:x86_64-ubi-jre-11.0.6_10
adoptopenjdk/openjdk11:x86_64-ubi-minimal-jre-11.0.6_10
adoptopenjdk/openjdk11:x86_64-centos-jre-11.0.6_10
adoptopenjdk/openjdk11:x86_64-ubuntu-jre-11.0.6_10
mcr.microsoft.com/java/jre:11u6-zulu-alpine
mcr.microsoft.com/java/jre:11u6-zulu-centos
mcr.microsoft.com/java/jre:11u6-zulu-debian8
mcr.microsoft.com/java/jre:11u6-zulu-debian9
mcr.microsoft.com/java/jre:11u6-zulu-debian10
mcr.microsoft.com/java/jre:11u6-zulu-ubuntu
azul/zulu-openjdk-alpine:11.0.6-jre

票数 17
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/53669151

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档