Как в Dockerfile CMD exe c form найти бинарный файл - PullRequest
0 голосов
/ 28 марта 2020

Если у меня есть Dockerfile, подобный этому:

FROM ubuntu 
CMD [ "ps", "-ef" ]

И если я создаю и запускаю образ, я получаю

$ docker run -it 156a9f959f43
UID        PID  PPID  C STIME TTY          TIME CMD
root         1     0  0 07:12 pts/0    00:00:00 ps -ef

, что соответствует документации.

Вопрос: Как бинарный файл ps оказывается в первую очередь при запуске контейнера?

Ответы [ 2 ]

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

Синтаксис exe c использует переменную окружения PATH, определенную в родительском образе (ubuntu:latest).

$ docker image inspect ubuntu:latest
[
    {
...
        "Config": {
...
            "Env": [
                "PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"
            ],
            "Cmd": [
                "/bin/bash"
            ],
....

Если вы go просматриваете файл Docker-файла base image ... вы действительно увидите, что переменная PATH там не определена. Мы могли бы go смотреть на scratch, но это виртуальный образ.

Итак, давайте создадим образ на scratch, не видя, какие переменные определены:

$ cat df.scratch 
FROM scratch

$ docker build -t test-scratch -f df.scratch .
...

$ docker image inspect test-scratch:latest
[
    {
...
        "Config": {
...
            "Env": [
                "PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"
            ],
...

Таким образом, PATH создается в образе scratch. Эта старая проблема и связанный PR показывают, что docker включает в себя PATH из коробки.

Как вы можете настроить этот путь? Вам нужно использовать строку ENV. Если вы установите переменную в строке RUN, она не будет сохранена после завершения этой строки RUN. И если вы добавляете к .bashrc в контейнере, это не относится к не bash оболочкам, таким как /bin/sh, к чему-либо, использующему синтаксис exe c без оболочки, и к любым неинтерактивным оболочкам bash (так как .bashrc останавливает обработку частично для неинтерактивных оболочек). Вот пример этого с другим изображением / сборкой:

$ cat df.path 
FROM ubuntu

# before state from the base image
RUN [ "env" ]

# attempting to modify the .bashrc
RUN echo "export PATH="$PATH:/my/custom/bin/dir"" >> ~/.bashrc 
RUN [ "env" ]

# modifying the image environment variable directly
ENV PATH=${PATH}:/opt/custom/bin
RUN [ "env" ]

$ docker build -t test-path -f df.path .
Sending build context to Docker daemon  31.23kB
Step 1/6 : FROM ubuntu
 ---> 4e5021d210f6
Step 2/6 : RUN [ "env" ]
 ---> Running in 5bb72abb386d
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
HOSTNAME=5bb72abb386d
HOME=/root
Removing intermediate container 5bb72abb386d
 ---> c438fb269c70
Step 3/6 : RUN echo "export PATH="$PATH:/my/custom/bin/dir"" >> ~/.bashrc
 ---> Running in 127b10aff046
Removing intermediate container 127b10aff046
 ---> 4af50595c271
Step 4/6 : RUN [ "env" ]
 ---> Running in c5ff46ba3b82
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
HOSTNAME=c5ff46ba3b82
HOME=/root
Removing intermediate container c5ff46ba3b82
 ---> 455325a5e484
Step 5/6 : ENV PATH=${PATH}:/opt/custom/bin
 ---> Running in e7960d9ce18a
Removing intermediate container e7960d9ce18a
 ---> ed532bff78b4
Step 6/6 : RUN [ "env" ]
 ---> Running in 9c1558a61ab7
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/opt/custom/bin
HOSTNAME=9c1558a61ab7
HOME=/root
Removing intermediate container 9c1558a61ab7
 ---> f08993f21b97
Successfully built f08993f21b97
Successfully tagged test-path:latest

Обратите внимание на исходное значение пути на шаге 2, оно не изменяется на шаге 4 и имеет определенное значение на шаге 6.

0 голосов
/ 28 марта 2020

В docker контейнерах (аналогично большинству операционных систем) существует переменная окружения $PATH, которая содержит пути к каталогам, в которых расположены исполняемые файлы (разделенные :).

Например, переменная $PATH может содержать значение наподобие /usr/local/bin:/usr/bin:/home/ubuntu/bin, что будет означать, что при выполнении команды наподобие ps она будет искать исполняемый файл в этих каталогах.

Вы можете узнать больше о Переменная $ PATH здесь https://en.wikipedia.org/wiki/PATH_ (переменная)

Примечание: переменная $PATH будет отличаться от контейнера к контейнеру (поскольку они являются изолированными единицами) и, скорее всего, будет содержать значение по умолчанию для базового дистрибутива, используемого изображением docker.

Чтобы внести изменения в переменную $ PATH в системах на основе linux, вы можете запустить export PATH="$PATH:/custom/bin/dir", и она добавит /custom/bin/dir к переменной. Чтобы сделать это изменение постоянным, вы должны добавить эту команду в ваш .bashr c, .profile, .zshr c или подобный файл (в зависимости от того, какую оболочку вы используете)

Итак, чтобы обновить переменную в ваших docker контейнерах вы должны добавить что-то подобное в ваш Docker файл

FROM ubuntu 
RUN echo "export PATH="$PATH:/my/custom/bin/dir"" >> ~/.bashrc 
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...