Frage Was ist der Unterschied zwischen CMD und ENTRYPOINT in einer Dockerfile?


In Dockerfiles gibt es zwei Befehle, die mir ähnlich sehen: CMD und ENTRYPOINT. Aber ich denke, dass es einen (subtilen?) Unterschied zwischen ihnen gibt - sonst würde es keinen Sinn machen, zwei Befehle für dasselbe zu haben.

Die Dokumentation besagt für CMD

Der Hauptzweck eines CMD besteht darin, Standardwerte für einen ausgeführten Container anzugeben.

und für ENTRYPOINT:

Ein ENTRYPOINT hilft Ihnen beim Konfigurieren eines Containers, den Sie als ausführbare Datei ausführen können.

Also, was ist der Unterschied zwischen diesen beiden Befehlen?


1030
2018-02-04 13:04


Ursprung


Antworten:


Docker hat einen Standardeinstiegspunkt, nämlich: /bin/sh -c hat aber keinen Standardbefehl.

Wenn Sie docker so ausführen: docker run -i -t ubuntu bash Der Einstiegspunkt ist der Standardwert /bin/sh -cDas Bild ist ubuntu und der Befehl ist bash.

Der Befehl wird über den Einstiegspunkt ausgeführt. h. die tatsächliche Sache, die ausgeführt wird, ist /bin/sh -c bash. Dies erlaubt Docker zu implementieren RUN schnell, indem Sie sich auf den Parser der Shell verlassen.

Später haben die Leute gebeten, dies so anzupassen ENTRYPOINT und --entrypoint wurden vorgestellt.

Alles danach ubuntu Im obigen Beispiel ist der Befehl und wird an den Einstiegspunkt übergeben. Bei der Verwendung der CMD Anweisung, es ist genau so, als ob Sie tun würden docker run -i -t ubuntu <cmd>. <cmd> wird der Parameter des Einstiegspunktes sein.

Sie erhalten auch das gleiche Ergebnis, wenn Sie stattdessen diesen Befehl eingeben docker run -i -t ubuntu. Du wirst trotzdem eine Bash Shell im Container starten wegen der ubuntu Dockerfile hat eine Standard-CMD angegeben: CMD ["bash"]

Da alles an den Einstiegspunkt übergeben wird, können Sie ein sehr gutes Verhalten von Ihren Bildern haben. @Jiri Beispiel ist gut, es zeigt, wie man ein Bild als "Binär" verwendet. Beim Benutzen ["/bin/cat"] als Einstiegspunkt und dann tun docker run img /etc/passwd, du verstehst es, /etc/passwd ist der Befehl und wird an den Einstiegspunkt übergeben, so dass die Ausführung des Endergebnisses einfach ist /bin/cat /etc/passwd.

Ein anderes Beispiel wäre ein cli als Einstiegspunkt. Zum Beispiel, wenn Sie ein Redis-Image haben, anstatt zu laufen docker run redisimg redis -H something -u toto get keykannst du einfach haben ENTRYPOINT ["redis", "-H", "something", "-u", "toto"] und dann für das gleiche Ergebnis wie folgt ausführen: docker run redisimg get key.


1083
2018-02-04 22:34



Das ENTRYPOINT Gibt einen Befehl an, der beim Start des Containers immer ausgeführt wird.

Das CMD spezifiziert Argumente, die dem ENTRYPOINT.

Wenn Sie ein Bild erstellen möchten, das einem bestimmten Befehl gewidmet ist, verwenden Sie es ENTRYPOINT ["/path/dedicated_command"]

Andernfalls, wenn Sie ein Bild für allgemeine Zwecke machen möchten, können Sie gehen ENTRYPOINT nicht spezifiziert und verwenden CMD ["/path/dedicated_command"] Sie können die Einstellung überschreiben, indem Sie Argumente angeben docker run.

Zum Beispiel, wenn Ihre Dockerfile ist:

FROM debian:wheezy
ENTRYPOINT ["/bin/ping"]
CMD ["localhost"]

Wenn das Bild ohne irgendein Argument ausgeführt wird, wird ein Ping an den lokalen Host gesendet:

