En Dockerfiles hay dos comandos que se parecen a mí: CMD
y ENTRYPOINT
. Pero supongo que hay una diferencia (¿sutil?) Entre ellos; de lo contrario, no tendría sentido tener dos comandos para lo mismo.
La documentación indica para CMD
El objetivo principal de un CMD es proporcionar valores predeterminados para un contenedor en ejecución.
y para ENTRYPOINT
:
Un ENTRYPOINT lo ayuda a configurar un contenedor que puede ejecutar como ejecutable.
Entonces, ¿cuál es la diferencia entre esos dos comandos?
ADD
yCOPY
Respuestas:
Docker tiene un punto de entrada predeterminado que es
/bin/sh -c
pero no tiene un comando predeterminado.Cuando ejecuta
docker run -i -t ubuntu bash
Docker de esta manera: el punto de entrada es el predeterminado/bin/sh -c
, la imagen esubuntu
y el comando esbash
.El comando se ejecuta a través del punto de entrada. es decir, lo que realmente se ejecuta es
/bin/sh -c bash
. Esto permitió a Docker implementarRUN
rápidamente confiando en el analizador del shell.Más tarde, la gente pidió poder personalizar esto,
ENTRYPOINT
y--entrypoint
se presentaron.Todo lo que
ubuntu
sigue en el ejemplo anterior es el comando y se pasa al punto de entrada. Al usar laCMD
instrucción, es exactamente como si lo estuviera haciendodocker run -i -t ubuntu <cmd>
.<cmd>
será el parámetro del punto de entrada.También obtendrá el mismo resultado si en su lugar escribe este comando
docker run -i -t ubuntu
. Aún comenzará un shell bash en el contenedor debido a que el Dockerfile de ubuntu especificó un CMD predeterminado:CMD ["bash"]
Como todo se pasa al punto de entrada, puede tener un comportamiento muy agradable de sus imágenes. El ejemplo de @Jiri es bueno, muestra cómo usar una imagen como "binario". Cuando se usa
["/bin/cat"]
como punto de entrada y luego se hacedocker run img /etc/passwd
, se obtiene,/etc/passwd
es el comando y se pasa al punto de entrada para que la ejecución del resultado final sea sencilla/bin/cat /etc/passwd
.Otro ejemplo sería tener cualquier cli como punto de entrada. Por ejemplo, si usted tiene una imagen de Redis, en lugar de correr
docker run redisimg redis -H something -u toto get key
, sólo tiene que tenerENTRYPOINT ["redis", "-H", "something", "-u", "toto"]
y luego ejecutar así por el mismo resultado:docker run redisimg get key
.fuente
ENTRYPOINT
; si se utiliza un shell depende de la forma utilizada delCMD
comando ( docs.docker.com/engine/reference/builder/#cmd ).CMD
vsENTRYPOINT
.Las
ENTRYPOINT
especifica un comando que siempre se ejecuta cuando se inicia el contenedor.El
CMD
especifica los argumentos que serán alimentados alENTRYPOINT
.Si desea hacer una imagen dedicada a un comando específico, utilizará
ENTRYPOINT ["/path/dedicated_command"]
De lo contrario, si desea crear una imagen para fines generales, puede dejarla sin
ENTRYPOINT
especificar y usar,CMD ["/path/dedicated_command"]
ya que podrá anular la configuración al proporcionar argumentos adocker run
.Por ejemplo, si su Dockerfile es:
Ejecutar la imagen sin ningún argumento hará ping al localhost:
Ahora, ejecutar la imagen con un argumento hará ping al argumento:
A modo de comparación, si su Dockerfile es:
Ejecutar la imagen sin ningún argumento hará ping al localhost:
Pero ejecutar la imagen con un argumento ejecutará el argumento:
Vea este artículo de Brian DeHamer para obtener más detalles: https://www.ctl.io/developers/blog/post/dockerfile-entrypoint-vs-cmd/
fuente
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.
es un buen resumen al punto.Según los documentos de Docker ,
Las tablas a continuación muestran qué comando se ejecuta para diferentes
ENTRYPOINT
/CMD
combinaciones :-
No ENTRYPOINT
-
ENTRYPOINT exec_entry p1_entry
-
ENTRYPOINT [“exec_entry”, “p1_entry”]
fuente
/bin/sh -c
está involucrado?/bin/sh -c
se agregaría a CMD como prefijo mientras CMD está escrito en sintaxis ejecutable (no en la sintaxis de lista).ENTRYPOINT exec_entry p1_ent
fue mal explicado. El formulario de shell evita que se utilicen argumentos CMD o de línea de comandos de ejecuciónSí, esa es una buena pregunta. Todavía no lo entiendo completamente, pero:
Entiendo que
ENTRYPOINT
es el binario que se está ejecutando. Puede anular el punto de entrada mediante --entrypoint = "".CMD es el argumento predeterminado para el contenedor. Sin punto de entrada, el argumento predeterminado es un comando que se ejecuta. Con punto de entrada, cmd se pasa al punto de entrada como argumento. Puede emular un comando con punto de entrada.
Entonces, la principal ventaja es que con el punto de entrada puede pasar argumentos (cmd) a su contenedor. Para lograr esto, debe usar ambos:
y
entonces puedes usar:
fuente
docker run image_name -h
para mostrar información de ayuda de esta imagen.Diferencia entre CMD y ENTRYPOINT por intuición :
Sí, se está mezclando.
Puede anular cualquiera de ellos cuando ejecute Docker Run.
Diferencia entre CMD y ENTRYPOINT por ejemplo :
Más sobre la diferencia entre
CMD
yENTRYPOINT
:Argumentos
docker run
como / bin / bash anulan cualquier comando CMD que escribimos en Dockerfile.ENTRYPOINT no se puede anular en tiempo de ejecución con comandos normales como
docker run [args]
. Alargs
final dedocker run [args]
se proporcionan como argumentos para ENTRYPOINT. De esta manera podemos crear uncontainer
que es como un binario normal comols
.Por lo tanto, CMD puede actuar como parámetros predeterminados para ENTRYPOINT y luego podemos anular los args CMD de [args].
ENTRYPOINT se puede anular con
--entrypoint
.fuente
En una palabra:
Si necesita más detalles o desea ver la diferencia en el ejemplo, hay una publicación de blog que compara exhaustivamente CMD y ENTRYPOINT con muchos ejemplos: http://goinbigdata.com/docker-run-vs-cmd-vs-entrypoint/
fuente
Agregaré mi respuesta como ejemplo 1 que podría ayudarlo a comprender mejor la diferencia.
Supongamos que queremos crear una imagen que siempre ejecutará un comando de suspensión cuando se inicie. Crearemos nuestra propia imagen y especificaremos un nuevo comando:
Ahora, construimos la imagen:
¿Qué pasa si queremos cambiar el número de segundos? Tendríamos que cambiar el
Dockerfile
valor ya que el valor está codificado allí, o anular el comando proporcionando uno diferente:Si bien esto funciona, no es una buena solución, ya que tenemos un comando de "suspensión" redundante (el propósito del contenedor es dormir , por lo que tener que especificar explícitamente el
sleep
comando no es una buena práctica).Ahora intentemos usar las
ENTRYPOINT
instrucciones:Esta instrucción especifica el programa que se ejecutará cuando se inicie el contenedor .
Ahora podemos ejecutar:
¿Qué pasa con un valor predeterminado? Bueno, lo has adivinado bien:
El
ENTRYPOINT
es el programa que se ejecutará y se le agregará el valor pasado al contenedor.Se
ENTRYPOINT
puede anular especificando un--entrypoint
indicador, seguido del nuevo punto de entrada que desea usar.No es mío, una vez vi un tutorial que proporcionó este ejemplo
fuente
La respuesta aceptada es fabulosa para explicar la historia. Encuentro que esta tabla lo explica muy bien del documento oficial sobre 'cómo interactúan CMD y ENTRYPOINT' :
fuente
Comentarios sobre la función EntryPoint en el código
Otra referencia de documentos
Ejemplo:
Construir : sudo ventana acoplable acumulación -t ent_cmd.
.
ps: en presencia de EntryPoint, CMD mantendrá argumentos para alimentar a EntryPoint. En ausencia de EntryPoint, CMD será el comando que se ejecutará.
fuente
CMD
El comando mencionado dentro delDockerfile
archivo se puede anular mediante undocker run
comando, mientrasENTRYPOINT
que no se puede.fuente
docker run --help
el comando dice lo contrario:--entrypoint string Overwrite the default ENTRYPOINT of the image
He leído todas las respuestas y quiero resumirlas para una mejor comprensión a primera vista como las siguientes:
En primer lugar, todo el comando que se ejecuta en el contenedor incluye dos partes: el comando y los argumentos
En el libro Kubernetes In Action señala una nota importante al respecto. (Capítulo 7)
También puede leer este artículo para obtener una gran explicación de una manera simple
fuente
CMD:
CMD ["executable","param1","param2"]
:["executable","param1","param2"]
es el primer proceso.CMD command param1 param2
:/bin/sh -c CMD command param1 param2
es el primer proceso.CMD command param1 param2
se bifurca desde el primer proceso.CMD ["param1","param2"]
: Este formulario se utiliza para proporcionar argumentos predeterminados paraENTRYPOINT
.PUNTO DE ENTRADA (La siguiente lista no considera el caso donde CMD y ENTRYPOINT se usan juntos):
ENTRYPOINT ["executable", "param1", "param2"]
:["executable", "param1", "param2"]
es el primer proceso.ENTRYPOINT command param1 param2
:/bin/sh -c command param1 param2
es el primer proceso.command param1 param2
se bifurca desde el primer proceso.Como dijo Creack , CMD se desarrolló primero. Luego ENTRYPOINT fue desarrollado para una mayor personalización. Dado que no están diseñados juntos, hay algunas superposiciones de funcionalidad entre CMD y ENTRYPOINT, que a menudo confunden a las personas.
fuente
La mayoría de la gente lo explica perfectamente aquí, así que no repetiré todas las respuestas. Pero para tener una buena idea, sugeriría probarlo usted mismo observando los procesos en el contenedor.
Cree un pequeño Dockerfile de la forma:
Constrúyalo, ejecútelo
docker run -it theimage
y ejecútelops -eo ppid,pid,args
en el contenedor. Compare esta salida con la salida que recibe de ps cuando usa:docker run -it theimage bash
ENTRYPOINT /bin/bash
y ejecutándola de ambas manerasCMD ["/bin/bash"]
De esta manera, verá fácilmente las diferencias entre todos los métodos posibles.
fuente
La documentación oficial de las mejores prácticas de Dockerfile hace un gran trabajo explicando las diferencias. Mejores prácticas de Dockerfile
CMD:
La instrucción CMD debe usarse para ejecutar el software contenido en su imagen, junto con cualquier argumento. La CMD casi siempre debe usarse en forma de
CMD ["executable", "param1", "param2"…]
. Por lo tanto, si la imagen es para un servicio, como Apache y Rails, ejecutaría algo asíCMD ["apache2","-DFOREGROUND"]
. De hecho, esta forma de instrucción se recomienda para cualquier imagen basada en servicios.PUNTO DE ENTRADA:
El mejor uso para ENTRYPOINT es establecer el comando principal de la imagen, permitiendo que esa imagen se ejecute como si fuera ese comando (y luego usar CMD como los indicadores predeterminados).
fuente