删除不再需要的文件后,如何在Docker Image中回收空间(java jdk 11用来做jre)。

问题描述 投票:1回答:1

我在一个Java应用中使用Docker,之前我使用的是 Java 8 JRE 而我的docker镜像总大小是 163MB后来,我转而使用Java 11 JRE,大小增加到------。230MB如果可能的话,我希望不要增加大小。

但是Java 11允许你建立自己的JRE(使用 jlink 的JDK),只包含你需要的模块。所以我修改了我的DockerFile,使其基于JDK而不是JRE,然后我用它来构建只包含我需要的模块的JRE,并在我的应用程序文件夹中创建了这个。然后我使用 rm -fr /opt/java 移除JDK,因为我不再需要它,假设这将缩小图像的大小,但它没有,现在的图像是 553MB. 我的应用程序可以运行,但没有必要使用 jlink 如果我不能缩小图像的大小,我做错了什么?

下面是Docker文件。

FROM adoptopenjdk/openjdk11:alpine

RUN apk --no-cache add \
      ca-certificates \
      curl \
      fontconfig \
      msttcorefonts-installer \
      tini \
 && update-ms-fonts \
 && fc-cache -f

RUN mkdir -p /opt \
 && curl http://www.jthink.net/songkong/downloads/build1114/songkong-linux-docker.tgz?val=130| tar -C /opt -xzf - \
&& find /opt/songkong -perm /u+x -type f -print0 | xargs -0 chmod a+x

RUN /opt/java/openjdk/bin/jlink --module-path=/opt/java/openjdk/jmods \
--add-modules java.desktop,java.datatransfer,java.logging,java.management,java.naming,java.net.http,java.prefs,java.scripting,java.sql,jdk.management,jdk.unsupported,jdk.scripting.nashorn \
--output /opt/songkong/jre

RUN rm -fr /opt/java

EXPOSE 4567

ENTRYPOINT ["/sbin/tini"]

# Config, License, Logs, Reports and Internal Database
VOLUME /songkong

# Music folder should be mounted here
VOLUME /music

WORKDIR /opt/songkong

CMD /opt/songkong/songkongremote.sh
docker java-11 jlink
1个回答
2
投票

这是正常的docker镜像的性质,一个Docker镜像是基于多层堆叠在一起,每一层都是不可改变的(不能更新另一层的内容)。

所以,当一个文件在一个层中创建并在另一个层中删除时,该文件仍然存在,但不再可用,而且Docker文件中的大多数指令都会创建一个新的层。

在你的例子中,我们将把你的镜像减少到3层来演示。

[Layer that remove the /opt/java folder]
[Layer with the new JRE]
[Base image with the JDK]

但是,在精细的情况下,你的图像有3层,所有的数据。docker image history myimage你将有一个层的列表和它们的大小。

如果你想减小尺寸,你将需要做一个多阶段的构建。- 第一阶段创建JRE - 第二阶段导入JRE并在上面添加你的代码

每个阶段都有不同的底图,所以第二个阶段可以使用小底图。

# First stage - Create the JRE
FROM adoptopenjdk/openjdk11:alpine AS jre

RUN /opt/java/openjdk/bin/jlink --module-path=/opt/java/openjdk/jmods \
--add-modules java.desktop,java.datatransfer,java.logging,java.management,java.naming,java.net.http,java.prefs,java.scripting,java.sql,jdk.management,jdk.unsupported,jdk.scripting.nashorn \
--output /opt/songkong/jre

# Second stage
FROM alpine
RUN apk --no-cache add \
      ca-certificates \
      curl \
      fontconfig \
      msttcorefonts-installer \
      tini \
 && update-ms-fonts \
 && fc-cache -f

COPY --from=jre /opt/songkong/jre /opt/songkong/jre

RUN mkdir -p /opt \
 && curl http://www.jthink.net/songkong/downloads/build1114/songkong-linux-docker.tgz?val=130| tar -C /opt -xzf - \
&& find /opt/songkong -perm /u+x -type f -print0 | xargs -0 chmod a+x

EXPOSE 4567

ENTRYPOINT ["/sbin/tini"]

# Config, License, Logs, Reports and Internal Database
VOLUME /songkong

# Music folder should be mounted here
VOLUME /music

WORKDIR /opt/songkong

CMD /opt/songkong/songkongremote.sh

有关多阶段构建的更多信息: https:/docs.docker.comdevelopdevelop-imagesmultistage-build。

有关图像和图层的更多信息。https:/docs.docker.comstoragestoragedriver#images-and-layers。


0
投票

我读了一些书,现在明白了每个层都是建立在其他层之上的。由于 optjava 是作为基础层的一部分创建的,所以它将一直存在于图像中,即使我在以后的层中删除它。

我需要做的是多阶段构建,即我在一个阶段构建我的jre,然后在第二个阶段基于基础图像,不使用jdk,我可以只复制我在第一阶段创建的jre到第二个阶段。

我发现文章解释得很好。

https:/medium.com@greutjava11-jlink-and-docker-2fec885fb2d。

但我有一个问题,base alpine:3.11镜像无法运行Java,我从一个doptopenjdk/openjdk11:alpine-jre 安装各种额外的包,但我不知道哪些包是需要用提供的jre来运行java的,所以我可能安装了太多。

FROM adoptopenjdk/openjdk11:alpine AS build

RUN /opt/java/openjdk/bin/jlink --module-path=/opt/java/openjdk/jmods \
--add-modules java.desktop,java.datatransfer,java.logging,java.management,java.naming,java.net.http,java.prefs,java.scripting,java.sql,jdk.management,jdk.unsupported,jdk.scripting.nashorn \
--output /opt/songkong/jre

RUN apk --no-cache add \
      curl \
      tini

RUN mkdir -p /opt \
 && curl http://www.jthink.net/songkong/downloads/build1114/songkong-linux-docker.tgz?val=131| tar -C /opt -xzf - \
&& find /opt/songkong -perm /u+x -type f -print0 | xargs -0 chmod a+x

RUN rm -fr /opt/java

FROM alpine:3.11

ENV LANG='en_US.UTF-8' LANGUAGE='en_US:en' LC_ALL='en_US.UTF-8'

RUN apk add --no-cache --virtual .build-deps curl binutils \
    && GLIBC_VER="2.31-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 --no-cache /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 --no-cache /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 --no-cache /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/*

RUN mkdir -p /opt

COPY --from=build /opt/songkong /opt/songkong

RUN apk --no-cache add \
      ca-certificates \
      curl \
      fontconfig \
      msttcorefonts-installer \
      tini \
 && update-ms-fonts \
 && fc-cache -f

EXPOSE 4567

ENTRYPOINT ["/sbin/tini"]

# Config, License, Logs, Reports and Internal Database
VOLUME /songkong

# Music folder should be mounted here
VOLUME /music

WORKDIR /opt/songkong

CMD /opt/songkong/songkongremote.sh
© www.soinside.com 2019 - 2024. All rights reserved.