В Dockerfiles есть две команды, которые похожи на меня: CMD
и ENTRYPOINT
. Но я думаю, что между ними есть (тонкая?) Разница - иначе было бы бессмысленно иметь две команды для одной и той же вещи.
Документация заявляет для CMD
Основная цель CMD - предоставить значения по умолчанию для исполняющего контейнера.
и для ENTRYPOINT
:
ENTRYPOINT помогает вам настроить контейнер, который вы можете запускать как исполняемый файл.
Итак, в чем разница между этими двумя командами?
ADD
иCOPY
Ответы:
Docker имеет точку входа по умолчанию, которая
/bin/sh -c
не имеет команды по умолчанию.Когда вы запускаете Docker, как это:
docker run -i -t ubuntu bash
точка входа по умолчанию/bin/sh -c
, изображениеubuntu
и командаbash
.Команда запускается через точку входа. то есть, реальная вещь , которая запускается на выполнение является
/bin/sh -c bash
. Это позволило DockerRUN
быстро реализовать , полагаясь на парсер оболочки.Позже люди попросили уметь настроить это, чтобы
ENTRYPOINT
и--entrypoint
были представлены.Все, что после
ubuntu
в приведенном выше примере, является командой и передается точке входа. При использованииCMD
инструкции это так же, как если бы вы делалиdocker run -i -t ubuntu <cmd>
.<cmd>
будет параметром точки входа.Вы также получите тот же результат, если вместо этого наберете эту команду
docker run -i -t ubuntu
. Вы по-прежнему запускаете оболочку bash в контейнере из-за файле Docker для Ubuntu указан CMD по умолчанию:CMD ["bash"]
Поскольку все передается точке входа, вы можете очень хорошо вести себя со своими изображениями. @Jiri пример хорош, он показывает, как использовать изображение в качестве «двоичного». При использовании в
["/bin/cat"]
качестве точки входа и последующем выполненииdocker run img /etc/passwd
вы получаете ее, она/etc/passwd
является командой и передается точке входа, поэтому выполнение конечного результата выполняется просто/bin/cat /etc/passwd
.Другим примером может быть любой cli в качестве точки входа. Например, если у вас есть REDIS изображение, а не работает
docker run redisimg redis -H something -u toto get key
, вы можете простоENTRYPOINT ["redis", "-H", "something", "-u", "toto"]
и затем запустить как это для того же результата:docker run redisimg get key
.источник
ENTRYPOINT
; используется ли оболочка, зависит от используемой формыCMD
команды ( docs.docker.com/engine/reference/builder/#cmd ).CMD
противENTRYPOINT
.ENTRYPOINT
Задает команду , которая всегда будет выполняться при запуске контейнера.В
CMD
Задает аргументы , которые будут подаваться вENTRYPOINT
.Если вы хотите сделать изображение, посвященное определенной команде, вы будете использовать
ENTRYPOINT ["/path/dedicated_command"]
В противном случае, если вы хотите создать изображение общего назначения, вы можете оставить его без
ENTRYPOINT
указания и использовать,CMD ["/path/dedicated_command"]
поскольку вы сможете переопределить настройку, предоставив аргументы дляdocker run
.Например, если ваш Dockerfile:
Запуск изображения без каких-либо аргументов пингует локальный хост:
Теперь, запуск изображения с аргументом будет проверять аргумент:
Для сравнения, если ваш Dockerfile:
Запуск изображения без каких-либо аргументов пингует локальный хост:
Но запуск изображения с аргументом запустит аргумент:
См. Эту статью от Брайана ДеХамера для более подробной информации: https://www.ctl.io/developers/blog/post/dockerfile-entrypoint-vs-cmd/
источник
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.
хорошее краткое изложение.Согласно докерской документации ,
В таблицах ниже показано, какая команда выполняется для различных
ENTRYPOINT
/CMD
комбинаций :-
No ENTRYPOINT
-
ENTRYPOINT exec_entry p1_entry
-
ENTRYPOINT [“exec_entry”, “p1_entry”]
источник
/bin/sh -c
участвует?/bin/sh -c
он будет добавлен в CMD в качестве префикса, а CMD записан в исполняемом синтаксисе (не в синтаксисе списка).ENTRYPOINT exec_entry p1_ent
был неправильно объяснен. Форма оболочки не позволяет использовать любые аргументы командной строки CMD или запуска - docs.docker.com/engine/reference/builder/#entrypointДа, это хороший вопрос. Я еще не совсем понимаю, но:
Я понимаю,
ENTRYPOINT
что это исполняемый файл. Вы можете переопределить точку входа путем --entrypoint = "".CMD является аргументом по умолчанию для контейнера. Без точки входа аргумент по умолчанию - это команда, которая выполняется. С точкой входа cmd передается точке входа в качестве аргумента. Вы можете эмулировать команду с точкой входа.
Итак, главное преимущество в том, что с точкой входа вы можете передавать аргументы (cmd) в ваш контейнер. Для этого вам нужно использовать оба:
а также
тогда вы можете использовать:
источник
docker run image_name -h
чтобы показать некоторую справочную информацию об этом изображении.Разница между CMD и ENTRYPOINT по интуиции :
Да, это смешивается.
Вы можете переопределить любой из них при запуске Docker Run.
Разница между CMD и ENTRYPOINT по примеру :
Подробнее о разнице между
CMD
иENTRYPOINT
:Аргумент,
docker run
такой как / bin / bash, переопределяет любую команду CMD, которую мы написали в Dockerfile.ENTRYPOINT нельзя переопределить во время выполнения с помощью обычных команд, таких как
docker run [args]
. Вargs
концеdocker run [args]
указываются аргументы ENTRYPOINT. Таким образом, мы можем создать acontainer
как обычный двоичный файл, такой какls
.Таким образом, CMD может выступать в качестве параметров по умолчанию для ENTRYPOINT, а затем мы можем переопределить аргументы CMD из [args].
ENTRYPOINT можно переопределить с помощью
--entrypoint
.источник
В двух словах:
Если вам нужно больше деталей или вы хотите увидеть разницу на примере, есть блог, в котором подробно сравниваются CMD и ENTRYPOINT с множеством примеров - http://goinbigdata.com/docker-run-vs-cmd-vs-entrypoint/
источник
Я добавлю свой ответ в качестве примера 1 который поможет вам лучше понять разницу.
Предположим, мы хотим создать образ, который всегда будет запускать команду сна при запуске. Мы создадим наш собственный образ и укажем новую команду:
Теперь мы строим изображение:
Что если мы хотим изменить количество секунд? Нам пришлось бы изменить значение,
Dockerfile
поскольку значение там жестко задано, или переопределить команду, указав другую:Хотя это работает, это не очень хорошее решение, так как у нас есть избыточная команда «сна» (цель контейнера состоит в том, чтобы спать , поэтому необходимо явно указать
sleep
команду не рекомендуется).Теперь давайте попробуем использовать
ENTRYPOINT
инструкцию:Эта инструкция указывает программу, которая будет запускаться при запуске контейнера .
Теперь мы можем запустить:
Как насчет значения по умолчанию? Ну, вы правильно догадались
Это
ENTRYPOINT
программа, которая будет запущена, и значение, переданное контейнеру, будет добавлено к нему.ENTRYPOINT
Может быть переопределены, указав--entrypoint
флаг, а затем новой точкой входа вы хотите использовать.Не мое, я когда-то смотрел учебник, который предоставил этот пример
источник
Принятый ответ невероятен в объяснении истории. Я нахожу, что эта таблица очень хорошо объясняет это из официального документа о том, «как взаимодействуют CMD и ENTRYPOINT» :
источник
Комментарии к функции EntryPoint в коде
Еще одна ссылка из документов
Пример:
Сборка : сборка sudo docker -t ent_cmd.
,
ps: при наличии EntryPoint CMD будет содержать аргументы для подачи в EntryPoint. В отсутствие EntryPoint CMD будет командой, которая будет выполняться.
источник
CMD
Команда, упомянутая внутриDockerfile
файла, может быть переопределена с помощьюdocker run
команды, ноENTRYPOINT
не может быть.источник
docker run --help
Команда говорит иначе:--entrypoint string Overwrite the default ENTRYPOINT of the image
Я прочитал все ответы и хочу подвести итог для лучшего понимания на первый взгляд, например:
Во-первых, вся команда, выполняемая в контейнере, состоит из двух частей: команды и аргументов.
В книге Kubernetes In Action отмечается важная заметка об этом. (глава 7)
Вы также можете прочитать эту статью для лучшего объяснения в простой форме
источник
CMD:
CMD ["executable","param1","param2"]
:["executable","param1","param2"]
это первый процесс.CMD command param1 param2
:/bin/sh -c CMD command param1 param2
это первый процесс.CMD command param1 param2
разветвляется с первого процесса.CMD ["param1","param2"]
: Эта форма используется для предоставления аргументов по умолчанию дляENTRYPOINT
.ENTRYPOINT (В следующем списке не рассматривается случай, когда CMD и ENTRYPOINT используются вместе):
ENTRYPOINT ["executable", "param1", "param2"]
:["executable", "param1", "param2"]
это первый процесс.ENTRYPOINT command param1 param2
:/bin/sh -c command param1 param2
это первый процесс.command param1 param2
разветвляется с первого процесса.Как сказал Крек , CMD был разработан первым. Затем была разработана ENTRYPOINT для дополнительной настройки. Поскольку они не предназначены для совместной работы, между CMD и ENTRYPOINT существуют некоторые функциональные совпадения, которые часто путают людей.
источник
Большинство людей прекрасно объясняют это здесь, поэтому я не буду повторять все ответы. Но чтобы получить хорошее чувство, я бы предложил проверить его самостоятельно, посмотрев на процессы в контейнере.
Создайте крошечный Dockerfile формы:
Постройте его, запустите его
docker run -it theimage
и запуститеps -eo ppid,pid,args
в контейнере. Сравните этот вывод с выводом, который вы получаете от ps при использовании:docker run -it theimage bash
ENTRYPOINT /bin/bash
и запустить его в обоих направленияхCMD ["/bin/bash"]
Таким образом, вы легко увидите различия между всеми возможными для себя методами.
источник
Официальная документация лучших практик Dockerfile объясняет различия. Лучшие практики Dockerfile
CMD:
Инструкция CMD должна использоваться для запуска программного обеспечения, содержащегося в вашем образе, вместе с любыми аргументами. CMD почти всегда следует использовать в форме
CMD ["executable", "param1", "param2"…]
. Таким образом, если изображение предназначено для службы, такой как Apache и Rails, вы должны выполнить что-то вродеCMD ["apache2","-DFOREGROUND"]
. Действительно, эта форма инструкции рекомендуется для любого сервисного изображения.ТОЧКА ВХОДА:
Лучшее использование для ENTRYPOINT - установить основную команду изображения, позволяя запускать этот образ, как если бы это была эта команда (а затем использовать CMD в качестве флагов по умолчанию).
источник