Question Quelle est la différence entre CMD et ENTRYPOINT dans un Dockerfile?


Dans Dockerfiles, il y a deux commandes qui me ressemblent: CMD et ENTRYPOINT. Mais je suppose qu'il y a une différence (subtile?) Entre eux - sinon cela n'aurait aucun sens d'avoir deux commandes pour la même chose.

La documentation stipule pour CMD

L'objectif principal d'un CMD est de fournir des valeurs par défaut pour un conteneur en cours d'exécution.

et pour ENTRYPOINT:

Un ENTRYPOINT vous aide à configurer un conteneur que vous pouvez exécuter en tant qu'exécutable.

Alors, quelle est la différence entre ces deux commandes?


1030
2018-02-04 13:04


origine


Réponses:


Docker a un entrypoint par défaut qui est /bin/sh -c mais n'a pas de commande par défaut.

Lorsque vous exécutez docker comme ceci: docker run -i -t ubuntu bash l'entrypoint est le défaut /bin/sh -c, l'image est ubuntu et la commande est bash.

La commande est exécutée via l'entrypoint. c'est-à-dire que la chose réelle qui est exécutée est /bin/sh -c bash. Cela a permis à Docker de mettre en œuvre RUN rapidement en s'appuyant sur l'analyseur du shell.

Plus tard, les gens ont demandé à pouvoir personnaliser cela, donc ENTRYPOINT et --entrypoint ont été présenté.

Tout après ubuntu dans l'exemple ci-dessus est la commande et est passé à l'entrypoint. Lorsque vous utilisez le CMD instruction, c'est exactement comme si tu faisais docker run -i -t ubuntu <cmd>. <cmd> sera le paramètre de l'entrypoint.

Vous obtiendrez également le même résultat si vous tapez plutôt cette commande docker run -i -t ubuntu. Vous allez toujours commencer un shell bash dans le conteneur en raison de la Ubuntu Dockerfile spécifié un CMD par défaut: CMD ["bash"]

Comme tout est passé à l'entrypoint, vous pouvez avoir un très bon comportement de vos images. L'exemple @Jiri est bon, il montre comment utiliser une image comme un "binaire". En utilisant ["/bin/cat"] comme entrypoint et ensuite faire docker run img /etc/passwd, vous l'avez, /etc/passwd est la commande et est passée à l'entrypoint de sorte que l'exécution du résultat final est simplement /bin/cat /etc/passwd.

Un autre exemple serait d'avoir n'importe quel cli comme entrypoint. Par exemple, si vous avez une image redis, au lieu de courir docker run redisimg redis -H something -u toto get key, vous pouvez simplement avoir ENTRYPOINT ["redis", "-H", "something", "-u", "toto"] et puis courir comme ça pour le même résultat: docker run redisimg get key.


1083
2018-02-04 22:34



le ENTRYPOINT spécifie une commande qui sera toujours exécutée au démarrage du conteneur.

le CMD spécifie les arguments qui seront fournis au ENTRYPOINT.

Si vous voulez faire une image dédiée à une commande spécifique, vous utiliserez ENTRYPOINT ["/path/dedicated_command"]

Sinon, si vous voulez faire une image à usage général, vous pouvez laisser ENTRYPOINT non spécifié et utilisation CMD ["/path/dedicated_command"] comme vous serez en mesure de remplacer le paramètre en fournissant des arguments à docker run.

Par exemple, si votre Dockerfile est:

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

L'exécution de l'image sans argument pingera l'hôte local:

$ 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

Maintenant, exécuter l'image avec un argument pingera l'argument:

$ 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 titre de comparaison, si votre Dockerfile est:

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

L'exécution de l'image sans argument pingera l'hôte local:

$ 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

Mais exécuter l'image avec un argument lancera l'argument:

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

Voir cet article de Brian DeHamer pour encore plus de détails: https://www.ctl.io/developers/blog/post/dockerfile-entrypoint-vs-cmd/


264
2017-12-12 22:17



Oui, c'est une bonne question. Je ne comprends pas encore complètement, mais:

je comprends que ENTRYPOINT est le binaire en cours d'exécution. Vous pouvez dépasser le point d'entrée par --entrypoint = "".

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

CMD est l'argument par défaut du conteneur. Sans entrypoint, l'argument par défaut est la commande qui est exécutée. Avec entrypoint, cmd est passé à entrypoint comme argument. Vous pouvez émuler une commande avec entrypoint.

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

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

Donc, le principal avantage est qu'avec entrypoint vous pouvez passer des arguments (cmd) à votre conteneur. Pour ce faire, vous devez utiliser les deux:

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

et

docker build -t=cat .

alors vous pouvez utiliser:

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

138
2018-02-04 17:12



Selon docker docs,

