W Dockerfiles są dwa polecenia, które wyglądają podobnie do mnie: CMD
i ENTRYPOINT
. Ale wydaje mi się, że istnieje (subtelna?) Różnica między nimi - w przeciwnym razie nie byłoby sensu mieć dwóch poleceń dla tej samej rzeczy.
Dokumentacja stwierdza dla CMD
Głównym celem CMD jest zapewnienie wartości domyślnych 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?
ADD
iCOPY
CMD
iENTRYPOINT
oba mają różne formy do napisania, exec i shell . Więc wyświadcz sobie przysługę i zrozum subtelne różnice w zachowaniu w zależności od używanej formy. Następnie przeczytaj docs.docker.com/engine/reference/builder/… .Odpowiedzi:
Docker ma domyślny punkt wejścia, który jest,
/bin/sh -c
ale nie ma domyślnego polecenia.Po uruchomieniu dokera w ten sposób:
docker run -i -t ubuntu bash
punktem wejściowym jest wartość domyślna/bin/sh -c
, obraz toubuntu
i polecenie tobash
.Polecenie jest uruchamiane przez punkt wejścia. tzn. faktyczną rzeczą, która zostanie wykonana, jest
/bin/sh -c bash
. To pozwoliło Dockerowi naRUN
szybką implementację , polegając na parserze powłoki.Później, ludzie pytali, aby móc dostosować to, więc
ENTRYPOINT
i--entrypoint
zostały wprowadzone.Wszystko
ubuntu
w powyższym przykładzie jest poleceniem i jest przekazywane do punktu wejścia. Podczas korzystania zCMD
instrukcji jest dokładnie tak, jakbyś to robiłdocker run -i -t ubuntu <cmd>
.<cmd>
będzie parametrem punktu wejścia.Ten sam wynik otrzymasz również, jeśli zamiast tego wpiszesz to polecenie
docker run -i -t ubuntu
. Nadal uruchomisz powłokę bash w kontenerze, ponieważ plik Docker w Ubuntu określił domyślną CMD:CMD ["bash"]
Ponieważ wszystko jest przekazywane do punktu wejścia, możesz mieć bardzo ładne zachowanie ze swoich zdjęć. @Jiri przykład jest dobry, pokazuje, jak używać obrazu jako „pliku binarnego”. Gdy używasz
["/bin/cat"]
jako punktu wejścia, a następnie robiszdocker run img /etc/passwd
, dostajesz go,/etc/passwd
jest to polecenie i jest przekazywane do punktu wejścia, więc wykonanie wyniku końcowego jest po prostu/bin/cat /etc/passwd
.Innym przykładem byłoby posiadanie dowolnego cli jako punktu wejścia. Na przykład, jeśli masz obraz Redis, zamiast biegać
docker run redisimg redis -H something -u toto get key
, można po prostu miećENTRYPOINT ["redis", "-H", "something", "-u", "toto"]
, a następnie uruchomić w ten sposób do tego samego rezultatu:docker run redisimg get key
.źródło
ENTRYPOINT
; to, czy używana jest powłoka, zależy od użytej formyCMD
polecenia ( docs.docker.com/engine/reference/builder/#cmd ).CMD
vsENTRYPOINT
.W
ENTRYPOINT
Określa polecenie, które zawsze będą wykonywane podczas uruchamiania pojemnika.W
CMD
Określa argumenty, które zostaną wykorzystane doENTRYPOINT
.Jeśli chcesz zrobić obraz dedykowany do konkretnego polecenia, którego użyjesz
ENTRYPOINT ["/path/dedicated_command"]
W przeciwnym razie, jeśli chcesz stworzyć obraz do ogólnego celu, możesz pozostawić
ENTRYPOINT
nieokreślony i użyć,CMD ["/path/dedicated_command"]
ponieważ będziesz w stanie zastąpić ustawienie, podając argumenty dodocker run
.Na przykład, jeśli Twój plik Docker to:
Uruchomienie obrazu bez żadnego argumentu spowoduje wysłanie polecenia ping do hosta lokalnego:
Teraz uruchomienie obrazu z argumentem spowoduje wysłanie polecenia ping do argumentu:
Dla porównania, jeśli Twój plik Docker to:
Uruchomienie obrazu bez żadnego argumentu spowoduje wysłanie polecenia ping do hosta lokalnego:
Ale uruchomienie obrazu z argumentem spowoduje uruchomienie argumentu:
Zobacz ten artykuł Briana DeHamera, aby uzyskać jeszcze więcej szczegółów: https://www.ctl.io/developers/blog/post/dockerfile-entrypoint-vs-cmd/
źródło
The ENTRYPOINT specifies a command that will always be executed when the container starts. The CMD specifies arguments that will be fed to the ENTRYPOINT.
jest dobrym podsumowaniem.Zgodnie z docs Döcker ,
Poniższe tabele pokazują, jakie polecenie jest wykonywane dla różnych
ENTRYPOINT
/CMD
kombinacji :-
No ENTRYPOINT
-
ENTRYPOINT exec_entry p1_entry
-
ENTRYPOINT [“exec_entry”, “p1_entry”]
źródło
/bin/sh -c
jest zaangażowany?/bin/sh -c
zostałby dodany do CMD jako przedrostek, podczas gdy CMD jest napisane w wykonywalnej składni (nie w składni listy).ENTRYPOINT exec_entry p1_ent
zostało źle wyjaśnione. Forma powłoki zapobiega użyciu jakichkolwiek argumentów CMD lub wiersza poleceń - docs.docker.com/engine/reference/builder/#entrypointTak, to dobre pytanie. Jeszcze tego nie rozumiem, ale:
Rozumiem, że
ENTRYPOINT
to plik binarny, który jest wykonywany. Możesz pominąć punkt wejścia przez --entrypoint = "".CMD jest domyślnym argumentem kontenera. Bez punktu wejścia domyślnym argumentem jest wykonywane polecenie. W przypadku punktu wejścia cmd jest przekazywane do punktu wejścia jako argument. Możesz emulować polecenie za pomocą punktu wejścia.
Główną zaletą jest to, że za pomocą punktu wejścia można przekazać argumenty (cmd) do kontenera. Aby to osiągnąć, musisz użyć obu:
i
wtedy możesz użyć:
źródło
docker run image_name -h
aby wyświetlić informacje pomocy dla tego obrazu.Różnica między CMD a ENTRYPOINT według intuicji :
Tak, to się miesza.
Możesz zastąpić dowolny z nich podczas uruchamiania okna dokowanego.
Różnica między CMD a ENTRYPOINT według przykładów :
Więcej na temat różnicy między
CMD
iENTRYPOINT
:Argument
docker run
taki jak / bin / bash zastępuje wszelkie polecenia CMD, które napisaliśmy w Dockerfile.ENTRYPOINT nie może być nadpisany w czasie wykonywania zwykłymi poleceniami, takimi jak
docker run [args]
. Naargs
końcudocker run [args]
są podane jako argumenty dla ENTRYPOINT. W ten sposób możemy stworzyćcontainer
normalny plik binarny, taki jakls
.Tak więc CMD może działać jako parametry domyślne dla ENTRYPOINT, a następnie możemy zastąpić argumenty CMD z [args].
ENTRYPOINT można zastąpić
--entrypoint
.źródło
W skrócie:
Jeśli potrzebujesz więcej szczegółów lub chciałbyś zobaczyć różnicę na przykład, jest post na blogu, który kompleksowo porównuje CMD i ENTRYPOINT z wieloma przykładami - http://goinbigdata.com/docker-run-vs-cmd-vs-entrypoint/
źródło
Dodaję odpowiedź jako przykład 1 który może pomóc ci lepiej zrozumieć różnicę.
Załóżmy, że chcemy utworzyć obraz, który zawsze uruchamia polecenie uśpienia podczas uruchamiania. Stworzymy własny obraz i określimy nowe polecenie:
Teraz budujemy obraz:
Co jeśli chcemy zmienić liczbę sekund? Musielibyśmy zmienić wartość,
Dockerfile
ponieważ wartość jest tam zapisana na stałe, lub zastąpić polecenie, podając inną:Chociaż to działa, nie jest to dobre rozwiązanie, ponieważ mamy nadmiarowe polecenie „uśpienia” (celem kontenera jest spanie , więc konieczność wyraźnego określenia
sleep
polecenia nie jest dobrą praktyką).Teraz spróbujmy użyć
ENTRYPOINT
instrukcji:Ta instrukcja określa program, który zostanie uruchomiony podczas uruchamiania kontenera .
Teraz możemy uruchomić:
Co z wartością domyślną? Dobrze zgadłeś:
Jest
ENTRYPOINT
to program, który zostanie uruchomiony, a wartość przekazana do kontenera zostanie do niego dołączona.ENTRYPOINT
Może być zastąpiona przez określenie--entrypoint
flagę, a następnie nowy punkt wyjścia, którego chcesz użyć.Nie mój, kiedyś obejrzałem samouczek z tym przykładem
źródło
Przyjęta odpowiedź jest wspaniała w wyjaśnianiu historii. Uważam, że ta tabela wyjaśnia to bardzo dobrze z oficjalnego dokumentu na temat „interakcji CMD i ENTRYPOINT” :
źródło
Komentarze do funkcji EntryPoint w kodzie
Kolejne odniesienie z dokumentów
Przykład:
Kompilacja : sudo docker build -t ent_cmd.
.
ps: W obecności EntryPoint, CMD przechowa argumenty do EntryPoint. Wbrew EntryPoint, CMD będzie poleceniem, które zostanie uruchomione.
źródło
CMD
polecenie wspomniane wDockerfile
pliku może zostać zastąpione przezdocker run
polecenie, podczas gdyENTRYPOINT
nie może być.źródło
docker run --help
polecenie mówi inaczej:--entrypoint string Overwrite the default ENTRYPOINT of the image
Przeczytałem wszystkie odpowiedzi i chcę podsumować dla lepszego zrozumienia na pierwszy rzut oka:
Po pierwsze, całe polecenie wykonywane w kontenerze składa się z dwóch części: polecenia i argumentów
W książce Kubernetes In Action wskazuje na to ważną uwagę. (Rozdział 7)
Możesz również przeczytać ten artykuł, aby uzyskać świetne wyjaśnienie w prosty sposób
źródło
CMD:
CMD ["executable","param1","param2"]
:["executable","param1","param2"]
to pierwszy proces.CMD command param1 param2
:/bin/sh -c CMD command param1 param2
to pierwszy proces.CMD command param1 param2
jest rozwidlony od pierwszego procesu.CMD ["param1","param2"]
: Ten formularz służy do podania domyślnych argumentów dlaENTRYPOINT
.ENTRYPOINT (Poniższa lista nie uwzględnia przypadku, w którym CMD i ENTRYPOINT są używane razem):
ENTRYPOINT ["executable", "param1", "param2"]
:["executable", "param1", "param2"]
to pierwszy proces.ENTRYPOINT command param1 param2
:/bin/sh -c command param1 param2
to pierwszy proces.command param1 param2
jest rozwidlony od pierwszego procesu.Jak powiedział Creack , najpierw opracowano CMD. Następnie opracowano ENTRYPOINT dla większej personalizacji. Ponieważ nie są one zaprojektowane razem, niektóre funkcje nakładają się między CMD i ENTRYPOINT, co często myli ludzi.
źródło
Większość ludzi wyjaśnia to tutaj doskonale, więc nie powtórzę wszystkich odpowiedzi. Ale aby uzyskać dobre samopoczucie, sugerowałbym przetestowanie go samemu, patrząc na procesy w pojemniku.
Utwórz mały plik Docker formularza:
Zbuduj, uruchom
docker run -it theimage
i uruchomps -eo ppid,pid,args
w kontenerze. Porównaj to wyjście z wyjściem otrzymanym z ps podczas używania:docker run -it theimage bash
ENTRYPOINT /bin/bash
i uruchamianie go na dwa sposobyCMD ["/bin/bash"]
W ten sposób z łatwością zobaczysz różnice między wszystkimi możliwymi metodami dla siebie.
źródło
Oficjalna dokumentacja najlepszych praktyk Dockerfile doskonale wyjaśnia różnice. Najlepsze praktyki dotyczące Dockerfile
CMD:
Do uruchomienia oprogramowania zawartego w obrazie należy użyć instrukcji CMD wraz z wszelkimi argumentami. CMD prawie zawsze powinno być stosowane w postaci
CMD ["executable", "param1", "param2"…]
. Zatem jeśli obraz dotyczy usługi, takiej jak Apache i Rails, uruchomiłbyś coś podobnegoCMD ["apache2","-DFOREGROUND"]
. Rzeczywiście, ta forma instrukcji jest zalecana dla każdego obrazu opartego na usługach.PUNKT WEJŚCIA:
Najlepszym zastosowaniem ENTRYPOINT jest ustawienie głównego polecenia obrazu, co pozwala na uruchomienie tego obrazu tak, jakby to było to polecenie (a następnie użycie CMD jako domyślnych flag).
źródło