[Definitive Edition 2018] [Java 11-Containerisierung] Nachdem Sie die Spring Boot-Anwendung bis zum Limit verkleinert haben, erstellen Sie sie mit Jib und senden Sie sie an ECR

Die Welt ist ein beispielloser Containerboom, und als ich dieses Jahr zur Konferenz ging, gab es keinen Tag, an dem ich die k8s-Geschichte nicht hörte.

Unter solchen Umständen hat Java einen großen Platzbedarf und ist nicht mit Cloud-Funktionen wie Lambda kompatibel, sodass es auf verschiedene Weise gemieden wird. Obwohl wir Java ständig verwenden, schreibt jeder Java-Material in unseren Future Advent Calendar 2018. Ich nicht. .. ..

Ich liebe Java, Python, Ruby, Go und ES6 und ich denke, ich sollte die richtige Person am richtigen Ort einsetzen, aber dieses Mal werde ich einen Artikel schreiben, der Java an Heiligabend zurückdrängt.

JDK Warring States Era-Welches JDK sollten wir verwenden?

Die Welt wurde von der Tatsache erschüttert, dass Java, das von Oracle von Sun Microsystems kostenlos verwendet wurde, im September 2018 endlich von Java 11 abgerechnet wird.

Wenn Sie die Informationen jedoch ordnungsgemäß organisieren, veröffentlichen die Community und die Anbieter zusätzlich zu dem Oracle-JDK, das Oracle gegen eine Gebühr unterstützt, LTS-Versionen des JDK, die auf dem von Oracle geführten Open JDK basieren. Dies ist also kein Problem. Ich denke.

Aber wer ist in der Unternehmenswelt verantwortlich und wird rechtzeitig repariert, wenn eine Sicherheitsanfälligkeit entdeckt wird? Der Punkt ist jedoch, dass die Sicherheit auf einer mehrschichtigen Verteidigung basiert und Schwachstellen wie Bibliotheken und Frameworks wie Struts einen größeren Einfluss haben als Java selbst. Daher ist eine rein japanische Denkweise ein normales Urteil. Ich denke, es ist hinderlich, aber ich denke, dass der bezahlte Support von Oracle auch für solche Unternehmen nützlich ist.

JDK Java8 Java11 Bezahlt / kostenlos Mit LTS Kommentar
OracleJDK Bezahlt Große Unternehmen, wenn Sie beruhigt kaufen möchten, dies
Oracle OpenJDK Kostenlos Keine LTS-Version, nicht mit Empra verwendet
Redhat OpenJDK Bezahlt * Wahl, wenn Sie Redhat verwenden
AdoptOpenJDK Kostenlos Im Moment kann es kostenlos genutzt werden und die Community ist solide, so dass es einflussreich ist
Amazon Corretto Kostenlos Es gibt einen Sinn für Favoriten, weil es von Javas Vater Gothrin auf AWS entwickelt wurde. Java 11 Release erwartet
GraalVM ✗ Kostenlos Von Oracle entwickelte Polyglot VM. Es scheint, dass es explosiv sein wird, wenn es zu einem nativen Bild gemacht wird, aber es gibt viele Einschränkungen

Darüber hinaus bietet Amazon / Azure auch OpenJDK und unterstützt LTS, genau die Ära der Warring States.

Es ist ironisch, weil dies bei anderen Sprachlaufzeiten unwahrscheinlich ist, aber Sie können sehen, wie viele Java-Systeme verwendet werden ^^;

Darüber hinaus kann die Existenz von Graal VM nicht übersehen werden. Da es verschiedene Einschränkungen gibt, z. B. dass das dynamische Laden im nativen Imaging noch nicht unterstützt werden kann, kann es nicht mit Spring Boot usw. verwendet werden, aber es scheint eine Frage der Zeit zu sein, daher muss ich mich darauf freuen.

Referenz

