So reduzieren Sie die Bildgröße mithilfe des mehrstufigen Docker-Builds

So reduzieren Sie die Bildgröße mithilfe des mehrstufigen Docker-Builds

In diesem Artikel wird beschrieben, wie Sie die mehrstufige Build-Funktion von Docker verwenden, um die Bildgröße erheblich zu reduzieren. Es eignet sich für Bilder, die Programme (z. B. javac) in Dockerfile erstellen müssen und die Installation einer Kompilierungstoolkette erfordern. (wie Java)

Lassen Sie uns zuerst die Wörter lernen (in diesem Artikel wird chinesisches Vokabular verwendet. Wenn Sie fremdsprachige Dokumente abfragen müssen, können Sie diese Vokabelliste zu Rate ziehen. Theoretisch bin ich persönlich nicht damit einverstanden, Begriffe zu übersetzen):

  • mehrstufig
  • bauen
  • Bild
  • Bühne

Schauen wir uns die Auswirkungen an: ursprünglich über 110 Mio., jetzt 92 Mio.

Dockerfile vergleichen

Dockerfile vor der Optimierung:

VON openjdk:8u171-jdk-alpine3.8

HINZUFÜGEN ./app
ARBEITSVERZEICHNIS /app

RUN apk add maven \
  && mvn sauberes Paket \
  && apk von Maven \
  && mv ziel/final.jar / \
  && CD / \
  && rm -rf /app \
  && rm -rf /root/.m2

EINSTIEGSPUNKT java -jar /final.jar

Optimiertes Dockerfile:

VON openjdk:8u171-jdk-alpine3.8 als Builder

HINZUFÜGEN ./app
ARBEITSVERZEICHNIS /app

RUN apk add maven \
  && mvn sauberes Paket \
  && apk von Maven \
  && mv ziel/final.jar /

VON openjdk:8u181-jre-alpine3.8 als Umgebung
ARBEITSVERZEICHNIS /
KOPIEREN --from=builder /final.jar .
EINSTIEGSPUNKT java -jar /final.jar

Offensichtlich fügt das optimierte Dockerfile den Befehl FROM AS hinzu und es werden zwei FROMs angezeigt. Dies ist ein mehrstufiger Aufbau.

Erfahren Sie mehr über mehrstufige Builds

Mehrstufige Builds sind eine neue Funktion von Docker 17.05, die mehrere FROM-Anweisungen in einer Docker-Datei verwenden kann, um mehrere Stufen zu erstellen. Jede Phase ist unabhängig (Quellanforderung) und Dateien aus anderen Phasen können über COPY --from abgerufen werden. Lassen Sie uns eine Analogie ziehen und das endgültige Bild mit einem Gericht (gebratene grüne Paprika) vergleichen. Nach dem Anbraten der rohen grünen Paprikaschoten servieren.

# Vergleichsliste spiegeln -> ein Gericht erster Schritt -> Pfannengericht zweiter Schritt -> servieren

Das Ziel der beiden Schritte besteht darin, das endgültige Gericht (Bild) herzustellen (zu erzeugen). Was wir tun müssen, ist, das Essen zu servieren, das im ersten Schritt „frittiert“ wird. Unser Ziel ist es, Gerichte mit möglichst leichten Tellern (Servier- und Zwischenprodukten) zuzubereiten.

Der Visualisierungsprozess läuft wie folgt ab:

# Kochvorgang ... Zutaten weglassen -> [Erster Schritt – Pfannenrühren] # Zu diesem Zeitpunkt befinden sich Pfannenrührwerkzeuge, Pfannenrührergebnisse und Zwischenprodukte auf dem Teller. # Zu diesem Zeitpunkt beginnt der zweite Schritt, behält nur die Pfannenrührergebnisse bei, andere werden nicht mehr benötigt.
-> Das Ergebnis des Pfannenrührens -> [Beginnen Sie mit dem Servieren, behalten Sie nur das Ergebnis] # Nehmen Sie die gebratene grüne Paprika (KOPIE --von) und nehmen Sie die anderen nicht -> Das fertige Gericht ist ein Gericht.

Jetzt sollten Sie ein allgemeines Verständnis des mehrstufigen Build-Prozesses haben. Übergeben wir das Mikrofon an Java und sehen wir uns an, wie man mit dem Kompilierungstool in Dockerfile ein JAR erstellt. Dabei behalten wir nur das erstellte JAR und die Laufzeit, geben es an Image weiter und werfen den Rest weg:

