Почему docker в контейнерах docker (dind) монтирует тома с путем к хосту?
У меня есть настройки с Docker в Docker и попробуйте смонтировать папки.
Допустим, у меня есть те папки, которыми я хочу поделиться со своим родителем. На хосте я создал файл в /tmp/dind с именем foo
, Хост запускает контейнер 1, который запускает контейнер 2. Это результат, который я хочу получить.
Host | Container 1 | Container 2
/tmp/dind | /tmp/dind2 | /tmp/dind3
<-------> <------->
Вместо этого я получаю
Host | Container 1 | Container 2
/tmp/dind | /tmp/dind2 | /tmp/dind3
<------->
<----------------------->
Код здесь:
docker run --rm -it \
-v /tmp/dind:/tmp/dind2 \
-v /var/run/docker.sock:/var/run/docker.sock docker sh -c \
"docker run --rm -it \
-v /tmp/dind2:/tmp/dind3 \
-v /var/run/docker.sock:/var/run/docker.sock \
docker ls /tmp/dind3"
Это ничего не выводит, а следующая команда выдает foo как результат. Я изменил установленный объем:
docker run --rm -it \
-v /tmp/dind:/tmp/dind2 \
-v /var/run/docker.sock:/var/run/docker.sock docker sh -c \
"docker run --rm -it \
-v /tmp/dind:/tmp/dind3 \
-v /var/run/docker.sock:/var/run/docker.sock \
docker ls /tmp/dind3"
Вопрос в том, что мне нужно сделать, чтобы использовать путь к контейнеру 1, а не хост? Или я что-то не так понимаю в докере?
2 ответа
Несмотря на то, что вы говорите "Docker-in-Docker" и "dind", эта настройка на самом деле не Docker-in-Docker: ваш container1 дает инструкции демону Docker хоста, который влияет на container2.
Host Container1
/-----
(Docker)
| Container2
\---->
(Примечание: обычно это рекомендуемый путь для установок типа CI. "Docker-in-Docker" обычно означает, что container1 запускает свой собственный отдельный демон Docker, который обычно не рекомендуется.)
Так как container1 дает инструкции Docker хоста, а Docker хоста запускает container2, любой docker run -v
пути всегда являются путями хоста. Если вы не знаете, что какой-то конкретный каталог уже смонтирован в вашем контейнере, сложно обмениваться файлами с "субконтейнерами".
Один из способов обойти это - утверждать, что существует какой-то общий путь:
docker run \
-v $PWD/exchange:/exchange \
-v /var/run/docker.sock:/var/run/docker.sock \
-e EXCHANGE_PATH=$PWD/exchange \
--name container1
...
# from within container1
mkdir $EXCHANGE_PATH/container2
echo hello world > $EXCHANGE_PATH/container2/file.txt
docker run \
-v $EXCHANGE_PATH/container2:/data
--name container2
...
Когда я делал это в прошлом (для тестовой установки, которая хотела запускать вспомогательные контейнеры), я использовал кропотливую работу docker create
, docker cp
, docker start
, docker cp
, Docker rm
последовательность. Это очень удобно, но имеет то преимущество, что "местная" сторона docker cp
всегда является текущим контекстом файловой системы, даже если вы разговариваете с демоном Docker хоста из контейнера.
Не имеет значения, связывает ли контейнер 2 путь хоста, потому что изменения в файлах в контейнере 1 напрямую влияют на все пути хоста. Таким образом, они все работают над одними и теми же файлами.
Таким образом, ваши настройки верны и будут функционировать так же, как если бы они ссылались так, как вы описали.
Обновить
Если вы хотите убедиться, что процесс не изменяет файлы хоста, вы можете сделать следующее:
Создание пользовательских образов Docker, которые копируют все данные из папки a
в папку b
где вы выполняете скрипт на папке b
, А затем смонтировать файлы с ./:/a
, Таким образом вы сохраняете гибкость в отношении файлов, которые вы привязываете к контейнеру, не позволяя контейнеру изменять файлы хоста.
Надеюсь, это ответит на ваш вопрос:)