No Dockerfiles, existem dois comandos semelhantes a mim: CMD
e ENTRYPOINT
. Mas acho que há uma diferença (sutil?) Entre eles - caso contrário, não faria sentido ter dois comandos para a mesma coisa.
A documentação declara para CMD
O principal objetivo de um CMD é fornecer padrões para um contêiner em execução.
e para ENTRYPOINT
:
Um ENTRYPOINT ajuda a configurar um contêiner que você pode executar como um executável.
Então, qual é a diferença entre esses dois comandos?
ADD
eCOPY
Respostas:
O Docker tem um ponto de entrada padrão que é,
/bin/sh -c
mas não possui um comando padrão.Quando você executa a janela de encaixe desta forma:
docker run -i -t ubuntu bash
o ponto de entrada é o padrão/bin/sh -c
, a imagem éubuntu
e o comando ébash
.O comando é executado através do ponto de entrada. ou seja, a coisa real que é executada é
/bin/sh -c bash
. Isso permitiu que o Docker fosse implementadoRUN
rapidamente, contando com o analisador do shell.Mais tarde, as pessoas pediram para poder personalizar isso
ENTRYPOINT
e--entrypoint
foram introduzidas.Tudo
ubuntu
o que se segue no exemplo acima é o comando e é passado para o ponto de entrada. Ao usar aCMD
instrução, é exatamente como se você estivesse fazendodocker run -i -t ubuntu <cmd>
.<cmd>
será o parâmetro do ponto de entrada.Você também obterá o mesmo resultado se digitar esse comando
docker run -i -t ubuntu
. Você ainda iniciará um shell bash no contêiner por causa do Dockerfile do ubuntu especificar um CMD padrão:CMD ["bash"]
Como tudo é passado para o ponto de entrada, você pode ter um comportamento muito agradável com suas imagens. @Jiri exemplo é bom, mostra como usar uma imagem como um "binário". Ao usar
["/bin/cat"]
como ponto de entrada e, em seguidadocker run img /etc/passwd
, executar , você recebe,/etc/passwd
é o comando e é passado para o ponto de entrada para que a execução do resultado final seja simples/bin/cat /etc/passwd
.Outro exemplo seria ter qualquer CLI como ponto de entrada. Por exemplo, se você tem uma imagem de Redis, em vez de correr
docker run redisimg redis -H something -u toto get key
, você pode simplesmente terENTRYPOINT ["redis", "-H", "something", "-u", "toto"]
e depois executar como este para o mesmo resultado:docker run redisimg get key
.fonte
ENTRYPOINT
; se um shell é usado depende da forma usada doCMD
comando ( docs.docker.com/engine/reference/builder/#cmd ).CMD
vsENTRYPOINT
.O
ENTRYPOINT
especifica um comando que sempre será executado quando o contêiner for iniciado.O
CMD
especifica argumentos que serão alimentados para oENTRYPOINT
.Se você quiser criar uma imagem dedicada a um comando específico, usará
ENTRYPOINT ["/path/dedicated_command"]
Caso contrário, se desejar criar uma imagem para uso geral, você pode deixar
ENTRYPOINT
não especificado e usá-CMD ["/path/dedicated_command"]
lo, pois poderá substituir a configuração fornecendo argumentos paradocker run
.Por exemplo, se o seu Dockerfile for:
A execução da imagem sem nenhum argumento fará ping no host local:
Agora, executar a imagem com um argumento fará ping no argumento:
Para comparação, se o seu Dockerfile for:
A execução da imagem sem nenhum argumento fará ping no host local:
Mas executar a imagem com um argumento executará o argumento:
Consulte este artigo de Brian DeHamer para obter mais detalhes: https://www.ctl.io/developers/blog/post/dockerfile-entrypoint-vs-cmd/
fonte
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.
é um bom resumo direto do ponto.De acordo com os documentos do docker ,
As tabelas abaixo mostram qual comando é executado para diferentes
ENTRYPOINT
/CMD
combinações :-
No ENTRYPOINT
-
ENTRYPOINT exec_entry p1_entry
-
ENTRYPOINT [“exec_entry”, “p1_entry”]
fonte
/bin/sh -c
está envolvido?/bin/sh -c
seria adicionado ao CMD como prefixo enquanto o CMD era gravado na sintaxe executável (não na sintaxe da lista).ENTRYPOINT exec_entry p1_ent
foi explicado erroneamente. A forma de concha impede quaisquer argumentos de linha de comando CMD ou execução de ser usado - docs.docker.com/engine/reference/builder/#entrypointSim, essa é uma boa pergunta. Ainda não o compreendo completamente, mas:
Eu entendo que
ENTRYPOINT
é o binário que está sendo executado. Você pode substituir o ponto de entrada por --entrypoint = "".CMD é o argumento padrão para o contêiner. Sem ponto de entrada, o argumento padrão é o comando que é executado. Com o ponto de entrada, o cmd é passado para o ponto de entrada como argumento. Você pode emular um comando com ponto de entrada.
Portanto, a principal vantagem é que, com o ponto de entrada, você pode passar argumentos (cmd) para o seu contêiner. Para fazer isso, você precisa usar os dois:
e
então você pode usar:
fonte
docker run image_name -h
para mostrar algumas informações de ajuda desta imagem.Diferença entre CMD e ENTRYPOINT por intuição :
Sim, está se misturando.
Você pode substituir qualquer um deles ao executar a janela de encaixe.
Diferença entre CMD e ENTRYPOINT por exemplo :
Mais sobre a diferença entre
CMD
eENTRYPOINT
:Argumentos
docker run
como / bin / bash substituem qualquer comando CMD que escrevemos no Dockerfile.ENTRYPOINT não pode ser substituído no tempo de execução por comandos normais como
docker run [args]
. Noargs
final dedocker run [args]
são fornecidos como argumentos para ENTRYPOINT. Desta forma, podemos criar umcontainer
que é como um binário normal comols
.Portanto, o CMD pode atuar como parâmetros padrão para ENTRYPOINT e, em seguida, podemos substituir os args do CMD de [args].
ENTRYPOINT pode ser substituído por
--entrypoint
.fonte
Em poucas palavras:
Se você precisar de mais detalhes ou quiser ver a diferença no exemplo, há uma postagem no blog que compara de maneira abrangente o CMD e o ENTRYPOINT com vários exemplos - http://goinbigdata.com/docker-run-vs-cmd-vs-entrypoint/
fonte
Vou adicionar minha resposta como exemplo 1 que pode ajudar você a entender melhor a diferença.
Vamos supor que queremos criar uma imagem que sempre execute um comando de suspensão quando for iniciado. Criaremos nossa própria imagem e especificaremos um novo comando:
Agora, criamos a imagem:
E se quisermos mudar o número de segundos? Teríamos que alterar o
Dockerfile
valor como o código é codificado lá ou substituir o comando fornecendo um diferente:Enquanto isso funciona, não é uma boa solução, pois temos um comando "sleep" redundante (o objetivo do contêiner é dormir , portanto, especificar explicitamente o
sleep
comando não é uma boa prática).Agora vamos tentar usar a
ENTRYPOINT
instrução:Esta instrução especifica o programa que será executado quando o contêiner iniciar .
Agora podemos executar:
Que tal um valor padrão? Bem, você adivinhou certo:
O
ENTRYPOINT
é o programa que será executado e o valor passado para o contêiner será anexado a ele.O
ENTRYPOINT
pode ser substituído, especificando um--entrypoint
sinalizador, seguido pelo novo ponto de entrada que você deseja usar.Não meu, uma vez assisti a um tutorial que forneceu este exemplo
fonte
A resposta aceita é fabulosa ao explicar a história. Acho que esta tabela explica muito bem o documento oficial sobre 'como o CMD e o ENTRYPOINT interagem' :
fonte
Comentários sobre a função EntryPoint no código
Outra referência de documentos
Exemplo:
Compilação : sudo docker build -t ent_cmd.
.
ps: Na presença do EntryPoint, o CMD manterá argumentos para alimentar o EntryPoint. Na ausência do EntryPoint, o CMD será o comando que será executado.
fonte
CMD
O comando mencionado dentro doDockerfile
arquivo pode ser substituído pelodocker run
comando enquantoENTRYPOINT
não pode ser.fonte
docker run --help
comando diz o contrário:--entrypoint string Overwrite the default ENTRYPOINT of the image
Li todas as respostas e quero resumir para uma melhor compreensão à primeira vista, como a seguir:
Primeiramente, todo o comando executado no contêiner inclui duas partes: o comando e os argumentos
No livro Kubernetes In Action, destaca-se uma nota importante. (Capítulo 7)
Você também pode ler este artigo para obter ótimas explicações de uma maneira simples
fonte
CMD:
CMD ["executable","param1","param2"]
:["executable","param1","param2"]
é o primeiro processo.CMD command param1 param2
:/bin/sh -c CMD command param1 param2
é o primeiro processo.CMD command param1 param2
é bifurcada desde o primeiro processo.CMD ["param1","param2"]
: Este formulário é usado para fornecer argumentos padrão paraENTRYPOINT
.ENTRYPOINT (A lista a seguir não considera o caso em que CMD e ENTRYPOINT são usados juntos):
ENTRYPOINT ["executable", "param1", "param2"]
:["executable", "param1", "param2"]
é o primeiro processo.ENTRYPOINT command param1 param2
:/bin/sh -c command param1 param2
é o primeiro processo.command param1 param2
é bifurcada desde o primeiro processo.Como o creack disse, o CMD foi desenvolvido primeiro. Em seguida, o ENTRYPOINT foi desenvolvido para mais personalização. Como eles não são projetados juntos, existem algumas sobreposições de funcionalidade entre o CMD e o ENTRYPOINT, que geralmente confundem as pessoas.
fonte
A maioria das pessoas explica perfeitamente aqui, então não vou repetir todas as respostas. Mas, para ter uma boa sensação, sugiro testá-lo, analisando os processos no contêiner.
Crie um pequeno Dockerfile do formulário:
Construa, execute
docker run -it theimage
e executeps -eo ppid,pid,args
no contêiner. Compare esta saída com a saída que você recebe do ps ao usar:docker run -it theimage bash
ENTRYPOINT /bin/bash
e executando-a nos dois sentidosCMD ["/bin/bash"]
Dessa forma, você verá facilmente as diferenças entre todos os métodos possíveis.
fonte
A documentação oficial das melhores práticas do Dockerfile faz um ótimo trabalho explicando as diferenças. Práticas recomendadas do Dockerfile
CMD:
A instrução CMD deve ser usada para executar o software contido na sua imagem, juntamente com quaisquer argumentos. O CMD quase sempre deve ser usado na forma de
CMD ["executable", "param1", "param2"…]
. Portanto, se a imagem for para um serviço, como Apache e Rails, você executaria algo parecidoCMD ["apache2","-DFOREGROUND"]
. De fato, essa forma de instrução é recomendada para qualquer imagem baseada em serviço.PONTO DE ENTRADA:
O melhor uso para ENTRYPOINT é definir o comando principal da imagem, permitindo que a imagem seja executada como se fosse esse comando (e use o CMD como sinalizadores padrão).
fonte