$ docker run -it test
PING localhost (127.0.0.1): 48 data bytes
56 bytes from 127.0.0.1: icmp_seq=0 ttl=64 time=0.096 ms
56 bytes from 127.0.0.1: icmp_seq=1 ttl=64 time=0.088 ms
56 bytes from 127.0.0.1: icmp_seq=2 ttl=64 time=0.088 ms
^C--- localhost ping statistics ---
3 packets transmitted, 3 packets received, 0% packet loss
round-trip min/avg/max/stddev = 0.088/0.091/0.096/0.000 ms

Wenn Sie jetzt das Bild mit einem Argument ausführen, wird das Argument ping:

$ docker run -it test google.com
PING google.com (173.194.45.70): 48 data bytes
56 bytes from 173.194.45.70: icmp_seq=0 ttl=55 time=32.583 ms
56 bytes from 173.194.45.70: icmp_seq=2 ttl=55 time=30.327 ms
56 bytes from 173.194.45.70: icmp_seq=4 ttl=55 time=46.379 ms
^C--- google.com ping statistics ---
5 packets transmitted, 3 packets received, 40% packet loss
round-trip min/avg/max/stddev = 30.327/36.430/46.379/7.095 ms

Zum Vergleich, wenn Ihre Dockerfile ist:

FROM debian:wheezy
CMD ["/bin/ping", "localhost"]

Wenn das Bild ohne irgendein Argument ausgeführt wird, wird ein Ping an den lokalen Host gesendet:

$ docker run -it test
PING localhost (127.0.0.1): 48 data bytes
56 bytes from 127.0.0.1: icmp_seq=0 ttl=64 time=0.076 ms
56 bytes from 127.0.0.1: icmp_seq=1 ttl=64 time=0.087 ms
56 bytes from 127.0.0.1: icmp_seq=2 ttl=64 time=0.090 ms
^C--- localhost ping statistics ---
3 packets transmitted, 3 packets received, 0% packet loss
round-trip min/avg/max/stddev = 0.076/0.084/0.090/0.000 ms

Wenn Sie das Bild mit einem Argument ausführen, wird das Argument ausgeführt:

docker run -it test bash
root@e8bb7249b843:/#

Weitere Details finden Sie in diesem Artikel von Brian DeHamer: https://www.ctl.io/developers/blog/post/dockerfile-entrypoint-vs-cmd/


264
2017-12-12 22:17



Ja, das ist eine gute Frage. Ich verstehe es noch nicht ganz, aber:

ich verstehe das ENTRYPOINT ist das Binary, das ausgeführt wird. Sie können den Einstiegspunkt mit --entrypoint = "" übersteuern.

docker run -t -i --entrypoint="/bin/bash" ubuntu

CMD ist das Standardargument für den Container. Ohne Einstiegspunkt ist das Standardargument der Befehl, der ausgeführt wird. Beim Einstiegspunkt wird cmd als Argument an den Einstiegspunkt übergeben. Sie können einen Befehl mit dem Einstiegspunkt emulieren.

# no entrypoint
docker run ubuntu /bin/cat /etc/passwd

# with entry point, emulating cat command
docker run --entrypoint="/bin/cat" ubuntu /etc/passwd

Der Hauptvorteil besteht also darin, dass Sie mit dem Argument Argumente (cmd) an Ihren Container übergeben können. Um dies zu erreichen, müssen Sie beide verwenden:

# Dockerfile
FROM ubuntu
ENTRYPOINT ["/bin/cat"]

und

docker build -t=cat .

dann kannst du verwenden:

docker run cat /etc/passwd
#              ^^^^^^^^^^^
#                   CMD
#          ^^^      
#          image (tag)- using the default ENTRYPOINT

138
2018-02-04 17:12



Gemäß Andockdokumente,

Sowohl CMD- als auch ENTRYPOINT-Befehle definieren, welcher Befehl ausgeführt wird   wenn ein Container läuft. Es gibt wenige Regeln, die ihre beschreiben   Zusammenarbeit.

  1. Dockerfile sollte mindestens eine von angeben CMD oder ENTRYPOINT Befehle.
  2. ENTRYPOINT sollte definiert werden, wenn der Container als ausführbare Datei verwendet wird.
  3. CMD sollte verwendet werden, um Standardargumente für ein zu definieren ENTRYPOINT Befehl oder zum Ausführen eines Ad-hoc-Befehls in einem   Container.
  4. CMD wird überschrieben, wenn der Container mit alternativen Argumenten ausgeführt wird.