# Phase 1 - Kompilieren (Braten)
FROM openjdk:8u171-jdk-alpine3.8 as builder # Integriertes Kompilierungstool ADD ./app
ARBEITSVERZEICHNIS /app

AUSFÜHREN ... Kompilierung und Bereinigung überspringen ...

# Jetzt ist das JAR draußen. JDK wird nicht mehr benötigt und kann daher nicht im Image belassen werden.
# Also starten wir die zweite Phase - laufend (auf dem Desktop) und verwerfen alle Dateien der ersten Phase (einschließlich der Kompilierungstools).
VON openjdk:8u181-jre-alpine3.8 als Umgebung # Nur Laufzeit# Derzeit haben wir die Kompilierungstools und andere Dinge aus der vorherigen Phase aufgegeben. Im aktuellen Image müssen wir nur beim Ausführen das Ergebnis der vorherigen Phase (Braten) übernehmen, die anderen brauchen wir nicht.
KOPIEREN --from=0 /final.jar .

# Ok, jetzt hat das Image nur die erforderliche Laufzeit und die JARs.
EINSTIEGSPUNKT java -jar /final.jar

Das Obige ist eine Einführung in die mehrstufige Konstruktion.

Verwenden mehrstufiger Builds

Der Kernbefehl des mehrstufigen Builds ist FROM. Für Sie, die Sie schon viele Kämpfe durchgemacht haben, bedarf FORM keiner großen Erklärung. Bei einem mehrstufigen Build startet jedes FROM eine neue Stufe, die als neues Image (nicht genau genug, Quellanforderung) angesehen werden kann, isoliert von anderen Stufen (sogar einschließlich Umgebungsvariablen). Nur das endgültige „VON“ wird in das Bild aufgenommen.

Lassen Sie uns ein einfaches Beispiel für einen mehrstufigen Build erstellen:

# Stufe 1
VON alpin:3.8
ARBEITSVERZEICHNIS /demo
RUN echo "Hallo, Stufe 1" > /demo/hi-1.txt

# Stufe 2
VON alpin:3.8
ARBEITSVERZEICHNIS /demo
RUN echo "Hallo, Stufe 2" > /demo/hi-2.txt

Sie können diese Docker-Datei selbst erstellen und dann „docker save <tag> > docker.tar“ ausführen, um den Inhalt anzuzeigen. Wenn nichts schief geht, sollten nur /demo/hi-2.txt und Alpine vorhanden sein.

In diesem Dockerfile haben wir zwei Phasen erstellt. Die erste Phase erstellt hi-1.txt, die zweite Phase erstellt hi-2.txt und die zweite Phase wird dem endgültigen Bild hinzugefügt, die anderen nicht.

Dateien kopieren – eine Brücke zwischen den Phasen

Wenn die Phasen vollständig voneinander isoliert sind, ist es sinnlos, mehrere Phasen durchzuführen – die Ergebnisse der vorherigen Phase werden vollständig verworfen und gehen in die nächste, völlig neue Phase über.