Vergleich von Anbietern von langfristigem kommerziellem Support (LTS) für JDK (auch zur kostenlosen Nutzung erwähnt) --Qiita https://qiita.com/u-tanick/items/bb166929a58a4c20bb88

Ich habe GraalVM-Qiita ausprobiert https://qiita.com/sonodar/items/dcfafdfba8af2db53b16

Versuchen Sie, mit Micronaut for Spring --Qiita ein natives Image der Spring Boot-Anwendung zu erstellen https://qiita.com/h-r-k-matsumoto/items/5b82177294cd71df5024

Java11 SpringBoot Containerization-Downsizing ist nicht auf den Host- beschränkt

Lassen Sie uns von hier aus überlegen, ob Sie unter Java 11 ausgeführt werden sollen, während Sie die Webanwendung von SpringBoot als Betreff verwenden.

Wenn Sie es nicht zu einem Container machen möchten, können Sie ein einzelnes Start-Jar (Fat-Jar) verwenden. Dies ist sehr einfach, da Sie es einfach in der Umgebung bereitstellen können, in der das JDK installiert ist. Ich denke, es gibt viele Fälle, in denen die Größe des Glases nur einige zehn MB beträgt.

Wenn es um die Containerisierung geht, ist es in Ordnung, das obige Glas in das Container-Image zu kopieren, das das JDK enthält, und es zu starten. Das Problem hierbei ist jedoch die Image-Größe. Der Container ist klein, aber gerecht, einschließlich PUSH / PULL für die Registrierung und den Start des Containers.

OpenJDK (offiziell)

Da das Dokcer-Image (1 GB) von OpenJDK11 groß ist, erstellen Sie ein kleines Image (85 MB) mit alpine Linux + jlink --Qiita https://qiita.com/h-r-k-matsumoto/items/294eeb838cfd062d75b6

Wie hier vorgestellt, beträgt das offizielle Image von OpenJDK 1 GB. Außerdem gibt es kein LTS ... also ist es nicht in den Optionen.  Distroless by Google

Erstellen Sie ein Laufzeit-Docker-Image mit einem verzweifelten Image-Qiita https://qiita.com/some-nyan/items/90b624b0f148231748f0)

Ich habe untersucht, dass Distoless, das von Google als Image zur Laufzeit veröffentlicht wird, gut zu sein scheint, aber im Moment unterstützt es nur Java 8 und es scheint, dass ich auf die Unterstützung von Java 11 warten muss.

AdoptOpenJDK

Wenn man sich adoptopenjdk / openjdk11: alpine ansieht, das von AdoptOpenJDK veröffentlicht wurde, sind es ungefähr 200 MB, was ziemlich schlank ist Es scheint, dass ab 2018 eine bessere Option ist.

Wenn Sie jedoch eine App darauf platzieren, wird diese schwerer. Wie im obigen Artikel beschrieben, hat Java 11 auch den Vorteil des Modulsystems. Daher erstellen wir mithilfe von jlink eine benutzerdefinierte JRE und verkleinern sie weiter.

Daher muss zunächst ein JDK erstellt werden, das auf das für den Betrieb von Spring Boot mit dem Alpine-Image von AdoptOpenJDK erforderliche Minimum reduziert und dann in das Original-Image von Alpine kopiert wird.

Hierbei ist zu beachten, dass das Kopieren einer benutzerdefinierten JRE in eine einfache Alpinregion nicht funktioniert. Fügen Sie daher glibc wie unten gezeigt hinzu.

Dockerfile


###########################################################
# spring-boot-jre-min-11
# Custom JRE from AdobtOpenJDK11 for spring-boot
# 
###########################################################
FROM adoptopenjdk/openjdk11:alpine AS builder

# create custom jre
RUN jlink \
    --module-path="${JAVA_HOME}/jmods" \
    --compress=2 \
    --add-modules=java.base,java.logging,java.xml,jdk.unsupported,java.sql,java.naming,java.desktop,java.management,java.security.jgss,java.instrument,jdk.charsets \
    --no-header-files \
    --no-man-pages \
    --verbose \
    --output=/opt/jre-min

