Docker CMD - когда следует использовать форму оболочки? - PullRequest
1 голос
/ 04 марта 2020

Dockerfile - лучшие практики говорит, что

CMD почти всегда следует использовать в форме CMD ["исполняемый файл", "param1", "param2"…]

в каком случае следует использовать форму оболочки?

Ответы [ 3 ]

1 голос
/ 04 марта 2020

Для CMD форма оболочки требуется только в том случае, если вам нужна функциональность, которая предоставляется только в оболочке - если ваша CMD включает ссылки на переменные среды $ARG, несколько команд a && b, конвейеры | tee ... или перенаправления 2>&1. Если у вас есть особенно сложный CMD, подобный этому, может быть лучше переместить его в сценарий оболочки (который вы можете независимо протестировать за пределами Docker), и у вас есть значение по умолчанию CMD просто для вызова сценария.

RUN технически имеет те же соображения. Однако очень часто можно запускать несколько команд в одной и той же инструкции RUN, а для этого требуется форма оболочки. Почти каждая строка RUN, которую я когда-либо видел, использует форму оболочки.

ENTRYPOINT должна всегда быть формой JSON. Помните, что точка входа получает команду в качестве аргументов; если вы используете форму оболочки, это фактически приводит к игнорированию этих аргументов. Опять же, если вам нужно сделать сложные вещи в ENTRYPOINT (включая exec "$@" для запуска команды), разделите его на отдельный сценарий оболочки и вызовите его, используя синтаксис JSON -array.

1 голос
/ 04 марта 2020

Форма оболочки вызовет командную оболочку и выполнит обычную обработку команд, которую обычно обрабатывает оболочка (например, подстановка переменных среды, таких как $HOME). Форма exe c не делает этого.

Это тесно связано с директивой SHELL.

В Dockerfile может быть несколько команд SHELL, но только одна CMD. CMD используется для указания того, что контейнер должен запускаться при запуске. Директива SHELL перезапишет оболочку по умолчанию, которая используется в форме оболочки различных команд (RUN, CMD, ENTRYPOINT).

Использование этого Dockerfile иллюстрирует это лучше, чем я мог бы объяснить:

FROM python:3.6
RUN echo $PATH
SHELL ["/bin/bash" ,"-c"]
RUN echo $PATH
RUN ["echo", "$PATH"]
COPY run.sh /run.sh

ENTRYPOINT ["/run.sh"]

Приведет к этому при запуске docker build:

$ docker build .

Sending build context to Docker daemon   5.12kB
Step 1/7 : FROM python:3.6
 ---> 5bf410ee7bb2
Step 2/7 : RUN echo $PATH
 ---> Running in 3a08d7c4450c
/usr/local/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
Removing intermediate container 3a08d7c4450c
 ---> 85b4da5d8e5d
Step 3/7 : SHELL ["/bin/bash" ,"-c"]
 ---> Running in da1b90ac14f2
Removing intermediate container da1b90ac14f2
 ---> ed747f0862a6
Step 4/7 : RUN echo $PATH
 ---> Running in 5c6a86e133ff
/usr/local/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
Removing intermediate container 5c6a86e133ff
 ---> 8ec42f23d390
Step 5/7 : RUN ["echo", "$PATH"]
 ---> Running in cc0650a6d8e8
$PATH
Removing intermediate container cc0650a6d8e8
 ---> 8b11432adb3a
Step 6/7 : COPY run.sh /run.sh
 ---> a168c58738e7
Step 7/7 : ENTRYPOINT ["/run.sh"]
 ---> Running in f9e28048d139
Removing intermediate container f9e28048d139
 ---> d20920ea562c
Successfully built d20920ea562c

Обратите внимание, что когда он запускал команды режима оболочки (используя оболочку по умолчанию и bash), $ PATH был расширен, но не при запуске в режиме exe c.

1 голос
/ 04 марта 2020

Почти никогда; если вам нужна команда оболочки, вы можете просто вызвать скрипт в формате скобок (CMD ["bash", "myscript.sh"]). Проблема с оболочкой заключается в том, что она прерывает работу: https://hynek.me/articles/docker-signals/

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...