Wir können den Befehl COPY verwenden, um Dateien aus anderen Phasen abzurufen. Die Verwendung von COPY in mehreren Phasen ist genau dasselbe wie bei einer normalen Anwendung, fügen Sie einfach --form ` hinzu. Dann ändern wir das vorherige Beispiel so, dass das endgültige Bild die Produkte aus zwei Phasen enthält:

# Stufe 1
VON alpin:3.8
ARBEITSVERZEICHNIS /demo
RUN echo "Hallo, Stufe 1" > /demo/hi-1.txt

# Stufe 2
VON alpin:3.8
ARBEITSVERZEICHNIS /demo
KOPIEREN --from=0 /demo/hi-1.txt /demo
RUN echo "Hallo, Stufe 2" > /demo/hi-2.txt

Erstellen Sie es neu und speichern Sie (Speichern). Sie finden eine zusätzliche Ebene, die hi-1.txt enthält.

Etappenbenennung - schnelle Identifizierung

Für diejenigen unter uns, die nur ein Gedächtnis von sieben Sekunden haben, ist es keine gute Idee, jedes Mal den Etappenindex zu verwenden. Zu diesem Zeitpunkt können Sie ihnen Namen geben, indem Sie die Phasen zur einfacheren Identifizierung benennen.

Das Hinzufügen eines Namens zu einer Phase ist ganz einfach: Fügen Sie nach „FROM“ einfach <Name> hinzu.

Jetzt aktualisieren wir die Docker-Datei, um der Phase einen Namen zu geben, und verwenden den Namen zum KOPIEREN.

# Stufe 1, der Name ist „build1“
VON alpin:3.8 als Build1
ARBEITSVERZEICHNIS /demo
RUN echo "Hallo, Stufe 1" > /demo/hi-1.txt

# Stufe 2, der Name ist „build2“
VON alpin:3.8 als build2
ARBEITSVERZEICHNIS /demo
# Keine Indizes mehr verwenden
KOPIEREN --from=build1 /demo/hi-1.txt /demo
RUN echo "Hallo, Stufe 2" > /demo/hi-2.txt

Neu erstellen und speichern, das Ergebnis sollte das gleiche wie beim letzten Mal sein.

Erstellen Sie nur einige Stufen – einfaches Debuggen

Docker bietet uns auch eine sehr praktische Möglichkeit zum Debuggen – es wird nur ein Teil der Phase erstellt. Es kann sein, dass der Build in einer bestimmten Phase gestoppt wird und die nachfolgenden Phasen nicht erstellt werden. Dies erleichtert das Debuggen und die Unterscheidung zwischen Produktion, Entwicklung und Test.

Verwenden Sie weiterhin das letzte Dockerfile, aber verwenden Sie zum Erstellen den Parameter --target <stage>:

$ docker build --target build1 .

Speichern Sie erneut, und Sie finden nur den Inhalt von Build1.

Zusammenfassen

Das ist alles, was es zu mehrstufigen Builds zu sagen gibt. Kehren wir zu den beiden Dockerfiles am Anfang zurück und vergleichen sie. Können Sie feststellen, wo das Image vor der Optimierung dick ist?

Offensichtlich enthält es das nutzlose JDK, das nur zur Kompilierungszeit funktioniert und nach der Kompilierung nutzlos ist. Es wird nur JRE benötigt. Daher können durch die Verwendung mehrstufiger Builds die Kompilierungsphase und die Ausführungsphase isoliert werden, um eine Bildoptimierung zu erreichen.

Verweise

https://docs.docker.com/develop/develop-images/multistage-build/#name-your-build-stages

https://yeasy.gitbooks.io/docker_practice/image/multistage-builds.html

Das Obige ist der vollständige Inhalt dieses Artikels. Ich hoffe, er wird für jedermanns Studium hilfreich sein. Ich hoffe auch, dass jeder 123WORDPRESS.COM unterstützen wird.

Das könnte Sie auch interessieren:
  • Gängige Methoden zur Optimierung der Docker-Imagegröße
  • Sechs Möglichkeiten, die Größe von Docker-Images zu reduzieren

<<:  js implementiert eine einfache Methode zur Kapselung von jQuery und eine detaillierte Erklärung der Kettenoperationen

>>:  Detailliertes Beispiel für die Verwendung von MySQL-Triggern

Artikel empfehlen

Detaillierte Schritte zum Konfigurieren des Tomcat-Servers in IDEA 2020

Die Schritte zum Konfigurieren von Tomcat in IDEA...

Einige Probleme, die bei der Installation von MySQL auftreten können

Frage 1: Wenn Sie während der Installation „net s...

Vue elementUI implementiert Baumstrukturtabelle und Lazy Loading

Inhaltsverzeichnis 1. Ergebnisse erzielen 2. Back...

Verwendung des Linux-Befehls ifconfig

1. Befehlseinführung Der Befehl ifconfig (Netzwer...

Detaillierte Erklärung und Zusammenfassung der URL zur Datenbankverbindung

Detaillierte Erklärung und Zusammenfassung der UR...

Beispiel für Javascript-Bubblesort

Inhaltsverzeichnis 1. Was ist Bubble Sort 2. Gebe...

Detaillierte Erklärung der grundlegenden Interaktion von Javascript

Inhaltsverzeichnis 1. So erhalten Sie Elemente Ho...

Vue Learning - Grundlagen des VueRouter-Routings

Inhaltsverzeichnis 1. VueRouter 1. Beschreibung 2...

Wie füge ich ein Website-Symbol hinzu?

Der erste Schritt besteht darin, eine Software zur...

JS praktisches objektorientiertes Schlangenspielbeispiel

Inhaltsverzeichnis denken 1. Bild mit dem gierige...