# pull plane alpine
FROM alpine:3.8

ENV JAVA_HOME="/opt/jre-min"
ENV PATH="$PATH:/opt/jre-min/bin"
ENV JAVA_VERSION="jdk-11.0.1+13"
ENV JAVA_TOOL_OPTIONS="-XX:+UseContainerSupport"

# add glibc-compat
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=builder /opt/jre-min /opt/jre-min

Folgendes habe ich an Docker Hub gesendet.

shoutstar/spring-boot-jre-min-11 - Docker Hub https://hub.docker.com/r/shoutstar/spring-boot-jre-min-11

Ich habe es geschafft, auf 48 MB zu verkleinern: smile:

Containerisiert beim Bau ~ Kennst du Jib? ~

GoogleContainerTools/jib: Build container images for your Java applications. https://github.com/GoogleContainerTools/jib

Jib ist ein Tool, das eine von Google im Juli dieses Jahres auf OSS veröffentlichte Java-Anwendung beim Erstellen von Maven / Gradle in ein Container-Image verwandelt und sogar in der Registrierung registriert. Das Folgende ist detailliert.

"Jib", der automatisch Java-Anwendungen in Docker-Images erstellt und von Google-Publickey in Open Source veröffentlicht wird https://www.publickey1.jp/blog/18/javadockerjibgoogle.html

Jib bietet einen Mechanismus, mit dem nicht nur DockerHub, sondern auch GCP GCR und AWS ECR automatisch gepusht werden können. Es ist extrem heiß, dass es bisher automatisiert werden kann, ohne eine Docker-Datei zu schreiben und ohne einen Docker-Befehl einzugeben: fire :.

Nun, wie ich das Dockerfile früher geschrieben habe ... Eigentlich gibt es einen Grund dafür. In Jib wird das from-Image in den Einstellungen angegeben, es ist jedoch nicht möglich, dieses from-Image durch Ausführen des obigen jlink anzupassen. Wenn Sie es also mit jlink unter Verwendung einer benutzerdefinierten JRE ausführen möchten, müssen Sie im Voraus ein Basis-Image erstellen und es in der Registrierung veröffentlichen.

https://github.com/GoogleContainerTools/jib/blob/master/docs/faq.md#i-need-to-run-commands-like-apt-get

Natürlich werden die Ressourcen im Klassenpfad automatisch kopiert, aber es ist möglich, jede Datei, die sich nicht im Klassenpfad befindet, durch Festlegen zu kopieren.

https://github.com/GoogleContainerTools/jib/blob/master/docs/faq.md#i-need-to-run-commands-like-apt-get

Zusätzlich zum PUSH in der Registrierung unterstützt Jib die Registrierung beim lokalen Docker-Daemon, das Erstellen von Teeren und vieles mehr.

#DRÜCKEN Sie in die Registrierung
$ mvn compile jib:build

#Registrierung beim lokalen Docker-Daemon (Docker-Start erforderlich)
$ mvn compile jib:dockerBuild

#Teer erstellen
$ mvn compile jib:buildTar

Dann werde ich dieses Mal mit Jibs Maven-Plug-In auf ECR pushen.

pom.xml


