In der Übersetzung des dritten Teils der Docker-Reihe werden wir uns weiterhin von Gebäck, nämlich Bagels, inspirieren lassen. Unser heutiges Hauptthema wird die Arbeit mit Dockerfiles sein. Wir werden die Anweisungen analysieren, die in diesen Dateien verwendet werden.
→
Teil 1: die Grundlagen→
Teil 2: Begriffe und Konzepte→
Teil 3: Dockerfile-Dateien→
Teil 4: Verkleinern von Bildern und Beschleunigen ihrer Montage→
Teil 5: Teams→
Teil 6: Arbeiten mit DatenBagels sind Anweisungen in einer Docker-Datei.Docker-Bilder
Denken Sie daran, dass ein Docker-Container ein Docker-Image ist, das zum Leben erweckt wird. Dies ist ein in sich geschlossenes Betriebssystem, in dem nur der am meisten erforderliche Anwendungscode vorhanden ist.
Docker-Images sind das Ergebnis des Erstellungsprozesses, und Docker-Container führen Images aus. Das Herzstück von Docker sind Dockerfiles. Dateien wie diese teilen Docker mit, wie die Bilder zusammengesetzt werden sollen, aus denen die Container erstellt werden.
Jedes Docker-Image verfügt über eine Datei namens Dockerfile. Sein Name ist so geschrieben - ohne Erweiterung. Wenn Sie den
docker build
ausführen, um ein neues Image zu erstellen, wird davon ausgegangen, dass sich die Docker-Datei im aktuellen Arbeitsverzeichnis befindet. Wenn sich diese Datei an einem anderen Ort befindet, kann ihr Speicherort mit dem Flag
-f
angegeben werden.
Behälter bestehen, wie wir im ersten Material dieser Serie herausgefunden haben, aus Schichten. Jede Ebene mit Ausnahme der letzten, die sich über allen anderen befindet, ist schreibgeschützt. Dockerfile teilt dem Docker-System mit, welche Ebenen und in welcher Reihenfolge dem Bild hinzugefügt werden sollen.
Tatsächlich ist jede Ebene nur eine Datei, die die Änderung des Bildzustands im Vergleich zu dem Zustand beschreibt, in dem sie sich nach dem Hinzufügen der vorherigen Ebene befand. Unter Unix ist übrigens fast alles eine
Datei .
Ein Basisbild ist die Quellenebene (oder die Quellenebenen) des zu erstellenden Bildes. Das Basisbild wird auch als übergeordnetes Bild bezeichnet.
Im Basis-Image beginnt das Docker-Image.Wenn ein Image von einem Remote-Repository auf einen lokalen Computer heruntergeladen wird, werden nur Ebenen heruntergeladen, die auf diesem Computer nicht verfügbar sind. Docker möchte Platz und Zeit sparen, indem vorhandene Ebenen wiederverwendet werden.
Dockerfile-Dateien
Docker-Dateien enthalten Anweisungen zum Erstellen eines Bildes. In Großbuchstaben beginnen die Zeilen dieser Datei. Den Anweisungen folgen sind ihre Argumente. Anweisungen werden beim Erstellen des Bildes von oben nach unten verarbeitet. So sieht es aus:
FROM ubuntu:18.04 COPY . /app
Ebenen im endgültigen Bild werden nur mit den Anweisungen
FROM
,
RUN
,
COPY
und
ADD
. Andere Anweisungen richten etwas ein, beschreiben Metadaten oder teilen Docker mit, dass Sie während der Ausführung des Containers etwas tun müssen, z. B. einen Port öffnen oder einen Befehl ausführen.
Hier gehen wir von der Annahme aus, dass ein Docker-Image verwendet wird, das auf einem Unix-ähnlichen Betriebssystem basiert. Natürlich können Sie hier auch ein auf Windows basierendes Bild verwenden, aber die Verwendung von Windows ist weniger üblich. Die Arbeit mit solchen Bildern ist schwieriger. Wenn Sie die Möglichkeit haben, verwenden Sie daher Unix.
Hier ist eine Liste der Dockerfile-Anweisungen mit kurzen Kommentaren.
Dutzend Dockerfile-Anweisungen
FROM
- Legt das Basisbild (übergeordnetes Bild) fest.LABEL
- beschreibt Metadaten. Zum Beispiel Informationen darüber, wer das Image erstellt und verwaltet.ENV
- Legt persistente Umgebungsvariablen fest.RUN
- führt einen Befehl aus und erstellt eine Bildebene. Wird verwendet, um Pakete in einem Container zu installieren.COPY
- kopiert Dateien und Ordner in den Container.ADD
- kopiert Dateien und Ordner in einen Container und kann lokale .tar-Dateien entpacken.CMD
- beschreibt einen Befehl mit Argumenten, der beim Starten des Containers ausgeführt werden muss. Argumente können beim Start des Containers überschrieben werden. Eine Datei kann nur eine CMD
Anweisung enthalten.WORKDIR
- WORKDIR
das Arbeitsverzeichnis für die nächste Anweisung fest.ARG
- Legt Variablen für die Übergabe von Docker während der Image-Erstellung fest.ENTRYPOINT
- Stellt einen Befehl mit Argumenten ENTRYPOINT
, die während der Containerausführung ENTRYPOINT
. Argumente werden nicht überschrieben.EXPOSE
- zeigt an, dass der Port geöffnet werden muss.VOLUME
- Erstellt einen Einhängepunkt für die Arbeit mit persistentem Speicher.
Lassen Sie uns nun über diese Anweisungen sprechen.
Anweisungen und Beispiele für ihre Verwendung
▍Einfache Docker-Datei
Dockerfile kann sehr einfach und kurz sein. Zum Beispiel - so:
FROM ubuntu:18.04
▍Aus der Anweisung
Die Docker-Datei muss mit einer
FROM
Anweisung oder mit einer
ARG
Anweisung gefolgt von einer
FROM
Anweisung beginnen.
Das Schlüsselwort
FROM weist Docker an, beim Erstellen des Bildes ein Basis-Image zu verwenden, das dem angegebenen Namen und Tag entspricht. Das Grundbild wird außerdem auch als
übergeordnetes Bild bezeichnet .
In diesem Beispiel wird das Basis-Image im
Ubuntu- Repository gespeichert. Ubuntu ist der Name des offiziellen Docker-Repositorys, das die Basisversion der beliebten Linux-Betriebssystemfamilie Ubuntu bereitstellt.
Bitte beachten Sie, dass die betreffende Docker-Datei ein
18.04
Tag enthält, das angibt, welches Basis-Image wir benötigen. Dieses Bild wird beim Erstellen unseres Bildes geladen. Wenn das Tag nicht in der Anweisung enthalten ist, geht Docker davon aus, dass das neueste Image aus dem Repository erforderlich ist. Um ihre Absichten klarer auszudrücken, wird empfohlen, dass der Dockerfile-Autor angibt, welches Bild er benötigt.
Wenn die obige Docker-Datei auf dem lokalen Computer zum ersten Mal zum Erstellen des Images verwendet wird, lädt Docker die durch das
ubuntu
Image definierten Ebenen. Man kann sich vorstellen, dass sie einander überlagert sind. Jede nächste Ebene ist eine Datei, die die Unterschiede des Bildes im Vergleich zu dem Zustand beschreibt, in dem es sich nach dem Hinzufügen der vorherigen Ebene befand.
Wenn Sie einen Container erstellen, wird zusätzlich zu allen anderen Ebenen eine Ebene hinzugefügt, in der Sie Änderungen vornehmen können. Die Daten in den verbleibenden Schichten können nur gelesen werden.
Containerstruktur (aus der Dokumentation entnommen)Docker verwendet aus Gründen der Effizienz eine Copy-on-Write-Strategie. Wenn die Ebene im Bild auf der vorherigen Ebene vorhanden ist und eine Ebene Daten daraus lesen muss, verwendet Docker die vorhandene Datei. Sie müssen nichts herunterladen.
Wenn das Bild ausgeführt wird und die Ebene mithilfe des Containers geändert werden muss, wird die entsprechende Datei in die oberste veränderbare Ebene kopiert. Weitere Informationen zur Copy-on-Write-Strategie finden Sie in der Docker-Dokumentation.
Wir setzen die Diskussion der in der Docker-Datei verwendeten Anweisungen fort und geben ein Beispiel für eine solche Datei mit einer komplexeren Struktur.
▍Mehr anspruchsvolle Docker-Datei
Obwohl sich die Docker-Datei, die wir gerade überprüft haben, als ordentlich und verständlich herausgestellt hat, ist sie zu einfach und verwendet nur eine Anweisung. Außerdem werden während der Containerausführung keine Anweisungen aufgerufen. Schauen Sie sich eine andere Datei an, die ein kleines Bild sammelt. Es verfügt über Mechanismen, die die Befehle bestimmen, die während der Ausführung des Containers aufgerufen werden.
FROM python:3.7.2-alpine3.8 LABEL maintainer="jeffmshale@gmail.com" ENV ADMIN="jeff" RUN apk update && apk upgrade && apk add bash COPY . ./app ADD https://raw.githubusercontent.com/discdiver/pachy-vid/master/sample_vids/vid1.mp4 \ /my_app_directory RUN ["mkdir", "/a_directory"] CMD ["python", "./my_script.py"]
Vielleicht erscheint diese Datei auf den ersten Blick ziemlich kompliziert. Lassen Sie uns deshalb mit ihm umgehen.
Die Basis dieses Bildes ist das offizielle Python-Bild mit dem Tag 3.7.2-alpine3.8. Nach der Analyse
dieses Codes können Sie feststellen, dass dieses Basisimage Linux, Python und im Großen und Ganzen nur seine Zusammensetzung enthält. Alpine OS-Images sind in der Docker-Welt sehr beliebt. Die Tatsache, dass sie klein, schnell und sicher sind. Alpine Bilder unterscheiden sich jedoch nicht in den für herkömmliche Betriebssysteme typischen umfassenden Funktionen. Um auf der Grundlage eines solchen Images etwas Nützliches zu sammeln, muss der Ersteller des Images die von ihm benötigten Pakete installieren.
▍Anweisungsetikett
TagsMit der
LABEL-Anweisung (Label) können Sie dem Bild Metadaten hinzufügen. Im Fall der jetzt betrachteten Datei enthält sie die Kontaktinformationen des Erstellers des Bildes. Durch das Deklarieren von Etiketten wird der Bildassemblierungsprozess nicht verlangsamt oder vergrößert. Sie enthalten nur nützliche Informationen zum Docker-Image. Es wird daher empfohlen, sie in die Datei aufzunehmen. Details zum Arbeiten mit Metadaten in der Docker-Datei finden Sie
hier .
▍Inv-Anweisung
UmgebungMit der
ENV- Anweisung können Sie konstante Umgebungsvariablen festlegen, die während der Ausführung im Container verfügbar sind. Im vorherigen Beispiel können Sie nach dem Erstellen des Containers die Variable
ADMIN
.
Der
ENV
Befehl eignet sich gut zum Einstellen von Konstanten. Wenn Sie einen bestimmten Wert in der Docker-Datei mehrmals verwenden, z. B. wenn Sie die Befehle beschreiben, die im Container ausgeführt werden, und vermuten, dass Sie ihn eines Tages in einen anderen ändern müssen, ist es sinnvoll, ihn in eine ähnliche Konstante zu schreiben.
Es ist zu beachten, dass es in Dockerfile-Dateien häufig verschiedene Möglichkeiten gibt, dieselben Probleme zu lösen. Was genau zu verwenden ist, ist eine Frage, deren Entscheidung durch den Wunsch beeinflusst wird, die in der Docker-Umgebung angewandten Arbeitsmethoden einzuhalten, um die Transparenz der Lösung und ihre hohe Leistung sicherzustellen. Beispielsweise dienen die
ENTRYPOINT
RUN
,
CMD
und
ENTRYPOINT
unterschiedlichen Zwecken, werden jedoch alle zum Ausführen von Befehlen verwendet.
▍RUN-Anweisung
RUN-AnweisungMit der
RUN- Anweisung können Sie während der Image-Erstellung eine Ebene erstellen. Nach seiner Ausführung wird dem Bild eine neue Ebene hinzugefügt, deren Status festgelegt ist. Die
RUN
Anweisung wird häufig verwendet, um zusätzliche Pakete in Images zu installieren. Im vorherigen Beispiel teilt die Anweisung
RUN apk update && apk upgrade
Docker mit, dass das System Pakete vom
RUN apk update && apk upgrade
muss. Nach diesen beiden Befehlen folgt der Befehl
&& apk add bash
, der angibt, dass bash im Image installiert werden muss.
Was in Teams wie
apk
aussieht, ist eine Abkürzung für
Alpine Linux package manager . Wenn Sie das Basis-Image eines anderen Betriebssystems der Linux-Familie verwenden, benötigen Sie beispielsweise bei Verwendung von Ubuntu möglicherweise einen Befehl des Formulars
RUN apt-get
, um Pakete zu installieren. Später werden wir über andere Möglichkeiten zur Installation von Paketen sprechen.
Die
RUN
Anweisung und ähnliche Anweisungen wie
CMD
und
ENTRYPOINT
können entweder in der Exec-Form oder in der Shell-Form verwendet werden. Das exec-Formular verwendet eine Syntax, die der Beschreibung eines JSON-Arrays ähnelt. Zum Beispiel könnte es so aussehen:
RUN ["my_executable", "my_first_param1", "my_second_param2"]
.
Im vorherigen Beispiel haben wir die Shell-Form der RUN-Anweisung wie folgt verwendet:
RUN apk update && apk upgrade && apk add bash
.
Später in unserer Docker-Datei haben wir die Exec-Form der
RUN
Anweisung in Form von
RUN ["mkdir", "/a_directory"]
, um ein Verzeichnis zu erstellen. Wenn Sie Anweisungen in diesem Formular verwenden, müssen Sie sich gleichzeitig daran erinnern, dass Zeichenfolgen mit doppelten Anführungszeichen formatiert werden müssen, wie dies im JSON-Format üblich ist.
▍Anweisung KOPIEREN
COPY-AnweisungDie
COPY- Anweisung wird in unserer Datei folgendermaßen dargestellt:
COPY . ./app
COPY . ./app
. Sie teilt Docker mit, dass sie Dateien und Ordner aus dem lokalen Kontext der Assembly entnehmen und zum aktuellen Arbeitsverzeichnis des Images hinzufügen muss. Wenn das Zielverzeichnis nicht vorhanden ist, wird es durch diese Anweisung erstellt.
▍Anweisung HINZUFÜGEN
Mit der
ADD- Anweisung können Sie dieselben Probleme wie mit
COPY
lösen, es sind jedoch einige weitere Anwendungsfälle damit verbunden. Mit dieser Anweisung können Sie also Dateien hinzufügen, die von Remote-Quellen heruntergeladen wurden, sowie lokale .tar-Dateien entpacken.
In diesem Beispiel wurde die Anweisung
ADD
verwendet, um eine URL-zugängliche Datei in das Containerverzeichnis
my_app_directory
zu kopieren. Es ist jedoch zu beachten, dass in der
Docker-Dokumentation die Verwendung solcher per URL erhaltenen Dateien nicht empfohlen wird, da sie nicht gelöscht werden können und das Bild vergrößert werden.
Darüber hinaus wird in der
Dokumentation nach Möglichkeit empfohlen, die
COPY
Anweisung anstelle der
ADD
Anweisung zu verwenden, um das Verständnis der Docker-Datei zu erleichtern. Ich denke, das Docker-Entwicklungsteam sollte
ADD
und
COPY
in einer Anweisung kombinieren, damit sich diejenigen, die die Bilder erstellen, nicht an zu viele Anweisungen erinnern müssen.
Beachten Sie, dass die
ADD
Anweisung das Zeilenumbruchzeichen -
\
. Solche Zeichen werden verwendet, um die Lesbarkeit langer Befehle zu verbessern, indem sie in mehrere Zeilen aufgeteilt werden.
▍ CMD-Anweisung
CMD-AnweisungDie
CMD- Anweisung stellt Docker einen Befehl zur Verfügung, der ausgeführt wird, wenn der Container gestartet wird. Die Ergebnisse dieses Befehls werden dem Image während seiner Montage nicht hinzugefügt. In unserem Beispiel startet dieser Befehl das Skript
my_script.py
zur Laufzeit.
Folgendes müssen Sie noch über die
CMD
Anweisung wissen:
- In einer Docker-Datei kann nur ein
CMD
Befehl vorhanden sein. Wenn die Datei mehrere solcher Anweisungen enthält, ignoriert das System alles außer der letzten. - Ein
CMD
Befehl kann eine Ausführungsform haben. Wenn die Anweisung keinen Verweis auf die ausführbare Datei enthält, muss die Anweisung ENTRYPOINT
in der Datei vorhanden sein. In diesem Fall müssen beide Anweisungen im JSON
. - Die an
docker run
Befehlszeilenargumente überschreiben die Argumente, die von der CMD
Anweisung in der Docker-Datei bereitgestellt werden.
▍Eine noch komplexere Docker-Datei
Stellen Sie sich eine andere Docker-Datei vor, in der einige neue Befehle verwendet werden.
FROM python:3.7.2-alpine3.8 LABEL maintainer="jeffmshale@gmail.com" # RUN apk add --update git # WORKDIR /usr/src/my_app_directory # COPY . . # ARG my_var=my_default_value # , ENTRYPOINT ["python", "./app/my_script.py", "my_var"] # EXPOSE 8000 # VOLUME /my_volume
In diesem Beispiel sehen Sie unter anderem Kommentare, die mit dem Zeichen
#
.
Eines der wichtigsten Dinge, die Dockerfile tut, ist die Installation von Paketen. Wie bereits erwähnt, gibt es verschiedene Möglichkeiten, Pakete mithilfe der
RUN
Anweisung zu installieren.
Pakete im Alpine Docker-Image können mit
apk
installiert werden. Hierzu wird, wie bereits gesagt, ein Befehl des Formulars
RUN apk update && apk upgrade && apk add bash
.
Darüber hinaus können Python-Pakete im Image mithilfe von
Pip ,
Wheel und
Conda installiert werden. Wenn es sich nicht um Python handelt, sondern um andere Programmiersprachen, können andere Paketmanager verwendet werden, um die entsprechenden Images vorzubereiten.
Gleichzeitig muss die zugrunde liegende Schicht dem Paketmanager einen geeigneten Paketmanager zur Verfügung stellen, damit eine Installation möglich ist. Wenn Sie Probleme beim Installieren von Paketen haben, stellen Sie daher sicher, dass der Paketmanager installiert ist, bevor Sie versuchen, ihn zu verwenden.
Beispielsweise können Sie die
RUN
Anweisung in einer Docker-Datei verwenden, um eine Liste von Paketen mit
pip
zu installieren. Wenn Sie dies tun, kombinieren Sie alle Befehle zu einer Anweisung und trennen Sie sie mit Zeilenumbruchzeichen unter Verwendung des Zeichens
\
. Dank dieses Ansatzes sehen die Dateien ordentlich aus und dies führt dazu, dass dem Bild weniger Ebenen hinzugefügt werden, als mit mehreren
RUN
Anweisungen hinzugefügt würden.
Darüber hinaus können Sie verschiedene Schritte ausführen, um mehrere Pakete zu installieren. Sie können sie in einer Datei auflisten und diese Datei mit
RUN
an den Paketmanager übertragen. In der Regel werden diese Dateien als
requirements.txt
.
▍ WORKDIR-Anweisung
ArbeitsverzeichnisseMit der Anweisung
WORKDIR können
Sie das Arbeitsverzeichnis des Containers ändern. Die
ENTRYPOINT
WORKDIR
COPY
,
ADD
,
RUN
,
CMD
und
WORKDIR
funktionieren mit diesem Verzeichnis. Hier sind einige Funktionen im Zusammenhang mit dieser Anleitung:
- Es ist besser, mit
WORKDIR
absolute Pfade zu Ordnern WORKDIR
als mit den cd
Befehlen in der Docker-Datei im Dateisystem zu navigieren. - Die Anweisung
WORKDIR
erstellt automatisch ein Verzeichnis, wenn es nicht vorhanden ist. - Sie können mehrere
WORKDIR
Anweisungen verwenden. Wenn für solche Anweisungen relative Anweisungen bereitgestellt werden, ändert jede von ihnen das aktuelle Arbeitsverzeichnis.
▍Guide ARG
Mit der
ARG- Anweisung können Sie eine Variable festlegen, deren Wert während der Assemblierung von der Befehlszeile an das Image übergeben werden kann. Der Wert für die Standardvariable kann in der Docker-Datei dargestellt werden. Zum Beispiel:
ARG my_var=my_default_value
.
Im Gegensatz zu
ENV
Variablen sind
ARG
Variablen zur Laufzeit nicht verfügbar.
ARG
Variablen können jedoch verwendet werden, um Standardwerte für
ENV
Variablen über die Befehlszeile während der Image-
ENV
. Und
ENV
Variablen sind bereits während der Ausführung im Container verfügbar. Details zu dieser Technik des Arbeitens mit Variablen finden Sie
hier .
▍Anweisung ENTRYPOINT
Übergangspunkt zu einem OrtMit der
ENTRYPOINT-Anweisung können
Sie einen Befehl mit Argumenten angeben, die beim
Starten des Containers ausgeführt werden sollen. Es ähnelt dem
CMD
Befehl, aber die in
ENTRYPOINT
angegebenen
ENTRYPOINT
werden nicht überschrieben, wenn der Container mit Befehlszeilenparametern gestartet wird.
Stattdessen werden die in den Konstruktionen des Formular-
docker run my_image_name
zu den in der
ENTRYPOINT
angegebenen Argumenten
ENTRYPOINT
. Nach dem Ausführen eines Befehls des Formular-
docker run my_image bash
Argument
docker run my_image bash
beispielsweise am Ende der von
ENTRYPOINT
angegebenen Liste von Argumenten
ENTRYPOINT
. Vergessen Sie bei der Vorbereitung Ihrer Docker-Datei nicht die
ENTRYPOINT
CMD
oder
ENTRYPOINT
.
In der Dokumentation zu Docker finden Sie verschiedene Empfehlungen dazu, welche Anweisung,
CMD
oder
ENTRYPOINT
, beim
ENTRYPOINT
des Containers als Werkzeug zum Ausführen von Befehlen ausgewählt werden soll:
- Wenn Sie bei jedem Start des Containers denselben Befehl
ENTRYPOINT
, verwenden Sie ENTRYPOINT
. - Wenn der Container als Anwendung verwendet wird, verwenden Sie
ENTRYPOINT
. - Wenn Sie wissen, dass Sie beim Starten des Containers Argumente übergeben müssen, die die in der Docker-Datei angegebenen Argumente überschreiben können, verwenden Sie
CMD
.
In unserem Beispiel führt die Verwendung der
ENTRYPOINT ["python", "my_script.py", "my_var"]
Anweisung
ENTRYPOINT ["python", "my_script.py", "my_var"]
dass der Container beim Start das Python-Skript
my_script.py
mit dem Argument
my_var
. Der durch
my_var
dargestellte
my_var
kann dann mit
argparse im Skript verwendet
werden . , Dockerfile
my_var
, ,
ARG
. , , .
Docker exec-
ENTRYPOINT
:
ENTRYPOINT ["executable", "param1", "param2"]
.
▍ EXPOSE
EXPOSEEXPOSE , , . . , , , , , , .
( ) ,
docker run
-p
.
-P
(
P
), ,
EXPOSE
.
▍ VOLUME
VOLUMEVOLUME , . .
Zusammenfassung
, Dockerfile. . , ,
USER
,
ONBUILD
,
STOPSIGNAL
,
SHELL
HEALTHCHECK
.
Dockerfile.
, Dockerfile — Docker, , . , .
Liebe Leser! Docker , , Docker-.