Die folgenden Tabellen zeigen welcher Befehl wird für andere ausgeführt ENTRYPOINT / CMD Kombinationen:

- No ENTRYPOINT

╔════════════════════════════╦═════════════════════════════╗
║ No CMD                     ║ error, not allowed          ║
╟────────────────────────────╫─────────────────────────────╢
║ CMD [“exec_cmd”, “p1_cmd”] ║ exec_cmd p1_cmd             ║
╟────────────────────────────╫─────────────────────────────╢
║ CMD [“p1_cmd”, “p2_cmd”]   ║ p1_cmd p2_cmd               ║
╟────────────────────────────╫─────────────────────────────╢
║ CMD exec_cmd p1_cmd        ║ /bin/sh -c exec_cmd p1_cmd  ║
╚════════════════════════════╩═════════════════════════════╝

- ENTRYPOINT exec_entry p1_entry

╔════════════════════════════╦═══════════════════════════════════════════════════════════╗
║ No CMD                     ║ /bin/sh -c exec_entry p1_entry                            ║
╟────────────────────────────╫───────────────────────────────────────────────────────────╢
║ CMD [“exec_cmd”, “p1_cmd”] ║ /bin/sh -c exec_entry p1_entry exec_cmd p1_cmd            ║
╟────────────────────────────╫───────────────────────────────────────────────────────────╢
║ CMD [“p1_cmd”, “p2_cmd”]   ║ /bin/sh -c exec_entry p1_entry p1_cmd p2_cmd              ║
╟────────────────────────────╫───────────────────────────────────────────────────────────╢
║ CMD exec_cmd p1_cmd        ║ /bin/sh -c exec_entry p1_entry /bin/sh -c exec_cmd p1_cmd ║
╚════════════════════════════╩═══════════════════════════════════════════════════════════╝

- ENTRYPOINT [“exec_entry”, “p1_entry”]

╔════════════════════════════╦═════════════════════════════════════════════════╗
║ No CMD                     ║ exec_entry p1_entry                             ║
╟────────────────────────────╫─────────────────────────────────────────────────╢
║ CMD [“exec_cmd”, “p1_cmd”] ║ exec_entry p1_entry exec_cmd p1_cmd             ║
╟────────────────────────────╫─────────────────────────────────────────────────╢
║ CMD [“p1_cmd”, “p2_cmd”]   ║ exec_entry p1_entry p1_cmd p2_cmd               ║
╟────────────────────────────╫─────────────────────────────────────────────────╢
║ CMD exec_cmd p1_cmd        ║ exec_entry p1_entry /bin/sh -c exec_cmd p1_cmd  ║
╚════════════════════════════╩═════════════════════════════════════════════════╝

109
2017-09-09 09:52



In einer Nussschale:

  • CMD legt den Standardbefehl und / oder die Standardparameter fest, die beim Ausführen des Andockcontainers über die Befehlszeile überschrieben werden können.
  • ENTRYPOINT-Befehl und -Parameter werden nicht von der Befehlszeile überschrieben. Stattdessen werden alle Befehlszeilenargumente nach ENTRYPOINT-Parametern hinzugefügt.

Wenn Sie mehr Details benötigen oder einen Unterschied sehen möchten, gibt es einen Blogbeitrag, der CMD und ENTRYPOINT umfassend mit vielen Beispielen vergleicht - http://goinbigdata.com/docker-run-vs-cmd-vs-entrypoint/ 


27
2018-04-03 09:32



Unterschied zwischen CMD und ENTRYPOINT durch Intuition:

  • ENTRYPOINT: Befehl, der beim Start des Containers ausgeführt wird.
  • CMD: Befehl, der beim Start von Containern oder bei Angabe von ENTRYPOINT-Argumenten ausgeführt wird.

Ja, es vermischt sich.

Sie können diese beim Ausführen von docker run überschreiben.

Unterschied zwischen CMD und ENTRYPOINT zum Beispiel:

docker run -it --rm yourcontainer /bin/bash            <-- /bin/bash overrides CMD
                                                       <-- /bin/bash does not override ENTRYPOINT
