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
:
Jaka jest różnica między tymi dwoma poleceniami?ENTRYPOINT pomaga skonfigurować kontener, który można uruchomić jako plik wykonywalny.
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
.
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/
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
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.
- Dockerfile powinien określać co najmniej jedno z poleceń
CMD
lubENTRYPOINT
.ENTRYPOINT
powinny być zdefiniowane podczas używania kontenera jako pliku wykonywalnego.CMD
powinny być używane jako sposób definiowania domyślnych argumentów dla poleceniaENTRYPOINT
lub dla wykonywanie polecenia ad-hoc w Pojemnik.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 ║
╚════════════════════════════╩═════════════════════════════════════════════════╝
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/
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.
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
.
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ą" :
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.
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 dlaENTRYPOINT
.
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.
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