Erstellen einer kompakten Java-Umgebung, die unter Docker ausgeführt wird

Basierend auf Java in einer Welt der Container auf Japanisch bei der Oracle Groundbreakers APAC Tour in Tokio am 13.11 Ich schreibe in.

Einführung

Die folgende Abbildung zeigt ein Moduldiagramm von Java9 oder höher. DD_IQdaVoAAc6Pu.jpg

Beim Schreiben einer Anwendung in Java wird selten alles in diesem Moduldiagramm verwendet. Zum Beispiel sind java.xml, corba, javaws oft nicht notwendig.

Wenn Sie ein Docker-Image mit Linux und JDK erstellen, ohne mit Docker darüber nachzudenken, ist es ziemlich groß. Daher wird oft behauptet, dass Container und Java nicht kompatibel sind. Große Kapazität, schwerer, langsamer Start usw. Die Funktionen von Java sind jedoch auch ideal für Container. Es gibt viele Vorteile wie Laufzeit-, Hardware- und Betriebssystemunabhängigkeit, JVM-garantierte Sicherheitskompatibilität, garantierte stabile Ausführung bei Änderungen der Umgebung, Ökosystem und die beste Auswahl an Containern. .. Ein JDK, das standardmäßig zu schwer ist, kann verbessert werden, indem das JDK selbst mit Jigsaw modularisiert und die Abhängigkeiten organisiert werden.

Dockerfile

Das Betriebssystem erstellt ein Image mit ubuntu: latest. Erstellen Sie zunächst eine Umgebung mit der Standardgröße und versuchen Sie es mit Hello World.

Dockerfile


FROM ubuntu:latest
ADD openjdk-11.0.1_linux-x64_bin.tar.gz /opt/jdk/
ADD HelloWorld.class HelloWorld.class
ENV PATH /opt/jdk/jdk-11.0.1/bin:$PATH
CMD [ "java", "-showversion", "HelloWorld" ]

Erstellen Sie das Image und führen Sie es aus.

$ docker build -t helloworld-java .
$ docker run --rm helloworld-java
openjdk version "11.0.1" 2018-10-16
OpenJDK Runtime Environment 18.9 (build 11.0.1+13)
OpenJDK 64-Bit Server VM 18.9 (build 11.0.1+13, mixed mode)
Hello World!

Schauen wir uns das erstellte Bild an.

$ docker images helloworld-java
REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
helloworld-java     latest              682ae9922b5b        2 minutes ago       396MB

Es gibt ungefähr 400 MB.

Benutzerdefinierte JRE

Erstellen Sie eine benutzerdefinierte JRE mit jdeps und jlink. Sie können die Modulabhängigkeiten mithilfe von jdeps anzeigen. Werfen wir einen Blick auf das Hello World-Modul.

$ jdeps --list-deps HelloWorld.class
   java.base

Da der Inhalt Hello World ist, gibt es nur wenige Abhängigkeiten. Auf der HelloWorld-Ebene wird anscheinend nur das Modul java.base verwendet.

Erstellen wir eine benutzerdefinierte JRE mit jlink.

 jlink --compress=2 --module-path $JAVA_HOME/jmods --add-modules java.base --output jre-min

Es wird nur java.base verwendet, daher wird nur Add-Module angegeben. Nach der Ausführung wird jre-min erstellt. In dieser Umgebung ist Hello World das Minimum, das zum Ausführen erforderlich ist. Die Kapazität betrug ebenfalls 27 MB.

python


