Jaka jest różnica między CMD a ENTRYPOINT w pliku Dockerfile?

W plikach Dockerfiles są dwie komendy, które wyglądają podobnie do mnie: CMD i ENTRYPOINT. Ale myślę, że jest (subtelny?) różnica między nimi-w przeciwnym razie nie miałoby sensu posiadanie dwóch komend dla tego samego.

Dokumentacja stanowi dla CMD

Głównym celem CMD jest dostarczenie domyślnych wartości dla wykonującego kontenera.

I dla ENTRYPOINT:

ENTRYPOINT pomaga skonfigurować kontener, który można uruchomić jako plik wykonywalny.

Jaka jest różnica między tymi dwoma poleceniami?
 1091
Author: Jiri, 2014-02-04

9 answers

Docker ma domyślny punkt wejścia, który jest /bin/sh -c, ale nie ma domyślnego polecenia.

Kiedy uruchamiasz Dockera w ten sposób: docker run -i -t ubuntu bash entrypoint jest domyślnym /bin/sh -c, obrazkiem jest ubuntu, a komendą jest bash.

Komenda jest uruchamiana przez punkt wejścia. np. rzeczywista rzecz, która zostaje wykonana to /bin/sh -c bash. To pozwoliło Dockerowi zaimplementować RUN szybko, opierając się na parserze powłoki.

Później ludzie prosili o możliwość dostosowania tego, więc ENTRYPOINT i --entrypoint zostały wprowadzone.

Wszystko po ubuntu w powyższym przykładzie jest komendą i jest przekazywane do punktu wejścia. Podczas korzystania z instrukcji CMD, jest dokładnie tak, jakbyś robił docker run -i -t ubuntu <cmd>. <cmd> będzie parametrem punktu wejścia.

Uzyskasz ten sam wynik, jeśli zamiast tego wpiszesz to polecenie docker run -i -t ubuntu. Nadal uruchomisz powłokę bash w kontenerze, ponieważ plik Dockerfile ubuntu określa domyślny CMD: CMD ["bash"]

Jak wszystko jest przekazane do punktu wejścia, możesz mieć bardzo ładne zachowanie ze swoich zdjęć. @ Jiri przykład jest dobry, pokazuje jak używać obrazu jako "binarnego". Kiedy używasz ["/bin/cat"] jako entrypoint, a następnie wykonujesz docker run img /etc/passwd, otrzymujesz to, /etc/passwd jest komendą i jest przekazywana do entrypoint, więc końcowym wynikiem jest po prostu /bin/cat /etc/passwd.

Innym przykładem byłoby mieć dowolny cli jako entrypoint. Na przykład, jeśli masz obraz redis, zamiast uruchomić docker run redisimg redis -H something -u toto get key, możesz po prostu mieć ENTRYPOINT ["redis", "-H", "something", "-u", "toto"], a następnie uruchomić w ten sposób dla tego samego wyniku: docker run redisimg get key.

 1157
Author: creack,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-05-09 20:46:49

ENTRYPOINT określa polecenie, które będzie zawsze wykonywane podczas uruchamiania kontenera.

CMD określa argumenty, które zostaną przekazane do ENTRYPOINT.

Jeśli chcesz zrobić obrazek dedykowany konkretnemu poleceniu, użyjesz ENTRYPOINT ["/path/dedicated_command"]

W przeciwnym razie, jeśli chcesz stworzyć obraz ogólnego przeznaczenia, możesz pozostawić ENTRYPOINT nieokreślone i użyć CMD ["/path/dedicated_command"], ponieważ będziesz mógł zastąpić to ustawienie przez podanie argumentów do docker run.

Na przykład, jeśli twój Dockerfile to:

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

Uruchomienie obrazu bez żadnego argumentu spowoduje pingowanie localhost:

$ 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

Teraz uruchomienie obrazu z argumentem spowoduje pingowanie argumentu:

$ 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

Dla porównania, jeśli Twój plik Dockerfile to:

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

Uruchomienie obrazu bez żadnego argumentu spowoduje pingowanie localhost:

$ 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

Ale uruchomienie obrazu z argumentem spowoduje uruchomienie argumentu:

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

Zobacz ten artykuł Briana Dehamera, aby dowiedzieć się więcej szczegóły: https://www.ctl.io/developers/blog/post/dockerfile-entrypoint-vs-cmd/

 298
Author: Daishi,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-12-12 22:17:34

Tak, to dobre pytanie. Nie rozumiem tego jeszcze do końca, ale:

Rozumiem, że ENTRYPOINT jest wykonywanym plikiem binarnym. Możesz przesunąć entrypoint przez --entrypoint="".

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

CMD jest domyślnym argumentem kontenera. Bez entrypoint domyślnym argumentem jest komenda, która jest wykonywana. Z entrypoint, cmd jest przekazywane do entrypoint jako argument. Możesz emulować polecenie za pomocą entrypoint.

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

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

Więc główną zaletą jest to, że z entrypoint można przejść argumenty (cmd) do kontenera. Aby to osiągnąć, musisz użyć obu:

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

I

docker build -t=cat .

Wtedy możesz użyć:

docker run cat /etc/passwd
#              ^^^^^^^^^^^
#                   CMD
#          ^^^      
#          image (tag)- using the default ENTRYPOINT
 146
Author: Jiri,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-10-30 12:40:23

Według docker docs ,

