Гибкость и надёжность Docker как инструмента контейнеризации сопровождаются сложностью, которая может пугать. Для выполнения схожих задач доступно несколько методов, и пользователи должны понимать плюсы и минусы доступных вариантов, чтобы выбрать лучший подход для своих проектов.
Одна из запутанных областей касается инструкций RUN
, CMD
и ENTRYPOINT
Dockerfile. В этой статье мы обсудим различия между этими инструкциями и опишем варианты использования для каждой.
Что такое Dockerfile?
По сути, Dockerfiles — это простые текстовые файлы с инструкциями по созданию образов Docker. Контейнеры, созданные с помощью Dockerfile, могут работать на любом сервере Linux.
Бизнес-приложения могут быть более гибкими и переносимыми с помощью Dockerfile. Приложения и их зависимости упаковываются с помощью Dockerfile и запускаются в виртуальных контейнерах как локально, так и в общедоступных облаках.
RUN — Инструкция Dockerfile для выполнения команд, которые создают и настраивают образ Docker. Эти команды выполняются в процессе создания образа, и каждая инструкция RUN
создаёт новый слой в образе Docker.
Например, если вы создаёте образ, для которого требуется установить определённое программное обеспечение или библиотеки, вы используете RUN
для выполнения необходимых команд установки.
CMD — CMD описывает параметры или команды контейнера по умолчанию. При использовании этого параметра пользователь может легко переопределить команду по умолчанию.
ENTRYPOINT — контейнер с ENTRYPOINT предпочтительнее, если вы хотите определить исполняемый файл. Вы можете переопределить его, только если используете флаг --entrypoint
.
Что такое CMD и ENTRYPOINT?
Прежде чем перейти к различиям и практическим примерам, давайте попробуем понять, что это такое и зачем они нам нужны. Оба параметра используются для указания программ/команд, которые будут выполняться при инициализации контейнера из образа Docker.
CMD
: устанавливает параметры по умолчанию, которые можно изменить с помощью интерфейса командной строки Docker (CLI) при запуске контейнера Docker.
ENTRYPOINT
: параметры по умолчанию, которые нельзя изменить при выполнении контейнеров Docker с параметрами командной строки.
Использование CMD
# Base Image
FROM ubuntu:20.04
# Required installations
RUN apt-get update && apt-get -y install iputils-ping
CMD ["ping", "www.google.com"]
Теперь мы создадим образ с помощью Dockerfile и запустим его с помощью следующих команд (pinger — это имя образа, который мы создаём):
docker build -t pinger .
docker run -d pinger
И нам успешно удалось запустить контейнер, который постоянно отправляет запросы на сайт www.google.com.
Использование ENTRYPOINT
Мы повторяем процесс, только на этот раз заменяем CMD на ENTRYPOINT в нашем Dockerfile:
# Base Image
FROM ubuntu:20.04
# Required installations
RUN apt-get update && apt-get -y install iputils-ping
ENTRYPOINT ["ping", "www.google.com"]
Мы снова собираем и запускаем Dockerfile, используя те же команды, что и раньше, и замечаем, что до сих пор не было никакой разницы между двумя запусками.
Различия между CMD и ENTRYPOINT
Как мы уже говорили выше, они используются для указания программ, которые запускаются при старте контейнера, но основные различия между ними заключаются в следующем: команды CMD игнорируются демоном, если в команде docker run
указаны параметры, в то время как инструкции ENTRYPOINT не игнорируются, а добавляются в качестве параметров командной строки, рассматриваясь как аргументы команды.
Теперь давайте рассмотрим подробнее. Мы будем использовать обе формы команд, чтобы пройти различные этапы запуска контейнера Docker.
Вот краткое описание различий между CMD
и ENTRYPOINT
в виде таблицы:
Команда | CMD | ENTRYPOINT |
Укажите команды по умолчанию, которые будут выполняться при запуске образа Docker как контейнера | ДА | ДА |
Аргументы могут быть переопределены пользователем | ДА | НЕТ |
Использование CMD
Прежде чем мы углубимся в то, в чём заключается разница между этими двумя командами, стоит обратить внимание на docker run
команду. Синтаксис выглядит следующим образом: docker run <optional flags> <image name> <command>
. -d
— это необязательный флаг, который мы используем, pinger
— это имя нашего образа, и всё, что мы можем добавить после имени образа, станет частью нашей команды, которая передаётся в CMD
/ENTRYPOINT
.
Теперь мы создадим и запустим оба наших Dockerfile, только на этот раз мы передадим дополнительные аргументы в docker run
команду.
Сначала мы создаём файл Dockerfile, содержащий команду CMD, и запускаем его с помощью следующей команды:
docker run -d pinger ping www.youtube.com
Мы видим, что наша программа теперь пингует www.youtube.com вместо www.google.com. Дополнительные аргументы, которые мы передаем команде docker run
, заменяют существующие аргументы, определенные в Dockerfile, и выполняется следующее:
ping www.youtube.com
docker run -d pinger python3 sample.py
И сработает python3 sample.py если в нашем контейнере установлен python3, а в каталоге есть файл sample.py.
Использование ENTRYPOINT
Далее мы запускаем Dockerfile, содержащий команду ENTRYPOINT, с помощью следующей команды:
docker run -d pinger ping www.youtube.com
Однако в этом случае программа отправляет запрос на www.google.com и сразу же завершает работу. Дополнительные аргументы к docker run
команде добавляются к существующим аргументам, определенным в Dockerfile, поэтому мы пытаемся выполнить следующее:
ping www.google.com ping www.youtube.com
Поскольку эта команда содержит синтаксическую ошибку, вся команда не выполняется, и наша программа завершает работу. Чтобы исправить это, мы можем изменить команду запуска Docker, добавив &&
в начало дополнительных аргументов:
docker run -d pinger && ping www.youtube.com
Итак, мы выполняем следующую команду:
ping www.google.com && ping www.youtube.com
И мы видим, что наша программа теперь пингует и www.google.com,и www.youtube.com.
Объединение CMD и ENTRYPOINT
Мы можем объединить CMD и ENTRYPOINT, если хотим зафиксировать некоторые параметры команд, которые мы хотим запустить, а другие оставить переменными. В приведенном выше примере мы можем захотеть, чтобы контейнер всегда проверял наличие связи с веб-сайтом, но веб-сайт, с которым проверяется связь, остается переменной.
Мы могли бы сделать это, объединив ENTRYPOINT и CMD в Dockerfile:
# Base Image
FROM ubuntu:20.04
# Required installations
RUN apt-get update && apt-get -y install iputils-ping
ENTRYPOINT ["ping"]
CMD ["www.google.come"]
Теперь мы сначала создадим наш образ и запустим его без дополнительных аргументов:
docker build -t pinger
docker run -d pinger
И наш контейнер запускает следующую команду:
ping www.google.com
Если мы изменим команду docker run
, чтобы запустить следующее:
docker run -d pinger www.youtube.com
Вместо этого наш контейнер теперь запускает следующую команду:
ping www.youtube.com
Мы видим, что ping
осталось неизменным, в то время как www.google.com
было заменено на www.youtube.com
. Таким образом, мы можем комбинировать ENTRYPOINT и CMD, чтобы использовать отдельные свойства, предоставляемые обеими командами.
Описание команды и примеры использования
Команда | Описание | Пример использования |
CMD | Определяет исполняемый файл по умолчанию для образа Docker. Его можно переопределить с помощью docker run аргументов. | Утилитные образы позволяют пользователям передавать различные исполняемые файлы и аргументы в командной строке. |
ENTRYPOINT | Определяет исполняемый файл по умолчанию. Его можно переопределить с помощью “--entrypoint” docker run аргументов. | Образы, созданные для определённой цели, когда не требуется заменять исполняемый файл по умолчанию. |
RUN | Выполняет команды для построения слоев. | Создание образа |
Основные отличия
1. Переопределение команды: CMD может быть полностью переопределена при запуске контейнера, в то время как ENTRYPOINT предопределяет базовую команду, и любые аргументы, указанные при запуске, добавляются к этой команде.
2. Использование в комбинации: Часто ENTRYPOINT используется в комбинации с CMD, где ENTRYPOINT задает исполняемый файл, а CMD задает аргументы по умолчанию, которые могут быть переопределены при запуске.
CMD и ENTRYPOINT обе определяют, какая команда будет выполнена при запуске Docker-контейнера, но делают это по-разному. CMD лучше использовать для задания параметров по умолчанию, которые могут быть изменены, а ENTRYPOINT для установки фиксированной базовой команды, к которой можно добавлять аргументы.
Ссылки