A diferença entre CMD e ENTRYPOINT em imagens do Docker

As instruções CMD e ENTRYPOINT são duas diretivas Dockerfile comumente confundidas. Ambos têm a função de determinar o comando que será executado quando o contêiner for iniciado.
O CMD e o ENTRYPOINT podem ser substituídos individualmente em cada imagem. O uso eficaz dessas diretivas torna seu contêiner mais fácil de usar, reduzindo o comprimento dos comandos fornecidos.
Qual é o ponto de entrada?
Analisaremos o ENTRYPOINT primeiro, pois ele é processado antes do CMD ao iniciar um novo contêiner. O ponto de entrada da imagem define o processo que será executado quando o contêiner for iniciado.
O Docker padroniza o ponto de entrada para / bin / sh -c. Isso significa que você terminará em uma sessão de shell ao iniciar o contêiner. Para muitos contêineres, é mais desejável ter um processo diferente iniciado por padrão. Você deseja que os serviços sem controle iniciem sua carga de trabalho imediatamente.
Definir a diretiva ENTRYPOINT em um Dockerfile instrui o Docker a executar um comando específico quando o contêiner é iniciado. Ele se tornará o processo de primeiro plano, em vez da sessão de shell padrão.
[PRÉ] PONTO DE ENTRADA ["data"]
Um contêiner criado com este Dockerfile executará o comando date. Como a data não é um processo de primeiro plano de longa duração, o contêiner sairá imediatamente depois.
Os pontos de entrada devem ser binários ou scripts executáveis. Seu contêiner não será iniciado se você especificar um ponto de entrada inválido. Se você estiver usando um script personalizado, certifique-se de que ele tenha o conjunto de bits executáveis. Você pode adicionar permissões de execução usando chmod + x my-script. sh.
Adicionando o comando (CMD)
A instrução CMD é um nome impróprio. Ele fornece argumentos padrão para o comando definido por ENTRYPOINT.
ENTRYPOINT ["data"] CMD ["+% A"]
Este exemplo resulta na data de execução do contêiner +% A. O argumento +% A para data exibe o dia atual da semana (por exemplo, segunda-feira).
O CMD foi projetado para ser substituído. docker run permite que você especifique um comando diferente para uma instância de contêiner individual:
docker executa minha imagem +% B
O CMD padrão será substituído por +% B, fazendo com que o container exiba o nome do mês atual. Isso funciona porque o ponto de entrada da imagem permanece intacto. O CMD é sempre anexado ao ENTRYPOINT, então o comando final torna-se data +% B.
Você deve usar ENTRYPOINT para definir o executável principal do seu contêiner. Use o CMD para definir os argumentos padrão para esse executável. Ele será substituído quando o contêiner for executado com argumentos diferentes.
Substituições de ponto de entrada
Você pode forçar o Docker a iniciar uma imagem usando um ponto de entrada personalizado. Passe o sinalizador --entrypoint para docker run:
docker run --entrypoint / bin / sh minha-imagem
O ponto de entrada definido na imagem do contêiner será ignorado em favor do comando que você especificou. Em nosso exemplo, uma sessão de shell será iniciada, em vez do comando de data.
A substituição de pontos de entrada deve ser uma ocorrência rara. Isso pode ir contra as intenções do autor da imagem. Entretanto, definir um ponto de entrada personalizado pode ser útil, principalmente durante a depuração. Se um contêiner estiver se comportando mal, substituir seu ponto de entrada pode conceder a você acesso ao shell que você não poderia obter de outra forma.
Qual usar?
Se você for um autor de imagens, deverá usar ENTRYPOINT ao definir o que seu contêiner executará. Se você deseja fornecer argumentos padrão, mas espera que o usuário os substitua, inclua o CMD também.
Como um usuário de imagem, você normalmente pode se limitar a substituir o CMD. docker run tem suporte transparente para substituições de comandos. Quaisquer argumentos fornecidos após o nome da imagem serão interpretados como a string CMD do contêiner.
Modos de ponto de entrada: Shell ou Exec
Na verdade, o Docker suporta duas formas diferentes de ENTRYPOINT: modo exec e modo shell. O modo Exec é caracterizado pelo uso de uma construção de matriz para especificar parâmetros. No modo shell, o comando é especificado como uma string.
# modo exec ENTRYPOINT ["binário", "--param", "--another-param"] # modo shell ENTRYPOINT binário --param --another-param
Usar o modo shell faz com que seu binário seja executado como um subprocesso de / bin / sh -c. Isso dá ao seu ponto de entrada acesso às variáveis de ambiente definidas pelo shell.
No entanto, o modo Shell tem vantagens. Você não pode usar o CMD para que os usuários não consigam fazer substituições. Os argumentos fornecidos para a execução do docker serão ignorados; seu contêiner sempre usará o ponto de entrada no estado em que se encontra.
Como seu binário é executado em um shell, os comandos de ciclo de vida do Docker, como docker stop, podem funcionar de forma irregular ou nem funcionar. O Docker sinalizará ao shell para parar, em vez do processo interno. Você pode iniciar seu processo com exec para evitar isso.
ENTRYPOINT exec binário --param --another-param
Benefícios da abordagem de ponto de entrada do Docker
Separar o ponto de entrada de seus argumentos ajuda a ocultar a complexidade em seus contêineres. Isso é mais benéfico quando você &’ está criando recipientes de utilitário para encapsular programas CLI.
Defina o binário da CLI como o ponto de entrada da imagem. Isso permite que os usuários interajam sem repetir o nome binário em cada comando.
Considere se empacotamos o Dockerfile acima como data: mais recente:
# data de execução do docker do ponto de entrada padrão (/ bin / sh -c): data mais recente +% A # com `date` como a data de execução do docker do ponto de entrada: mais recente +% A`
Definir um ponto de entrada personalizado encurta os comandos e reduz a repetição. O contêiner se torna mais especializado invocando data automaticamente. Isso cria uma interface mais amigável para seus usuários.
Resumo
As instruções ENTRYPOINT e CMD doDocker são uma fonte frequente de confusão. Seus nomes mascaram seus propósitos pretendidos.
Use ENTRYPOINT para definir o “ comando ” que será executado quando novos contêineres forem iniciados. Você pode definir argumentos padrão usando CMD. ENTRYPOINT e CMD são combinados para produzir a string de comando final do contêiner.
Quando você usa docker run, o Docker substitui o CMD padrão da imagem pelos argumentos que você especificar. Se você precisar substituir o ponto de entrada de uma imagem, use o sinalizador --entrypoint.
Nenhum comentário