Instrukcje CMD i ENTRYPOINT definiują, jakie polecenie jest wykonywane podczas uruchamiania kontenera. Istnieje kilka zasad, które opisują ich współpraca.

  1. Dockerfile powinien określać co najmniej jedno z poleceń CMD lub ENTRYPOINT.
  2. ENTRYPOINT powinny być zdefiniowane podczas używania kontenera jako pliku wykonywalnego.
  3. CMD powinny być używane jako sposób definiowania domyślnych argumentów dla polecenia ENTRYPOINT lub dla wykonywanie polecenia ad-hoc w Pojemnik.
  4. CMD zostanie nadpisana podczas uruchamiania kontenera z alternatywnymi argumentami.

Poniższe tabele pokazują jakie polecenie jest wykonywane dla różnych ENTRYPOINT / CMD kombinacje :

-- 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  ║
╚════════════════════════════╩═════════════════════════════════════════════════╝
 118
Author: Rafaf Tahsin,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-06-07 13:41:43

W skrócie:

  • CMD ustawia domyślne polecenia i / lub parametry, które mogą być nadpisane z linii poleceń podczas uruchamiania kontenera dokera.
  • polecenie i parametry ENTRYPOINT nie zostaną nadpisane z linii poleceń. Zamiast tego, wszystkie argumenty linii poleceń zostaną dodane po parametrach ENTRYPOINT.

Jeśli potrzebujesz więcej szczegółów lub chciałbyś zobaczyć różnicę na przykładzie, istnieje wpis na blogu, który kompleksowo porównuje CMD i ENTRYPOINT z wieloma przykładami - http://goinbigdata.com/docker-run-vs-cmd-vs-entrypoint/

 29
Author: upitau,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-04-03 09:32:35

Różnica między CMD a ENTRYPOINT przez intuicję :

  • ENTRYPOINT: polecenie do uruchomienia po uruchomieniu kontenera.
  • CMD: polecenie do uruchomienia po uruchomieniu kontenera lub argumenty do ENTRYPOINT, jeśli podano.
Tak, mieszają się.

Możesz nadpisać dowolny z nich podczas uruchamiania docker run.

Różnica między CMD a ENTRYPOINT przez przykład :

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

Więcej o różnicy między CMD A ENTRYPOINT:

Argument docker run, taki jak /bin/bash nadpisuje polecenie CMD, które napisaliśmy w pliku Dockerfile.

ENTRYPOINT nie może być nadpisany podczas wykonywania zwykłymi poleceniami, takimi jak docker run [args]. args na końcu docker run [args] są podane jako argumenty do ENTRYPOINT. W ten sposób możemy utworzyć container, który jest jak normalny binarny, taki jak ls.

Więc CMD może działać jako domyślne parametry ENTRYPOINT, a następnie możemy nadpisać args CMD z [args].

ENTRYPOINT może być nadpisane przez --entrypoint.

 18
Author: Tomer Ben David,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-03-01 11:36:12

Przyjęta odpowiedź jest fantastyczna w wyjaśnianiu historii. Ta tabela wyjaśnia to bardzo dobrze z oficjalnego dokumentu na temat "jak CMD i ENTRYPOINT współdziałają" : Tutaj wpisz opis obrazka

 7
Author: Xiao Peng - ZenUML.com,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-05-31 10:39:02

Komentarze do funkcji EntryPoint w kodzie

// ENTRYPOINT / usr / sbin / nginx.

W tym celu należy ustawić na /usr/sbin/nginx (domyślnie sh-c). W tym celu prosimy o zapoznanie się z naszą polityką prywatności.

Kolejny odnośnik z dokumentów

Możesz użyć formy Exec ENTRYPOINT, aby ustawić dość stabilne domyślne polecenia i argumenty, a następnie użyć CMD, aby ustawić dodatkowe domyślne wartości, które są bardziej prawdopodobnie zostanie zmieniona.

Przykład:

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

Build : 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: W obecności EntryPoint, CMD będzie trzymać argumenty do fed do EntryPoint. W przypadku braku EntryPoint, CMD będzie komendą, która zostanie uruchomiona.

 5
Author: Tahir Rauf,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-08-29 04:37:36

CMD:

  • CMD ["executable","param1","param2"]: ["executable","param1","param2"] jest pierwszym procesem.
  • CMD command param1 param2: /bin/sh -c CMD command param1 param2 jest pierwszym procesem. CMD command param1 param2 jest rozwidlona od pierwszego procesu.
  • CMD ["param1","param2"]: ten formularz jest używany do dostarczania domyślnych argumentów dla ENTRYPOINT.

ENTRYPOINT (poniższa lista nie uwzględnia przypadku, gdy CMD i ENTRYPOINT są używane razem):

  • ENTRYPOINT ["executable", "param1", "param2"]: ["executable", "param1", "param2"] jest pierwszym procesem.
  • ENTRYPOINT command param1 param2: /bin/sh -c command param1 param2 jest pierwszym procesem. command param1 param2 jest rozwidlona od pierwszego proces.

Jak powiedział creack , CMD został opracowany jako pierwszy. Następnie ENTRYPOINT został opracowany dla większej personalizacji. Ponieważ nie są one projektowane razem, między CMD i ENTRYPOINT nakładają się pewne funkcje, które często mylą ludzi.

 1
Author: Jingguo Yao,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-05-23 12:03:09