.
├── Dockerfile
├── HelloWorld.class
├── HelloWorld.java
├── hello.jar
├── jre-min
│   ├── bin
│   │   ├── java
│   │   └── keytool
│   ├── conf
│   │   ├── net.properties
│   │   └── security
│   │       ├── java.policy
│   │       ├── java.security
│   │       └── policy
│   │           ├── README.txt
│   │           ├── limited
│   │           │   ├── default_US_export.policy
│   │           │   ├── default_local.policy
│   │           │   └── exempt_local.policy
│   │           └── unlimited
│   │               ├── default_US_export.policy
│   │               └── default_local.policy
│   ├── include
│   │   ├── classfile_constants.h
│   │   ├── darwin
│   │   │   └── jni_md.h
│   │   ├── jni.h
│   │   ├── jvmti.h
│   │   └── jvmticmlr.h
│   ├── legal
│   │   └── java.base
│   │       ├── COPYRIGHT
│   │       ├── LICENSE
│   │       ├── aes.md
│   │       ├── asm.md
│   │       ├── c-libutl.md
│   │       ├── cldr.md
│   │       ├── icu.md
│   │       ├── public_suffix.md
│   │       └── unicode.md
│   ├── lib
│   │   ├── classlist
│   │   ├── jli
│   │   │   └── libjli.dylib
│   │   ├── jrt-fs.jar
│   │   ├── jspawnhelper
│   │   ├── jvm.cfg
│   │   ├── libjava.dylib
│   │   ├── libjimage.dylib
│   │   ├── libjsig.dylib
│   │   ├── libnet.dylib
│   │   ├── libnio.dylib
│   │   ├── libosxsecurity.dylib
│   │   ├── libverify.dylib
│   │   ├── libzip.dylib
│   │   ├── modules
│   │   ├── security
│   │   │   ├── blacklisted.certs
│   │   │   ├── cacerts
│   │   │   ├── default.policy
│   │   │   └── public_suffix_list.dat
│   │   ├── server
│   │   │   ├── Xusage.txt
│   │   │   ├── libjsig.dylib
│   │   │   └── libjvm.dylib
│   │   └── tzdb.dat
│   └── release
└── openjdk-11.0.1_linux-x64_bin.tar.gz

Lassen Sie uns Hello World in dieser minimalen Umgebung ausführen.

$ jre-min/bin/java -showversion HelloWorld
java version "11.0.1" 2018-10-16 LTS
Java(TM) SE Runtime Environment 18.9 (build 11.0.1+13-LTS)
Java HotSpot(TM) 64-Bit Server VM 18.9 (build 11.0.1+13-LTS, mixed mode)
Hello World!

Docker Build mit minimalem Java

Lassen Sie uns eine benutzerdefinierte JRE mit jlink erstellen und erstellen.

Dockerfile


FROM ubuntu:latest AS build
ADD openjdk-11.0.1_linux-x64_bin.tar.gz /opt/jdk/
ENV PATH /opt/jdk/jdk-11.0.1/bin:$PATH
RUN ["jlink", "--compress=2", "--module-path", "/opt/jdk/jdk-11/jmods", "--add-modules", "java.base", "--output", "/linked"]

FROM ubuntu:latest
COPY --from=build /linked /opt/jdk/
ENV PATH=$PATH:/opt/jdk/bin
ADD HelloWorld.class /

CMD [ "java", "-showversion", "HelloWorld" ]
$ docker images
REPOSITORY        TAG        IMAGE ID            CREATED             SIZE
helloworld-java   latest     e71329542c40        2 minutes ago       123MB
$ docker run -it helloworld-java
openjdk version "11.0.1" 2018-10-16
OpenJDK Runtime Environment 18.9 (build 11.0.1+13)
OpenJDK 64-Bit Server VM 18.9 (build 11.0.1+13, mixed mode)
Hello World!

Die Größe beträgt weniger als ein Viertel der vorherigen.

Leichtere Umgebungskonstruktion Docker bauen

Wir haben das minimal erforderliche Java, aber wir haben immer noch 123 MB. Wenn nur die Methode früher verwendet wird, kann nur Java leichter gemacht werden, daher werden wir auch das Betriebssystem ändern. Wenn Sie nur ava ausführen möchten, ist Ubuntu zu luxuriös. Verwenden Sie daher alpines Linux, um die minimal erforderliche Linux-Umgebung zu erstellen. alpine ist ein leichtes Linux, das auf musl libc und BusyBox basiert (es enthält wirklich nichts ...). Die Mindestkonfiguration scheint leichter als 5 MB zu sein. Siehe von AdoptOpenJDK veröffentlichte Docker-Datei für alpine Java-Umgebungen Erstellen Sie ein Image mit der Mindestkonfiguration.

