Pregunta ¿Cuál es la diferencia entre CMD y ENTRYPOINT en un archivo Docker?


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 la misma cosa.

La documentación dice para CMD

El objetivo principal de una CMD es proporcionar valores predeterminados para un contenedor de ejecución.

y para ENTRYPOINT:

Un ENTRYPOINT le ayuda a configurar un contenedor que puede ejecutar como un ejecutable.

Entonces, ¿cuál es la diferencia entre esos dos comandos?


1030
2018-02-04 13:04


origen


Respuestas:


Docker tiene un punto de entrada predeterminado que es /bin/sh -c pero no tiene un comando predeterminado.

Cuando ejecutas docker de esta manera: docker run -i -t ubuntu bash el punto de entrada es el predeterminado /bin/sh -c, la imagen es ubuntu y el comando es bash.

El comando se ejecuta a través del punto de entrada. es decir, la cosa real que se ejecuta es /bin/sh -c bash. Esto permitió a Docker implementar RUN rápidamente al confiar en el analizador del intérprete de comandos.

Más tarde, la gente pidió que se pueda personalizar esto, por lo que ENTRYPOINT y --entrypoint fueron presentados.

Todo después ubuntu en el ejemplo anterior es el comando y se pasa al punto de entrada. Al usar el CMD instrucción, es exactamente como si estuvieras haciendo docker 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. Todavía comenzará un shell bash en el contenedor debido a la ubuntu Dockerfile 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 un "binario". Cuando usas ["/bin/cat"] como punto de entrada y luego haciendo docker run img /etc/passwd, usted lo consigue, /etc/passwd es el comando y se pasa al punto de entrada para que la ejecución del resultado final sea simplemente /bin/cat /etc/passwd.

Otro ejemplo sería tener cualquier cli como punto de entrada. Por ejemplo, si tiene una imagen redis, en lugar de ejecutar docker run redisimg redis -H something -u toto get key, simplemente puede tener ENTRYPOINT ["redis", "-H", "something", "-u", "toto"] y luego corre así para el mismo resultado: docker run redisimg get key.


1083
2018-02-04 22:34



los ENTRYPOINT especifica un comando que siempre se ejecutará cuando se inicie el contenedor.

los CMD especifica los argumentos que se alimentarán al ENTRYPOINT.

Si desea hacer una imagen dedicada a un comando específico, usará ENTRYPOINT ["/path/dedicated_command"]

De lo contrario, si quiere hacer una imagen para un propósito general, puede irse ENTRYPOINT no especificado y uso CMD ["/path/dedicated_command"] ya que podrá anular la configuración suministrando argumentos para docker run.

Por ejemplo, si su Dockerfile es:

FROM debian:wheezy
ENTRYPOINT ["/bin/ping"]
CMD ["localhost"]

Ejecutar la imagen sin ningún argumento hará ping al 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

Ahora, ejecutar la imagen con un argumento hará ping al argumento:

$ 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

A modo de comparación, si su Dockerfile es:

FROM debian:wheezy
CMD ["/bin/ping", "localhost"]

Ejecutar la imagen sin ningún argumento hará ping al 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

Pero ejecutar la imagen con un argumento ejecutará el argumento:

docker run -it test bash
root@e8bb7249b843:/#

Vea este artículo de Brian DeHamer para más detalles: https://www.ctl.io/developers/blog/post/dockerfile-entrypoint-vs-cmd/


264
2017-12-12 22:17



Sí, esa es una buena pregunta. Todavía no lo entiendo completamente, pero:

Entiendo que ENTRYPOINT es el binario que se está ejecutando. Puede sobreponer el punto de entrada por --entrypoint = "".

docker run -t -i --entrypoint="/bin/bash" ubuntu

CMD es el argumento predeterminado para contenedor. Sin punto de entrada, el argumento predeterminado es el comando que se ejecuta. Con entrypoint, cmd se pasa al punto de entrada como argumento. Puedes emular un comando con punto de entrada.

# no entrypoint
docker run ubuntu /bin/cat /etc/passwd

# with entry point, emulating cat command
docker run --entrypoint="/bin/cat" ubuntu /etc/passwd

Entonces, la principal ventaja es que con entrypoint puedes pasar argumentos (cmd) a tu contenedor. Para lograr esto, debe usar ambos:

# Dockerfile
FROM ubuntu
ENTRYPOINT ["/bin/cat"]

y

docker build -t=cat .

