Ich habe über Dockerfile von Fedora ein einfaches Bild erstellt (anfangs 320 MB).
Nano (dieser winzige Editor mit einer Größe von 1 MB) wurde hinzugefügt, und die Größe des Bildes ist auf 530 MB gestiegen. Ich habe darüber Git hinzugefügt (30 MB) und dann meine Bildgröße Sky-Rockets auf 830 MB.
Ist das nicht verrückt?
Ich habe versucht, Container zu exportieren und zu importieren, um Verlaufs- / Zwischenbilder zu entfernen. Dieser Aufwand sparte bis zu 25 MB, jetzt beträgt meine Bildgröße 804 MB. Ich habe auch versucht, viele Befehle auf einem auszuführen RUN
, aber ich erhalte immer noch die gleichen anfänglichen 830 MB.
Ich habe meine Zweifel, ob es sich lohnt, Docker überhaupt zu verwenden. Ich meine, ich habe kaum etwas installiert und ich habe 1 GB überschritten. Wenn ich ernsthafte Dinge wie eine Datenbank usw. hinzufügen muss, geht mir möglicherweise der Speicherplatz aus.
Wer leidet unter lächerlicher Größe von Bildern? Wie gehst du damit um?
Es sei denn, meine Docker-Datei ist schrecklich falsch?
FROM fedora:latest
MAINTAINER Me NotYou <[email protected]>
RUN yum -y install nano
RUN yum -y install git
aber es ist schwer vorstellbar, was hier schief gehen könnte.
yum clean all
das einen Einfluss auf die Größe?docker images
der in der letzten Spalte satte 830 MB angegeben sind. Ich weiß möglicherweise nicht, wie groß mein Bild tatsächlich ist, da der Befehl docker images angibt, dass diese 830 MB eine virtuelle Größe haben. Aber wie groß ist das Bild tatsächlich?Antworten:
Wie @rexposadas sagte, enthalten Bilder alle Ebenen und jede Ebene enthält alle Abhängigkeiten für das, was Sie installiert haben. Es ist auch wichtig zu beachten, dass die Basis-Images (wie sie
fedora:latest
in der Regel sehr einfach sind). Sie werden möglicherweise von der Anzahl der Abhängigkeiten überrascht sein, die Ihre installierte Software aufweist.Ich konnte Ihre Installation erheblich verkleinern, indem ich
yum -y clean all
zu jeder Zeile Folgendes hinzufügte :Es ist wichtig, dass Sie dies für jeden RUN tun, bevor die Ebene festgeschrieben wird. Andernfalls werden beim Löschen keine Daten entfernt. Das heißt, in einem Union / Copy-on-Write-Dateisystem reduziert die Bereinigung am Ende die Dateisystemnutzung nicht wirklich, da die realen Daten bereits auf niedrigeren Ebenen festgeschrieben sind. Um dies zu umgehen, müssen Sie jede Schicht reinigen.
quelle
docker images
). Ist es möglich, diese alten Ebenen zu entfernen / löschen / zerstören? Genauer gesagt: Ich möchte (basierend auf Ihrem Beispiel) Bilder vollständig entfernen: 172743bd5d60, 3f2fed40e4b0, fd241224e9cf, 511136ea3c5a aus dem Verlauf, sodass meine virtuelle Bildgröße mehr als der endgültigen Bildgröße entspricht, hier ~ 260 MB .docker export
und danndocker import
wieder. Das würde die Schichten abflachen. Ich denke nicht, dass es die Größe reduzieren würde, aber ich könnte mich irren.docker ps -s
die tatsächliche Größe der Festplatte angezeigt wird, die in meinem Fall der Fall war-1B
. Das klingt vernünftig, minus 1 Byte . Ich habe etwas Platz auf der Festplatte gewonnen ... scheint echt zu sein.Docker-Bilder sind nicht groß, Sie erstellen nur große Bilder.
Das
scratch
Bild ist 0B und Sie können es verwenden, um Ihren Code zu verpacken, wenn Sie Ihren Code in eine statische Binärdatei kompilieren können. Sie können beispielsweise Ihr Go-Programm kompilieren und darauf verpackenscratch
, um ein vollständig verwendbares Image mit weniger als 5 MB zu erstellen.Der Schlüssel ist, die offiziellen Docker-Bilder nicht zu verwenden, sie sind zu groß. Scratch ist auch nicht so praktisch, daher würde ich empfehlen, Alpine Linux als Basis-Image zu verwenden. Es ist ~ 5 MB groß, dann fügen Sie nur das hinzu, was für Ihre App erforderlich ist. Dieser Beitrag über Mikrocontainer zeigt Ihnen, wie Sie sehr kleine Bilder basierend auf Alpine erstellen.
UPDATE: Die offiziellen Docker-Bilder basieren jetzt auf Alpine und können jetzt gut verwendet werden.
quelle
Hier sind einige weitere Dinge, die Sie tun können :
RUN
Befehle, wo Sie können. Fügen Sie so viel wie möglich in einenRUN
Befehl ein (mit&&
)Mit diesen beiden UND den Empfehlungen von @Andy und @michau konnte ich die Größe meines NodeJS-Images von 1,062 GB auf 542 MB ändern.
Bearbeiten: Eine weitere wichtige Sache: "Es hat eine Weile gedauert, bis ich wirklich verstanden habe, dass jeder Dockerfile-Befehl einen neuen Container mit den Deltas erstellt. [...] Es spielt keine Rolle, ob Sie die Dateien in einem späteren Befehl rm -rf; Sie existieren weiterhin in einem Zwischenschichtbehälter. " So , jetzt habe ich es geschafft setzen
apt-get install
,wget
,npm install
(mit git Abhängigkeiten) undapt-get remove
in einem einzigenRUN
Befehl, so jetzt mein Bild nur 438 MB hat.Bearbeiten 29/06/17
Mit Docker v17.06 gibt es eine neue Funktion für Docker-Dateien: Sie können mehrere
FROM
Anweisungen in einer Docker-Datei haben, und nur das letzte MaterialFROM
befindet sich in Ihrem endgültigen Docker-Image. Dies ist nützlich, um die Bildgröße zu reduzieren, zum Beispiel:Dies führt dazu, dass ein Bild nur das Basisbild des Knotens plus den Inhalt von / var / my-project aus den ersten Schritten enthält - jedoch ohne Ruby, Python, Git, OpenSh und GCC!
quelle
Ja, diese Größen sind lächerlich, und ich habe wirklich keine Ahnung, warum so wenige Leute das bemerken.
Ich habe ein Ubuntu-Bild erstellt, das eigentlich minimal ist (im Gegensatz zu anderen sogenannten "minimalen" Bildern). Es heißt
textlab/ubuntu-essential
und hat 60 MB.Das obige Bild ist 82 MB nach der Installation von Nano.
Git hat viel mehr Voraussetzungen, so dass das Bild größer wird, ungefähr 192 MB. Das ist immer noch weniger als die ursprüngliche Größe der meisten Bilder.
Sie können sich auch das Skript ansehen, das ich geschrieben habe, um das minimale Ubuntu-Image für Docker zu erstellen . Sie können es vielleicht an Fedora anpassen, aber ich bin mir nicht sicher, wie viel Sie deinstallieren können.
quelle
Folgendes hat mir sehr geholfen:
Nachdem ich nicht verwendete Pakete (z. B. Redis 1200 MB befreit) in meinem Container entfernt habe, habe ich Folgendes getan:
Die Schichten werden abgeflacht. Die Größe des neuen Bildes wird kleiner, da ich Pakete wie oben angegeben aus dem Container entfernt habe.
Das hat viel Zeit gekostet, um das zu verstehen, und deshalb habe ich meinen Kommentar hinzugefügt.
quelle
docker export <CONTAINER ID> | docker import - some-image-name:latest
Für eine bewährte Methode sollten Sie einen einzelnen RUN-Befehl ausführen, da jeder RUN-Befehl in der Docker-Datei eine neue Ebene in das Image schreibt und jede Ebene zusätzlichen Speicherplatz auf der Festplatte benötigt. Um die Anzahl der Ebenen auf ein Minimum zu beschränken, sollten alle Dateimanipulationen wie Installieren, Verschieben, Extrahieren, Entfernen usw. idealerweise unter einer einzigen RUN-Anweisung durchgeführt werden
quelle
Docker Squash ist eine wirklich gute Lösung dafür. Sie können
$packagemanager clean
im letzten Schritt statt in jeder Zeile einen Docker-Squash ausführen, um alle Ebenen zu entfernen.https://github.com/jwilder/docker-squash
quelle
Ja, das Schichtsystem ist ziemlich überraschend. Wenn Sie ein Basis-Image haben und es wie folgt erhöhen:
Das Bild hat genau die gleiche Größe. Das bedeutet im Wesentlichen, dass Sie es schaffen müssen, viel Magie zum Extrahieren, Installieren und Bereinigen in Ihre RUN-Schritte zu integrieren, um die Images so klein wie die installierte Software zu machen.
Das macht das Leben viel schwieriger ...
Dem dockerBuild fehlen RUN-Schritte ohne Commit.
quelle