docker run -it --rm --entrypoint ls yourcontainer      <-- overrides ENTRYPOINT with ls
docker run -it --rm --entrypoint ls yourcontainer  -la  <-- overrides ENTRYPOINT with ls and overrides CMD with -la

Mehr über den Unterschied zwischen CMD und ENTRYPOINT:

Argument zu docker run Wie zB / bin / bash überschreibt jeder CMD-Befehl, den wir in Dockerfile geschrieben haben.

ENTRYPOINT kann zur Laufzeit nicht mit normalen Befehlen wie z docker run [args]. Das args am Ende von docker run [args] werden als Argumente für ENTRYPOINT bereitgestellt. Auf diese Weise können wir ein container das ist wie eine normale binäre wie ls.

Daher kann CMD als Standardparameter für ENTRYPOINT fungieren und dann können wir die CMD-Argumente von [args] überschreiben.

ENTRYPOINT kann mit überschrieben werden --entrypoint.


16
2018-01-16 12:34



Die angenommene Antwort ist fabelhaft, um die Geschichte zu erklären. Ich finde diese Tabelle sehr gut von erklären offizielles Dokument über "wie CMD und ENTRYPOINT interagieren": enter image description here


7
2018-05-31 07:12



Kommentare zur EntryPoint Funktion in Code

// ENTRYPOINT / usr / sbin / nginx.

// Setze den Einstiegspunkt (der standardmäßig sh -c ist) auf / usr / sbin / nginx.

// Akzeptiert den CMD als Argumente für / usr / sbin / nginx.

Eine weitere Referenz aus Dokumenten

Sie können das exec-Formular von ENTRYPOINT verwenden, um festzulegen ziemlich stabile Standardbefehle und -argumente und verwenden Sie dann CMD, um zusätzliche Standardeinstellungen festzulegen, die mit größerer Wahrscheinlichkeit geändert werden.

Beispiel:

FROM ubuntu:14.04.3
ENTRYPOINT ["/bin/ping"]
CMD ["localhost", "-c", "2"]

Bauen: sudo docker build -t ent_cmd.

CMD arguments are easy to override.

NO argument (sudo docker -it ent_cmd)                :  ping localhost 
argument    (sudo docker run -it ent_cmd google.com) :  ping google.com

.

To override EntryPoint argument, you need to supply entrypoint
sudo docker run -it --entrypoint="/bin/bash" ent_cmdd

p.s: In Anwesenheit von EntryPoint hält CMD Argumente bereit, die an EntryPoint übergeben werden. In Abwesenheit von EntryPoint wird CMD der Befehl sein, der ausgeführt wird.


5
2018-01-16 07:32



CMD:

  • CMD ["executable","param1","param2"]: ["executable","param1","param2"] ist der erste Prozess.
  • CMD command param1 param2: /bin/sh -c CMD command param1 param2 ist der erste Prozess. CMD command param1 param2 wird vom ersten Prozess gespalten.
  • CMD ["param1","param2"]: Dieses Formular wird verwendet, um Standardargumente für bereitzustellen ENTRYPOINT.

ENTRYPOINT (Die folgende Liste berücksichtigt nicht den Fall, in dem CMD und ENTRYPOINT zusammen verwendet werden):

  • ENTRYPOINT ["executable", "param1", "param2"]: ["executable", "param1", "param2"] ist der erste Prozess.
  • ENTRYPOINT command param1 param2: /bin/sh -c command param1 param2 ist der erste Prozess. command param1 param2 wird vom ersten Prozess gespalten.

Wie Creack sagte, CMD wurde zuerst entwickelt. Dann wurde ENTRYPOINT für mehr Anpassung entwickelt. Da sie nicht zusammen entworfen werden, gibt es einige Funktionsüberschneidungen zwischen CMD und ENTRYPOINT, die oft Leute verwirren.


1
2018-01-05 06:42



Dies ist wahrscheinlich die beste Beschreibung, die ich gefunden habe: Dockerfile: ENTRYPOINT vs CMD

Ich hatte hier eine Zusammenfassung, aber die Leute gingen immer weiter, ohne einen Grund anzugeben, also habe ich es gelöscht.


-1
2018-02-04 22:34