entonces puedes usar:

docker run cat /etc/passwd
#              ^^^^^^^^^^^
#                   CMD
#          ^^^      
#          image (tag)- using the default ENTRYPOINT

138
2018-02-04 17:12



De acuerdo a docker docs,

Las instrucciones CMD y ENTRYPOINT definen qué comando se ejecuta   cuando se ejecuta un contenedor. Hay pocas reglas que describen su   cooperación.

  1. Dockerfile debe especificar al menos uno de CMD o ENTRYPOINT comandos.
  2. ENTRYPOINT debe definirse cuando se utiliza el contenedor como un ejecutable.
  3. CMD debe usarse como una forma de definir argumentos predeterminados para un ENTRYPOINT comando o para ejecutar un comando ad-hoc en un   envase.
  4. CMD se anulará al ejecutar el contenedor con argumentos alternativos.

Las tablas a continuación muestran qué comando se ejecuta para diferentes ENTRYPOINT / CMD combinaciones:

- 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  ║
╚════════════════════════════╩═════════════════════════════════════════════════╝

109
2017-09-09 09:52



En una palabra:

  • CMD establece comandos y / o parámetros predeterminados, que se pueden sobrescribir desde la línea de comandos cuando se ejecuta el contenedor docker.
  • El comando y los parámetros de ENTRYPOINT no se sobrescribirán desde la línea de comandos. En cambio, todos los argumentos de línea de comando se agregarán después de los parámetros ENTRYPOINT.

Si necesita más detalles o le gustaría ver la diferencia en el ejemplo, hay una publicación en el blog que compara exhaustivamente CMD y ENTRYPOINT con muchos ejemplos: http://goinbigdata.com/docker-run-vs-cmd-vs-entrypoint/ 


27
2018-04-03 09:32



Diferencia entre CMD y ENTRYPOINT por intuición:

  • ENTRYPOINT: comando para ejecutar cuando se inicia el contenedor.
  • CMD: comando para ejecutar cuando el contenedor se inicia o argumentos a ENTRYPOINT si se especifica.

Sí, se está mezclando.

Puede anular cualquiera de ellos al ejecutar la ejecución del acoplador.

Diferencia entre CMD y ENTRYPOINT por ejemplo:

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

Más sobre la diferencia entre CMD y ENTRYPOINT:

Argumento a docker run como / bin / bash anula cualquier comando de CMD que hayamos escrito en Dockerfile.

ENTRYPOINT no se puede anular en tiempo de ejecución con comandos normales como docker run [args]. los args al final de docker run [args] se proporcionan como argumentos para ENTRYPOINT. De esta manera, podemos crear un container que es como un binario normal como ls.

Entonces, CMD puede actuar como parámetros por defecto en ENTRYPOINT y luego podemos anular los argumentos de CMD de [args].

ENTRYPOINT puede ser anulado con --entrypoint.


16
2018-01-16 12:34



La respuesta aceptada es fabulosa al explicar la historia. Encuentro que esta tabla lo explica muy bien de documento oficial sobre 'cómo interactúan CMD y ENTRYPOINT': enter image description here


7
2018-05-31 07:12



Comentarios sobre la función EntryPoint en código

// ENTRYPOINT / usr / sbin / nginx.

// Establecer el punto de entrada (que por defecto es sh -c) en / usr / sbin / nginx.

// Acepta el CMD como argumentos para / usr / sbin / nginx.

Otra referencia de documentos

Puede usar la forma ejecutiva de ENTRYPOINT para establecer comandos y argumentos predeterminados bastante estables y luego use CMD para establecer valores predeterminados adicionales que es más probable que se modifiquen.

Ejemplo:

FROM ubuntu:14.04.3
ENTRYPOINT ["/bin/ping"]
CMD ["localhost", "-c", "2"]

Construir: 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

PD: En presencia de EntryPoint, CMD mantendrá argumentos para alimentar a EntryPoint. En ausencia de EntryPoint, CMD será el comando que se ejecutará.


5
2018-01-16 07:32



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 usa para proporcionar argumentos predeterminados para ENTRYPOINT.

ENTRYPOINT (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 crepitar dijo, CMD fue desarrollado primero. Luego, ENTRYPOINT se desarrolló para una mayor personalización. Debido a que no están diseñados en conjunto, existen algunas superposiciones de funcionalidad entre CMD y ENTRYPOINT, que a menudo confunden a las personas.


1
2018-01-05 06:42