Auf einen Blick: Dockers CMD und ENTRYPOINT sind wesentliche Anweisungen in Dockerfiles, die bestimmen, wie Container Befehle beim Start ausführen. CMD legt Standardbefehle fest, die überschrieben werden können, während ENTRYPOINT-Befehle bedingungslos ausgeführt werden.
- CMD kann über Kommandozeilen-Argumente überschrieben werden; ENTRYPOINT nicht.
- Nutze CMD für Standardeinstellungen und ENTRYPOINT für kritische Befehle, die immer ausgeführt werden müssen.
CMD und ENTRYPOINT sind zwei Dockerfile-Befehle, die zusammen den Befehl definieren, der ausgeführt wird, wenn Ihr Container startet. Sie müssen diese Anweisungen in Ihren Dockerfiles verwenden, damit Benutzer leicht mit Ihren Bildern interagieren können. Da CMD und ENTRYPOINT zusammenarbeiten, können sie oft verwirrend zu verstehen sein. Dieser Artikel hilft, mögliche Unterschiede in diesem Bereich auszuschließen.
In einem cloudnativen Setup sind Docker-Container wesentliche Elemente, die sicherstellen, dass eine Anwendung effektiv in verschiedenen Computerumgebungen läuft. Diese Container sind dafür gedacht, spezifische Aufgaben und Prozesse eines Anwendungsworkflows zu übernehmen und werden von Docker-Images unterstützt.
Die Images hingegen werden ausgeführt, indem Docker-Anweisungen über eine Dockerfile ausgeführt werden. Es gibt drei Arten von Anweisungen (Befehlen), die Sie verwenden, um Dockerfiles zu erstellen und auszuführen:
- RUN. RUN wird hauptsächlich zum Erstellen von Images und zur Installation von Anwendungen und Paketen verwendet und baut eine neue Ebene über einem bestehenden Image, indem es die Ergebnisse commitet.
- CMD. Legt Standardparameter fest, die aus der Docker-Kommandozeilenschnittstelle (CLI) überschrieben werden können, wenn ein Container ausgeführt wird.
- ENTRYPOINT. Standardparameter , die nicht überschrieben werden können, wenn Docker-Container mit CLI-Parametern ausgeführt werden.
Jedes Docker-Image muss eine ENTRYPOINT- oder CMD-Deklaration haben, damit ein Container starten kann. Obwohl die ENTRYPOINT- und CMD-Anweisungen auf den ersten Blick ähnlich erscheinen mögen, gibt es grundlegende Unterschiede darin, wie sie Container-Images erstellen.
(
Shell-Form vs. ausführbare Form
Zuerst müssen wir verstehen, wie ein Docker-Daemon Anweisungen verarbeitet, sobald sie weitergegeben wurden.
Alle Docker-Befehlstypen (Befehle) können entweder in Shell- oder Exec-Form angegeben werden. Lassen Sie uns eine Beispiel-Dockerfile erstellen, um diese beiden Befehle zu verstehen.
(Entdecken Sie weitere Docker-Befehle.)
Shell-Befehlsform
Wie der Name schon sagt, initiiert eine Shell-Form von Anweisungen Prozesse, die innerhalb der Shell ausgeführt werden. Um dies auszuführen, ruft /bin/sh -c <Befehl> auf.
Typischerweise erfordert jede Ausführung durch einen Shell-Befehl, dass die Umgebungsvariablen validiert werden, bevor die Ergebnisse zurückgegeben werden.
Die Syntaxen von Shell-Befehlen sind in folgender Form angegeben:
<Anweisung> <Befehl>
Beispiele für Shell-Form-Befehle sind:
RUN yum -y update
RUN yum -y install httpd
COPY ./index.html/var/www/index.html
CMD echo “Hello World”
Eine Dockerfile namens Darwin, die den Shell-Befehl verwendet, hat folgende Spezifikationen:
ENV name Darwin
ENTRYPOINT /bin/echo "Welcome, $name"
(Die oben verwendeten Befehlsspezifikationen dienen als Referenz. Du kannst jeden anderen Shell-Befehl je nach eigenen Anforderungen einfügen.)
Basierend auf der obigen Spezifikation wird die Ausgabe des docker-run-it-Darwin-Befehls sein:
Willkommen, Darwin
Dieses Befehlsformular weist die Shell an, die Validierung durchzuführen, bevor Ergebnisse zurückgegeben werden, was häufig zu Leistungsengpässen führt. Daher sind Shell-Formulare in der Regel keine bevorzugte Methode, es sei denn, es gibt spezifische Anforderungen an die Befehls- oder Umgebungsvalidierung.
Ausführbares Befehlsformular
Im Gegensatz zum Shell-Befehlstyp führt eine in ausführbarer Form geschriebene Anweisung die ausführbaren Binärdateien direkt aus, ohne eine Shell-Validierung und -verarbeitung durchlaufen zu müssen.
Ausführbare Befehlssyntaxen werden in der Form angegeben:
<Anweisung> ["ausführbare Datei", "Parameter 1", "Parameter 2", ...]
Beispiele für ausführbare Befehle sind:
RUN ["yum", "-y", "update"]
CMD ["yum", "-y" "install" "httpd"]
COPY ["./index.html/var/www/index.html"]
Um eine Dockerfile namens Darwin in Exec-Form zu erstellen:
ENV name Darwin
ENTRYPOINT ["/bin/echo", "Welcome, $name"]
Da dies eine Shell-Verarbeitung vermeidet, wird die Ausgabe des docker run -it Darwin-Befehls zurückgegeben als: Welcome, $name.
Dies liegt daran, dass die Umgebungsvariable im Dockerfile nicht eingefügt wird. Um Bash in Exec-Form auszuführen, gib /bin/bash als ausführbare Datei an, d.h.:
ENV name Darwin
ENTRYPOINT ["/bin/bash", “-c” "echo Welcome, $name"]
Dies fordert die Shell-Verarbeitung auf, sodass die Ausgabe der Dockerfile folgt: Willkommen, Darwin.
Befehle in einem containerisierten Setup sind essentielle Befehle, die an die Betriebsumgebung für ein gewünschtes Ergebnis übermittelt werden. Es ist von größter Bedeutung, das richtige Befehlsformular zum Weitergeben von Anweisungen zu verwenden, um:
- Geben Sie das gewünschte Ergebnis zurück
- Stellen Sie sicher, dass Sie die Umgebung nicht in unnötige Verarbeitung treiben, was die operative Effizienz beeinträchtigt
Interessiert an Enterprise DevOps? Erfahren Sie mehr über DevOps-Lösungen und -Tools mit BMC. ›
CMD vs. ENTRYPOINT: Grundlegende Unterschiede
CMD- und ENTRYPOINT-Anweisungen unterscheiden sich grundlegend in ihrer Funktionsweise, was jede für unterschiedliche Anwendungen, Umgebungen und Szenarien geeignet macht.
Beide spezifizieren Programme, die ausgeführt werden, wenn der Container zu laufen beginnt, aber:
- CMD-Befehle werden von Daemon ignoriert, wenn im Docker-Run-Befehl Parameter angegeben sind.
- ENTRYPOINT-Anweisungen werden nicht ignoriert, sondern als Kommandozeilenparameter angehängt, indem diese als Argumente des Befehls behandelt werden.
Als Nächstes werfen wir einen genaueren Blick darauf. Wir verwenden beide Befehlsformulare, um die verschiedenen Phasen des Ausführens eines Docker-Containers durchzugehen.
Docker CMD
Docker-CMD-Befehle werden durch eine Dockerfile gesendet, die aus folgenden Teilen besteht:
- Anleitungen zum Erstellen eines Docker-Images
- Standard-Binärdateien zum Ausführen eines Containers über dem Image
Bei einem CMD-Befehlstyp wird ein Standardbefehl/-programm ausgeführt, selbst wenn kein Befehl in der CLI angegeben ist.
Idealerweise sollte es einen einzigen CMD-Befehl in einer Dockerfile geben. Zum Beispiel werden bei mehreren CMD-Befehlen in einer Dockerfile alle außer dem letzten für die Ausführung ignoriert.
Ein wesentliches Merkmal eines CMD-Befehls ist seine Möglichkeit, überschrieben zu werden. Dies ermöglicht es Benutzern, Befehle über die CLI auszuführen, um CMD-Anweisungen innerhalb einer Dockerfile zu überschreiben.
Eine Docker-CMD-Anweisung kann sowohl in Shell- als auch in Exec-Form geschrieben werden als:
- Exec-Form: CMD ["executable", "parameter1", "parameter2"]
- Schalenform: CMD-Befehlsparameter1 Parameter2
Stufe 1. Erstellung einer Dockerfile
Beim Erstellen einer Dockerfile gibt die CMD-Instruktion das Standardprogramm an, das ausgeführt wird, sobald der Container ausgeführt wird. Ein kurzer Hinweis: CMD-Befehle werden nur verwendet, wenn Kommandozeilenargumente fehlen.
Wir schauen uns eine Dockerfile namens Darwin mit CMD-Anweisungen an und analysieren ihr Verhalten.
Die Dockerfile-Spezifikationen für Darwin sind:
Stufe 1. Erstellung einer Dockerfile
FROM centos:7
RUN apt-get update
RUN apt-get -y install python
COPY ./opt/source code
CMD ["echo", "Hello, Darwin"]
Die CMD-Instruktion in der obigen Datei spiegelt die Nachricht Hello, Darwin wider, wenn der Container ohne CLI-Argument gestartet wird.
Phase 2. Ein Bild aufbauen
Docker-Images werden aus Dockerfiles mit dem Befehl erstellt:
Phase 2. Ein Bild aufbauen
$ docker build -t Darwin .
Der obige Befehl bewirkt zwei Dinge:
- Befiehlt dem Docker-Daemon, ein Bild zu bauen
- Setzt den Tag-Namen auf Darwin, der sich im aktuellen Verzeichnis befindet
Phase 3. Betrieb eines Docker-Containers
Um einen Docker-Container auszuführen, verwenden Sie den Befehl docker run:
Phase 3. Betrieb eines Docker-Containers
$ docker run Darwin
Da dies ein Kommandozeilenargument ausschließt, führt der Container die Standard-CMD-Instruktion aus und zeigt Hello, Darwin als Ausgabe an.
Wenn wir ein Argument mit dem Ausführen-Befehl hinzufügen, überschreibt es die Standardinstruktion, d.h.:
$ docker run Darwin hostname
Wenn ein CMD-Standardbefehl überschrieben wird, führt der obige Befehl den Container aus und zeigt den Hostnamen an, wodurch die Echo-Instruktion in der Dockerfile mit folgender Ausgabe ignoriert wird:
6e14beead430
was der Hostname des Darwin-Containers ist.
Wann man CMD verwenden sollte
Der beste Weg, eine CMD-Instruktion zu verwenden, besteht darin, Standardprogramme anzugeben, die ausgeführt werden sollen, wenn Benutzer keine Argumente in der Kommandozeile eingeben.
Diese Instruktion stellt sicher, dass der Container im laufenden Zustand ist, indem eine Anwendung startet, sobald das Container-Image ausgeführt ist. Dadurch lädt das CMD-Argument das Basis-Image sofort, sobald der Container gestartet ist.
Zusätzlich kann in bestimmten Anwendungsfällen ein Docker-Run-Befehl über eine CLI ausgeführt werden, um Anweisungen im Dockerfile zu überschreiben.
Docker ENTRYPOINT
In Dockerfiles wird eine ENTRYPOINT-Instruktion verwendet, um ausführbare Dateien zu setzen, die immer ausgeführt werden, wenn der Container gestartet wird.
Im Gegensatz zu CMD-Befehlen können ENTRYPOINT-Befehle nicht ignoriert oder überschrieben werden – selbst wenn der Container mit angegebenen Kommandozeilenargumenten ausgeführt wird.
Eine Docker ENTRYPOINT-Anweisung kann sowohl in Shell- als auch in Exec-Form geschrieben werden:
- Exec-Formular: ENTRYPOINT ["ausführbare Datei", "parameter1", "parameter2"]
- Schalenform: ENTRYPOINT-Befehlsparameter1 Parameter2
ENTRYPOINT-Instruktionen werden verwendet, um Dockerfiles zu erstellen, die bestimmte Befehle ausführen sollen.
Dies sind Referenz-Dockerfile-Spezifikationen mit einem Entrypoint-Befehl:
FROM centos:7
RUN apt-get update
RUN apt-get -y install python
COPY ./opt/source code
ENTRYPOINT ["echo", "Hello, Darwin"]
Die obige Dockerfile verwendet eine ENTRYPOINT-Anweisung , die Hello, Darwin widerspiegelt, wenn der Container läuft.
Der nächste Schritt ist, ein Docker-Image zu erstellen. Verwenden Sie den Befehl:
$ docker build -t Darwin .
Beim Erstellen dieses Images sucht der Daemon nach der ENTRYPOINT-Instruktion und gibt sie als Standardprogramm an, das mit oder ohne Kommandozeileneingabe ausgeführt wird.
Wenn ein Docker-Container mit dem Darwin-Image ohne Kommandozeilenargumente ausgeführt wird, werden die Standard-ENTRYPOINT-Anweisungen ausgeführt, was an Hello, Darwin erinnert.
Falls zusätzliche Kommandozeilen-Argumente über die CLI eingeführt werden, wird der ENTRYPOINT nicht ignoriert. Stattdessen werden die Kommandozeilenparameter als Argumente für den ENTRYPOINT-Befehl angehängt, d. h.:
$ docker run Darwin hostname
führt den ENTRYPOINT aus, hallt Hello, Darwin und zeigt dann den Hostnamen an, um folgende Ausgabe zurückzugeben:
Hello, Darwin 6e14beead430
Wann man ENTRYPOINT verwenden sollte
ENTRYPOINT-Befehle eignen sich sowohl für Einzweck- als auch für Multimode-Images, bei denen immer ein spezifischer Befehl ausgeführt werden muss, wenn der Container startet.
Einer der beliebten Anwendungsfälle ist der Aufbau von Wrapper-Container-Images, die ältere Programme für die Containerisierung kapseln, wobei eine ENTRYPOINT-Anweisung genutzt wird, um sicherzustellen, dass das Programm immer ausgeführt wird.
Verwendung von CMD- und ENTRYPOINT-Anweisungen zusammen
Obwohl es grundlegende Unterschiede in ihren Operationen gibt, schließen sich CMD- und ENTRYPOINT-Anweisungen nicht gegenseitig aus. Mehrere Szenarien erfordern die Verwendung ihrer kombinierten Anweisungen in einer Dockerfile.
Ein sehr beliebter Anwendungsfall für deren Mischung ist die Automatisierung von Containerstart-Aufgaben. In einem solchen Fall kann die ENTRYPOINT-Instruktion zur Definition der ausführbaren Datei verwendet werden, während CMD zur Parameterdefinition verwendet wird.
Lassen Sie uns das mit der Darwin Dockerfile durchgehen, mit ihren Spezifikationen als:
FROM centos:7
RUN apt-get update
RUN apt-get -y install python
COPY ./opt/source code
ENTRYPOINT ["echo", "Hello"]CMD [“Darwin”]
Das Bild wird dann mit dem Befehl erstellt:
$ docker build -t darwin .
Wenn wir den Container ohne CLI-Parameter ausführen, wird die Nachricht Hallo, Darwin widerhallt.
Das Anhängen des Befehls mit einem Parameter wie Benutzername überschreibt die CMD-Anweisung und führt nur die ENTRYPOINT-Anweisung mit den CLI-Parametern als Argumente aus. Zum Beispiel der Befehl:
$ docker run Darwin User_JDArwin
wird die Ausgabe zurückgeben:
Hello User_JDArwin
Dies liegt daran, dass die ENTRYPOINT-Anweisungen nicht ignoriert werden können, während bei CMD die Befehlszeilenargumente die Anweisung überschreiben.
Verwendung von ENTRYPOINT oder CMD
Sowohl ENTRYPOINT als auch CMD sind für das Erstellen und Ausführen von Dockerfiles unerlässlich – es hängt einfach von deinem Anwendungsfall ab. Als Faustregel:
- Verwenden Sie ENTRYPOINT-Anweisungen beim Erstellen eines ausführbaren Docker-Images mit Befehlen, die immer ausgeführt werden müssen.
- Verwenden Sie CMD-Befehle, wenn Sie eine zusätzliche Menge von Argumenten benötigen, die als Standardinstruktionen dienen, bis es explizite Befehlszeilennutzung gibt, wenn ein Docker-Container ausgeführt wird.
Ein Container-Image benötigt verschiedene Elemente, darunter Laufzeitbefehle, Systemwerkzeuge und Bibliotheken, um eine Anwendung auszuführen. Um das Beste aus einer Docker-Einrichtung herauszuholen, wird dringend empfohlen, dass Ihre Administratoren verschiedene Funktionen, Strukturen und Anwendungen dieser Anweisungen verstehen, da sie entscheidende Funktionen sind, die Ihnen helfen, Images zu erstellen und Container effizient auszuführen.
Verwandte Literatur
Docker-Leitfaden
Diese Beiträge sind meine eigenen und spiegeln nicht unbedingt die Position, Strategien oder Meinung von BMC wider.