<plugin>
    <groupId>com.google.cloud.tools</groupId>
    <artifactId>jib-maven-plugin</artifactId>
    <version>0.10.0</version>
    <configuration>
        <!--In einigen Fällen ist es zweckmäßig, es bei Verwendung eines Proxys einzugeben-->
        <allowInsecureRegistries>true</allowInsecureRegistries>
        <from>
            <!--Ziehen Sie ein leichtes Bild, das nur aus benutzerdefiniertem JRE von Docker Hub besteht-->
            <image>shoutstar/spring-boot-jre-min-11</image>
        </from>
        <to>
            <!--Zur Bauzeit-Djib.to.Durch Bild ersetzen-->
            <image>future/sprinb-boot-app</image>
            <!--Zur Bauzeit-Djib.to.Durch credHelpr ersetzen
            <credHelper>ecr-login</credHelper>
            -->
        </to>
        <container>
            <!--Ich werde hier das Profil des Frühlings übergeben-->
            <jvmFlags>
                <jvmFlag>-Dadd-opens=java.base/java.lang=ALL-UNNAMED</jvmFlag>
                <jvmFlag>-Dadd-opens=java.base/java.lang.invoke=ALL-UNNAMED</jvmFlag>
                <jvmFlag>-Dspring.profiles.active=${spring.profiles.active}</jvmFlag>
            </jvmFlags>
            <!--Legen Sie die Erstellungszeit für das Bild zur Erstellungszeit fest-->
            <useCurrentTimestamp>true</useCurrentTimestamp>
        </container>
    </configuration>
</plugin>

Ergänzung zu pom.xml

jib.from.image

Die oben erwähnte benutzerdefinierte JRE ist angegeben. Es ist "Shoutstar / Spring-Boot-Jre-Min-11" von Docker Hub.

jib.to.image, jib.to.credHelpr

Da es Fälle gibt, in denen Sie es während der Entwicklung im lokalen Docker ablegen möchten, ist es meiner Meinung nach besser, es zur Erstellungszeit durch "-Djib.to.image" und "-Djib.to.credHelper" zu ersetzen.

DRÜCKEN

Ursprünglich wird der Befehl $ (aws ecr get-login --no-include-email --region ap-northeast-1) verwendet, um den Docker-Anmeldebefehl auszugeben, um sich anzumelden und dann zu pushen. Sie können es in Zusammenarbeit mit dem Befehlszeilentool verschieben.

awslabs/amazon-ecr-credential-helper: Automatically gets credentials for Amazon ECR on docker push/docker pull https://github.com/awslabs/amazon-ecr-credential-helper

Folgen Sie der README oben, um zu installieren. Die Installation von Golang 1.6 oder höher ist erforderlich.

$ go get -u github.com/awslabs/amazon-ecr-credential-helper/ecr-login/cli/docker-credential-ecr-login

Fügen Sie einen symbolischen Link in "$ GOPATH / bin / docker-credential-ecr-login" ein und fügen Sie ihn in Ihren PFAD ein.

Erstellen Sie dann die folgende config.json, um alle ECR-Registrierungsanmeldungen in Ordnung zu bringen.

json:~/.docker/config.json


{
    "credsStore": "ecr-login"
}

Wenn die Build-Umgebung EC2 ist und Sie eine IAM-Rolle zuweisen, sind keine weiteren Einstellungen erforderlich. Wenn dies nicht möglich ist, setzen Sie das Zugriffsschlüsselgeheimnis in "~ / .aws / credentials" oder geben Sie "AWS_ACCESS_KEY_ID" bzw. "AWS_SECRET_ACCESS_KEY" in den Umgebungsvariablen an.

Wenn Sie auf ECR drücken, lautet der Befehl wie folgt.

$ mvn clean compile jib:build \
-Djib.to.image=xxxxxx.dkr.ecr.ap-northeast-1.amazonaws.com/future/spring-boot-app \
-Djib.to.credHelper=ecr-login

...Unterlassung

