В Dockerfiles есть две команды, которые кажутся мне похожими: CMD
и ENTRYPOINT
. Но я предполагаю, что между ними есть (тонкая?) разница - иначе не было бы никакого смысла иметь две команды для одного и того же.
В документации говорится, что для CMD
Основное назначение CMD заключается в предоставлении настроек по умолчанию для выполняющегося контейнера.
и для ENTRYPOINT
:
ENTRYPOINT помогает вам настроить контейнер, который вы можете запустить как исполняемый файл.
Итак, в чем же разница между этими двумя командами?
У Docker есть точка входа по умолчанию, которой является /bin/sh -c
, но нет команды по умолчанию.
Когда вы запускаете docker следующим образом:
docker run -i -t ubuntu bash
.
то точка входа по умолчанию /bin/sh -c
, образ - ubuntu
, а команда - bash
.
Команда выполняется через точку входа, т.е. фактически выполняется /bin/sh -c bash
. Это позволило Docker быстро реализовать RUN
, полагаясь на парсер оболочки.
Позже люди попросили дать им возможность настраивать это, поэтому были введены ENTRYPOINT
и --entrypoint
.
Все, что идет после ubuntu
в приведенном примере, является командой и передается в точку входа. При использовании инструкции CMD
все происходит точно так же, как если бы вы выполняли команду docker run -i -t ubuntu <cmd>
. <cmd>
будет параметром точки входа.
Вы получите тот же результат, если вместо этого введете команду docker run -i -t ubuntu
. Вы все равно запустите оболочку bash в контейнере, потому что в ubuntu Dockerfile указан 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
указываются аргументы, которые будут передаваться в ENTRYPOINT
.
Если вы хотите сделать образ, предназначенный для определенной команды, используйте ENTRYPOINT ["/path/dedicated_command"]
.
В противном случае, если вы хотите сделать образ для общего назначения, вы можете оставить ENTRYPOINT
неуказанным и использовать CMD ["/path/dedicated_command"]
, поскольку вы сможете отменить эту настройку, предоставив аргументы в docker run
.
Например, если ваш Dockerfile имеет вид:
FROM debian:wheezy
ENTRYPOINT ["/bin/ping"]
CMD ["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
Теперь, запустив образ с аргументом, вы будете пинговать аргумент:
$ 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
Для сравнения, если ваш Dockerfile имеет вид:
FROM debian:wheezy
CMD ["/bin/ping", "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
Но запуск образа с аргументом приведет к запуску аргумента:
docker run -it test bash
root@e8bb7249b843:/#
Более подробную информацию можно найти в этой статье Брайана ДеХамера: https://www.ctl.io/developers/blog/post/dockerfile-entrypoint-vs-cmd/
По данным докер документы,
и CMD и указания точки входа определить, какая команда запускается на выполнение при запуске контейнера. Есть несколько правил, которые описывают их сотрудничество.
- Файла Docker должны указать по крайней мере один из
УМК
илиточки входа
команды.- `Точка входа должна быть определена при использовании контейнера в качестве исполняемого.
- Команду " cmd " должно быть использовано как способ определения аргументов по умолчанию для команды
точки входа
или для выполнения специальной команды контейнер.- Команду " cmd " будет преодолено, когда запущен контейнер с альтернативными аргументами.
В таблицах ниже показывает какая команда выполняется для комбинаций различных точки входа
/ УМК
:
-- Нет точки входа
╔════════════════════════════╦═════════════════════════════╗
║ 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 ║
╚════════════════════════════╩═════════════════════════════╝
-- Точки входа p1_entry exec_entry
╔════════════════════════════╦══════════════════════════════════╗
║ No CMD ║ /bin/sh -c exec_entry p1_entry ║
╟────────────────────────────╫──────────────────────────────────╢
║ CMD [“exec_cmd”, “p1_cmd”] ║ /bin/sh -c exec_entry p1_entry ║
╟────────────────────────────╫──────────────────────────────────╢
║ CMD [“p1_cmd”, “p2_cmd”] ║ /bin/sh -c exec_entry p1_entry ║
╟────────────────────────────╫──────────────────────────────────╢
║ CMD exec_cmd p1_cmd ║ /bin/sh -c exec_entry p1_entry ║
╚════════════════════════════╩══════════════════════════════════╝
-- Точки входа [“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 ║
╚════════════════════════════╩═════════════════════════════════════════════════╝
Да, это хороший вопрос. Я еще не до конца его понимаю, но..:
Я понимаю, что ENTRYPOINT
- это бинарный файл, который выполняется. Вы можете изменить точку входа с помощью --entrypoint="".
docker run -t -i --entrypoint="/bin/bash" ubuntu
CMD - это аргумент по умолчанию для контейнера. Без точки входа аргументом по умолчанию является команда, которая выполняется. С точкой входа cmd передается в точку входа в качестве аргумента. Вы можете эмулировать команду с помощью точки входа.
# no entrypoint
docker run ubuntu /bin/cat /etc/passwd
# with entry point, emulating cat command
docker run --entrypoint="/bin/cat" ubuntu /etc/passwd
Итак, основное преимущество заключается в том, что с помощью entrypoint вы можете передавать аргументы (cmd) вашему контейнеру. Чтобы добиться этого, вам нужно использовать оба варианта:
# Dockerfile
FROM ubuntu
ENTRYPOINT ["/bin/cat"]
и
docker build -t=cat .
тогда вы можете использовать:
docker run cat /etc/passwd
# ^^^^^^^^^^^
# CMD
# ^^^
# image (tag)- using the default ENTRYPOINT
Разница между cmd и точки входа интуиция:
Да, это'ы помешивая.
Вы можете переопределить любой из них при запуске докер запустить.
Разница между cmd и точки входа пример:
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
Подробнее о разнице между cmd
и точки входа
:
Аргумент докер запустить
таких как /bin/Баш перекрывает любые команды CMD мы писали в файла Docker.
Точка входа не могут быть переопределены во время выполнения обычных команд, таких как докер запустить [аргументы]
. Эти аргументы
в конце докер запустить [аргументы]
приводятся в качестве аргументов точки входа. Таким образом, мы можем создать "контейнер", который является как обычный двоичный, такие как ЛС
.
Так что cmd может выступать в качестве параметров по умолчанию для ENTRYPOINT и тогда мы можем переопределить аргументы cmd из [аргументы].
Точка входа может быть overriden с--точка входа`.
В двух словах:
Если вам нужно больше информации или хотели бы увидеть разницу на примере, есть в блоге, которые всесторонне сравнить cmd и точки входа с большим количеством примеров - http://goinbigdata.com/docker-run-vs-cmd-vs-entrypoint/
Принято отвечать-это сказочные в объяснении истории. Я нахожу эту таблицу очень хорошо объяснить с Официальный док О 'как cmd и точки входа взаимодействовать':
Я'будете добавлять мой ответ в качестве примера<суп>1</суп> это может помочь вам лучше понять разницу.
Позвольте'ы предположим, мы хотим создать образ, который будет всегда выполнить команду спать, когда она начинается. Мы'Лл создать наш собственный образ и указать новую команду:
Баш От Ubuntu УМК спать 10
Теперь, мы строим образ:
docker build -t custom_sleep .
docker run custom_sleep
# sleeps for 10 seconds and exits
Что, если мы хотим изменить количество секунд? Мы должны изменить файла Docker
в качестве значения жестко там, или переопределить команду путем предоставления другой:
docker run custom_sleep sleep 20
Хотя это работает, это's не хорошее решение, так как у нас есть избыточные "Спи" и команда (контейнер'с целью сон, поэтому для явного указания сон
команда не является хорошей практикой).
Теперь давайте'ы попробуйте использовать точки входа
инструкция:
Баш От Ubuntu Точки входа спать
Этот инструкция определяет программу, которая будет выполняться при старте контейнера.
Теперь мы можем работать:
Баш докер запустить custom_sleep 20
Насчет значений по умолчанию? Ну, вы догадались правильно:
Баш От Ubuntu Точка входа ["Спи" и] УМК ["и 10" и]
В точки входа
- это программа, которая будет выполняться, и значение, переданное в контейнер будет добавлен к нему.
В точки входа
может быть переопределено путем указания `--точка входа флаг, а затем на новой точке входа, которую вы хотите использовать.
<суп>не мое, я как-то смотрел учебник, который предоставил этот пример в</SUP и ГТ;
Комментарии о функция ENTRYPOINT в код
// точка входа в /usr на/sbin/nginx в.
// установить точки входа (по умолчанию Ш-с) в /usr на/sbin/nginx в.
// принимаем cmd в качестве аргументов в каталог /usr на/sbin/nginx в.
Еще одна ссылка из Документы
вы можете использовать exec в виде точки входа в комплекс довольно стабильной команды по умолчанию и аргументы, а затем использовать cmd, чтобы установить дополнительные значения по умолчанию, скорее всего, будут изменены.
Пример:
FROM ubuntu:14.04.3
ENTRYPOINT ["/bin/ping"]
CMD ["localhost", "-c", "2"]
Построить: судо докер построить -Т 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
С. с: При наличии точки входа, УМК проведет аргументов для ФРС с точки входа. В отсутствие точки входа, УМК будет команда, которая будет работать.
УМК:
УМК ["и исполняемый на", то"параметр1-то", то"параметр2-то"]
: [: "с исполняемого файла и", то"параметр1-то", то"параметр2-то"]
- это первый процесс.Команды CMD параметр1 параметр2
: /Бен/Ш-с в cmd команда параметр1 параметр2
- это первый процесс. Команды CMD параметр1 параметр2
ответвляется от первого процесса.УМК [на"параметр1-то", то"параметр2-то"]
: Эта форма используется для предоставления аргументов по умолчанию для точки входа
.Точка входа (в следующем списке не Рассмотрим случай, когда cmd и точки входа используются вместе):
Точка входа не исполняемый и", то "параметр1-то", то "параметр2-то"]
: [: "с исполняемого файла и", то "параметр1-то", то "параметр2-то"]
- это первый процесс.:
/Бен/ш-c команда параметр1 параметр2- это первый процесс. команда параметр1 параметр2
ответвляется от первого процесса.Как скрипят](https://stackoverflow.com/users/884978/creack) сказал, УМК разработан в первую очередь. Тогда точка входа был разработан для более детальной настройки. Поскольку они не рассчитаны вместе, есть некоторые функции пересекается между cmd и точки входа, которые часто путают люди.
Большинство людей прекрасно объяснит здесь, так что я выиграл'т повторить все ответы. Но чтобы получить хорошее чувство, я бы предложил тестирование самостоятельно, глядя на процессы в контейнер.
Создать крошечные файла Docker формы:
FROM ubuntu:latest
CMD /bin/bash
Построить его, запустите его в докер Run-это образ
и бежать `ПС-эо идентификатор,идентификатор процесса,аргументы в контейнер.
Сравните это выход для вывода, который вы получите от ПС при использовании:
докер Run-это образ Баш
Таким образом, вы будете легко видеть различия между всеми возможными методами для себя.