Les instructions CMD et ENTRYPOINT définissent la commande exécutée   lors de l'exécution d'un conteneur. Il y a peu de règles qui décrivent leur   la coopération.

  1. Dockerfile doit spécifier au moins un CMD ou ENTRYPOINT commandes.
  2. ENTRYPOINT devrait être défini lors de l'utilisation du conteneur en tant qu'exécutable.
  3. CMD devrait être utilisé comme un moyen de définir les arguments par défaut pour un ENTRYPOINT commande ou pour exécuter une commande ad-hoc dans un   récipient.
  4. CMD sera remplacé lors de l'exécution du conteneur avec des arguments alternatifs.

Les tableaux ci-dessous montrent quelle commande est exécutée pour différents ENTRYPOINT / CMD combinaisons:

- 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 un mot:

  • CMD définit la commande et / ou les paramètres par défaut, qui peuvent être écrasés à partir de la ligne de commande lorsque le conteneur docker est exécuté.
  • La commande ENTRYPOINT et les paramètres ne seront pas remplacés à partir de la ligne de commande. Au lieu de cela, tous les arguments de ligne de commande seront ajoutés après les paramètres ENTRYPOINT.

Si vous avez besoin de plus de détails ou si vous voulez voir une différence sur l'exemple, il y a un blog qui compare CMD et ENTRYPOINT avec beaucoup d'exemples - http://goinbigdata.com/docker-run-vs-cmd-vs-entrypoint/ 


27
2018-04-03 09:32



Différence entre CMD et ENTRYPOINT par intuition:

  • ENTRYPOINT: commande à exécuter lorsque le conteneur démarre.
  • CMD: commande à exécuter lorsque le conteneur démarre ou arguments à ENTRYPOINT si spécifié.

Oui, ça se mélange.

Vous pouvez remplacer l'un d'entre eux lors de l'exécution du menu fixe.

Différence entre CMD et ENTRYPOINT par exemple:

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

Plus sur la différence entre CMD et ENTRYPOINT:

Argument à docker run comme / bin / bash remplace toute commande CMD que nous avons écrite dans Dockerfile.

ENTRYPOINT ne peut pas être remplacé lors de l'exécution avec des commandes normales telles que docker run [args]. le args au bout du docker run [args] sont fournis en tant qu'arguments à ENTRYPOINT. De cette façon, nous pouvons créer un container qui est comme un binaire normal tel que ls.

Ainsi CMD peut agir comme paramètres par défaut à ENTRYPOINT et ensuite nous pouvons remplacer les arguments CMD de [args].

ENTRYPOINT peut être remplacé par --entrypoint.


16
2018-01-16 12:34



La réponse acceptée est fabuleuse pour expliquer l'histoire. Je trouve que ce tableau l'explique très bien de doc officiel sur 'comment CMD et ENTRYPOINT interagissent': enter image description here


7
2018-05-31 07:12



Commentaires sur la fonction EntryPoint dans code

// ENTRYPOINT / usr / sbin / nginx.

// Définit le point d'entrée (qui par défaut est sh -c) sur / usr / sbin / nginx.

// Acceptera le CMD en tant qu'argument de / usr / sbin / nginx.

Une autre référence à partir de documents

Vous pouvez utiliser le formulaire exec de ENTRYPOINT pour définir commandes et arguments par défaut assez stables puis utilisez CMD pour définir des valeurs par défaut supplémentaires susceptibles d'être modifiées.

Exemple:

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

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

p.s: En présence d'EntryPoint, CMD conservera les arguments à envoyer à EntryPoint. En l'absence de EntryPoint, CMD sera la commande qui sera exécutée.


5
2018-01-16 07:32



CMD:

  • CMD ["executable","param1","param2"]: ["executable","param1","param2"] est le premier processus.
  • CMD command param1 param2: /bin/sh -c CMD command param1 param2 est le premier processus. CMD command param1 param2 est fourchue à partir du premier processus.
  • CMD ["param1","param2"]: Ce formulaire est utilisé pour fournir des arguments par défaut pour ENTRYPOINT.

ENTRYPOINT (La liste suivante ne considère pas le cas où CMD et ENTRYPOINT sont utilisés ensemble):

  • ENTRYPOINT ["executable", "param1", "param2"]: ["executable", "param1", "param2"] est le premier processus.
  • ENTRYPOINT command param1 param2: /bin/sh -c command param1 param2 est le premier processus. command param1 param2 est fourchue à partir du premier processus.

Comme creack dit, CMD a été développé en premier. Alors ENTRYPOINT a été développé pour plus de personnalisation. Comme ils ne sont pas conçus ensemble, il existe des chevauchements de fonctionnalités entre CMD et ENTRYPOINT, ce qui souvent déroutent les gens.


1
2018-01-05 06:42