[INFO] --- jib-maven-plugin:0.10.0:build (default-cli) @ spring-boot-app ---
[WARNING] Setting image creation time to current time; your image may not be reproducible.
[INFO] 
[INFO] Containerizing application to xxxxxx.dkr.ecr.ap-northeast-1.amazonaws.com/future/spring-boot-app ...
[WARNING] Base image 'shoutstar/spring-boot-jre-min-11' does not use a specific image digest - build may not be reproducible
[INFO] Retrieving registry credentials for xxxxxx.dkr.ecr.ap-northeast-1.amazonaws.com...
[INFO] Getting base image shoutstar/spring-boot-jre-min-11...
[INFO] Building snapshot dependencies layer...
[INFO] Building resources layer...
[INFO] Building dependencies layer...
[INFO] Building classes layer...
[INFO] The base image requires auth. Trying again for shoutstar/spring-boot-jre-min-11...
[INFO] Retrieving registry credentials for registry.hub.docker.com...
[INFO] 
[INFO] Container entrypoint set to [java, -Dadd-opens=java.base/java.lang=ALL-UNNAMED, -Dadd-opens=java.base/java.lang.invoke=ALL-UNNAMED, -Dspring.profiles.active=container, -cp, /app/resources:/app/classes:/app/libs/*, jp.co.future.sample.SpringBootApplication]
[INFO] Finalizing...
[INFO] 
[INFO] Built and pushed image as xxxxxx.dkr.ecr.ap-northeast-1.amazonaws.com/future/spring-boot-app
[INFO] 
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------

Ich konnte sicher auf ECR drängen.

Übrigens handelt es sich um eine Anwendung wie den Spring-Petclinic-Klon, den ich erstellt habe, um die Funktionsweise des internen Frameworks zu überprüfen. Die Bildgröße beträgt ca. 95 MB. Ende 2018 frage ich mich, ob dies die Grenze ist: heat_smile:

Am Ende

Jib hat Container für Java-Ingenieure vertraut und einfach gemacht. Wenn Sie sie noch nicht berührt haben, probieren Sie es bitte aus. Immerhin habe ich den Docker-Befehl durch Ausprobieren gedrückt, sodass ich nicht glaube, dass er von Java-Benutzern verwendet werden kann, die Docker nicht kennen. .. ..

Wenn die Startgeschwindigkeit in Zukunft mit GraalVM schneller wird, kann sie anscheinend mit der Cloud-Funktion verwendet werden, und Micronaut, das von Spring Boot inspiriert ist, aber eine hohe Affinität zu GraalVM aufweist, ist ebenfalls bemerkenswert.

Vor ein paar Tagen kam Amazon EKS in die Region Tokio, daher möchte ich über die Bereitstellung des an ECR übertragenen Images für EKS schreiben.

Amazon EKS unterstützt jetzt die Region Tokio. Amazon Web Services Blog https://aws.amazon.com/jp/blogs/news/amazon-eks-tokyo-region/

Recommended Posts

[Definitive Edition 2018] [Java 11-Containerisierung] Nachdem Sie die Spring Boot-Anwendung bis zum Limit verkleinert haben, erstellen Sie sie mit Jib und senden Sie sie an ECR
[Java] Stellen Sie die Spring Boot-Anwendung für den Azure App Service bereit
Verwandeln Sie Java-Apps mit Jib ~ Build with gradle ganz einfach in Docker-Container und registrieren Sie sich im lokalen Repository
[Java] Artikel zum Hinzufügen einer Validierung mit Spring Boot 2.3.1.
Bis Sie ein Spring Boot-Projekt in Intellij erstellen und an Github senden
Versuch, SSR Vue.js mit Spring Boot und GraalJS zu verwenden
Behandeln Sie die Java 8-Datums- und Uhrzeit-API mit Thymeleaf mit Spring Boot
Implementieren Sie die REST-API mit Spring Boot und JPA (Application Layer).
Stellen Sie die von Spring Boot erstellte Anwendung für Heroku (öffentlich) bereit ②
Bis INSERT und SELECT für Postgres mit Spring Boot und Thymianblatt
Aufrufen und Verwenden der API in Java (Spring Boot)
Stellen Sie die von Spring Boot erstellte Anwendung für Heroku (öffentlich) bereit ①
Stellen Sie mit spring boot + spring jpa eine Verbindung zur Datenbank her und führen Sie die CRUD-Operation durch
Domänengesteuerte Entwicklung mit Java und Spring Boot-Layer und Modulabteilung
[Spring Boot] Ich möchte meine eigene Eigenschaftendatei hinzufügen und den Wert mit env.getProperty () abrufen.