Dockerfile


FROM adoptopenjdk/openjdk11:alpine-slim AS jlink
RUN ["jlink", "--compress=2", \
     "--module-path", "/opt/java/openjdk/jmods", \
     "--add-modules", "java.base", \
     "--output", "/jlinked"]


FROM alpine

RUN apk --update add --no-cache ca-certificates curl openssl binutils xz \
    && GLIBC_VER="2.28-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-8.2.1%2B20180831-1-x86_64.pkg.tar.xz" \
    && GCC_LIBS_SHA256=e4b39fb1f5957c5aab5c2ce0c46e03d30426f3b94b9992b009d417ff2d56af4d \
    && ZLIB_URL="https://archive.archlinux.org/packages/z/zlib/zlib-1%3A1.2.9-1-x86_64.pkg.tar.xz" \
    && ZLIB_SHA256=bb0959c08c1735de27abf01440a6f8a17c5c51e61c3b4c707e988c906d3b7f67 \
    && curl -Ls https://alpine-pkgs.sgerrand.com/sgerrand.rsa.pub -o /etc/apk/keys/sgerrand.rsa.pub \
    && curl -Ls ${ALPINE_GLIBC_REPO}/${GLIBC_VER}/glibc-${GLIBC_VER}.apk > /tmp/${GLIBC_VER}.apk \
    && apk add /tmp/${GLIBC_VER}.apk \
    && curl -Ls ${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 -Ls ${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 binutils \
    && rm -rf /tmp/${GLIBC_VER}.apk /tmp/gcc /tmp/gcc-libs.tar.xz /tmp/libz /tmp/libz.tar.xz /var/cache/apk/*

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

ADD HelloWorld.class /
CMD ["/opt/jdk/bin/java", "-showversion", "HelloWorld"]
$ docker build -t helloworld-java .
$ docker images
REPOSITORY                TAG                 IMAGE ID            CREATED              SIZE
helloworld-java           latest              407614883e2b        38 seconds ago       52.1MB

Es ist weniger als die Hälfte des vorherigen. Es ist ungefähr 1/8 des ursprünglichen.

Natürlich kann es ausgeführt werden

$ docker run -it helloworld-java
openjdk version "11.0.1" 2018-10-16
OpenJDK Runtime Environment AdoptOpenJDK (build 11.0.1+13)
OpenJDK 64-Bit Server VM AdoptOpenJDK (build 11.0.1+13, mixed mode)
Hello World!

Zusammenfassung

Es scheint, dass oft gesagt wird, dass der Container und Java aufgrund ihrer großen Kapazität, ihres hohen Gewichts und ihres langsamen Starts nicht miteinander kompatibel sind. Nach JDK9 können Sie mit jdeps und jlink eine dedizierte Umgebung erstellen. Da es möglich ist, die minimal erforderliche Umgebung zu erstellen, ist es möglich, einen Lichtbehälter zu erstellen. Durch Ändern des Betriebssystems können Sie eine Umgebung erstellen, die noch leichter ist und Ihnen gefällt.

Recommended Posts

Erstellen einer kompakten Java-Umgebung, die unter Docker ausgeführt wird
Erstellen Sie ein Docker-Image, um eine einfache Java-App auszuführen
Erstellen Sie eine Java-Entwicklungsumgebung auf dem Mac
Erstellen einer Entwicklungsumgebung für Java-Webanwendungen mit Docker für Mac Teil1
Konsolidieren Sie JavaFX-Apps in JAR-Dateien, die auf Java 8/11 funktionieren
Bereiten Sie eine Scraping-Umgebung mit Docker und Java vor
Erstellen Sie eine Entwicklungsumgebung für Docker, Java und Code
Erstellen Sie eine Java-Ausführungsumgebung auf Sakura VPS
Erstellen Sie eine Java-Entwicklungsumgebung mit jenv auf Ihrem Mac
[Hinweis] Erstellen Sie mit Docker eine Java-Umgebung von Grund auf neu
Ein Befehl, der die lokale Docker-Umgebung definitiv bereinigt
Versuchen Sie, mit Docker eine Java-Entwicklungsumgebung zu erstellen
Oracle Java 8 unter Docker Ubuntu
Erstellen eines Docker-Hosts in AWS mit Docker Machine (persönliches Memorandum)
Versuchen Sie Hello World mit einfachem Java im Docker-Container
Erstellen Sie mit Docker eine Vue3-Umgebung!
Erstellen Sie mit Docker eine Node.js-Umgebung
Erstellen Sie eine XAMPP-Umgebung unter Ubuntu
Konstruktionsverfahren für Rails on Docker-Umgebungen
Führen Sie PureScript auf einem Docker-Container aus
Erstellen einer Haskell-Umgebung mit Docker + VS-Code unter Windows 10 Home
Erstellen Sie eine Unity-Entwicklungsumgebung auf Docker
Installieren Sie die Java-Entwicklungsumgebung auf dem Mac
Erstellen Sie mit Docker CE für Windows eine Webanwendungsentwicklungsumgebung, die Java, MySQL und Redis verwendet
Greifen Sie über ein lokales Java-Programm (Host-Betriebssystem) auf MySQL in einem Docker-Container zu
So erstellen Sie eine Ruby on Rails-Entwicklungsumgebung mit Docker (Rails 6.x)
So erstellen Sie eine Ruby on Rails-Entwicklungsumgebung mit Docker (Rails 5.x)
Erstellen Sie mit Docker für Mac Teil2 eine Entwicklungsumgebung für Java-Webanwendungen
Erstellen Sie mit Docker eine PureScript-Entwicklungsumgebung
Konstruktionsnotiz für die Java-Entwicklungsumgebung auf dem Mac
Verwenden Sie Docker in einer Proxy-Umgebung unter Ubuntu 20.04.1
[Erstellen] Ein Memorandum über das Codieren in Java
[Java] Einen Fehler im JDK-Compiler beheben
Erstellen Sie eine WAS-Ausführungsumgebung aus Docker
Lassen Sie uns eine Java-Entwicklungsumgebung erstellen (Aktualisierung)
[Ruby] Erstellen einer Ruby-Entwicklungsumgebung unter Ubuntu
Erstellen Sie eine Java 8-Entwicklungsumgebung mit AWS Cloud 9
Aufbau der Spring Boot + Docker Java-Entwicklungsumgebung
Stellen Sie eine Java-Web-App für Heroku bereit
Erstellen Sie eine Redmine-Code-Leseumgebung in Docker
Erstellen einer Matrixklasse in Java Teil 1
Erstellen Sie eine Umgebung mit Docker unter AWS
Erstellen Sie eine JMeter-Umgebung auf Ihrem Mac
Installieren Sie Docker und erstellen Sie eine Java-Ausführungsumgebung
Einfache Konstruktion der Docker + Django-Entwicklungsumgebung
Ein Memo, in dem Ubuntu 20.4 auf HP Z2 Mini G4 installiert und mit Python Docker eine Deep Learning-Umgebung erstellt wurde
[Erste Umgebungskonstruktion] Ich habe versucht, eine Rails6 + MySQL8.0 + Docker-Umgebung unter Windows 10 zu erstellen.
Ich habe eine Java EE-Umgebung auf AWS erstellt und versucht, eine Webanwendung auszuführen
Erstellen Sie eine Entwicklungsumgebung, um Ruby on Jets + React-Apps mit Docker zu erstellen
[Teil 1] Erstellen eines Docker-Containers, der mit Apache / Pandoc Markdown in HTML liefert
Erstellen Sie eine Entwicklungsumgebung für Docker + Rails6 + Postgresql
Versuchen Sie, eine Java 8-Umgebung unter Amazon Linux2 zu erstellen
[Memo] Erstellen Sie mit Docker ganz einfach eine CentOS 8-Umgebung