#docker #docker-compose #docker-in-docker
Вопрос:
Я подключил том shared
к своему сервису main
. Теперь я пытаюсь подключить тот же том к другому контейнеру client
, который запускается docker-compose up client
изнутри main
контейнера (Докер в докере).:
version: "3.8"
# set COMPOSE_PROJECT_NAME=default before running `docker-compose up main`
services:
main:
image: rbird/docker-compose:python-3.9-slim-buster
privileged: true
entrypoint: docker-compose up client # start client
volumes:
- //var/run/docker.sock:/var/run/docker.sock
- ./docker-compose.yml:/docker-compose.yml
- ./shared:/shared
client:
image: alpine
entrypoint: sh -c "ls shared*"
profiles:
- do-not-run-directly
volumes:
- /shared:/shared1
- ./shared:/shared2
Результат, который я получаю, таков:
[ ] Running 2/2
- Network test_default Created 0.0s
- Container test_main_1 Started 0.9s
Attaching to main_1
Recreating default_client_1 ... done
Attaching to default_client_1
main_1 | client_1 | shared1:
main_1 | client_1 |
main_1 | client_1 | shared2:
main_1 | default_client_1 exited with code 0
main_1 exited with code 0
Поэтому папки /shared2
и /shared2
пусты, хотя они содержат файлы как в каталоге хоста, так и в main
контейнере.
Как повторно разделить объемы между контейнерами?
Или есть способ разделить каталог хоста между всеми контейнерами, даже теми, которые запущены одним из контейнеров?
Ответ №1:
Самый чистый ответ здесь-удалить main:
контейнер и profiles:
блок для client:
контейнера и запустить docker-compose
непосредственно на хосте.
В приведенной здесь настройке используется сокет Docker хоста. (Это не «Докер в докере»; эта настройка, как правило, является еще более запутанным случаем запуска второго демона Докера в контейнере.) Это означает, что экземпляр Docker Compose внутри контейнера отправляет инструкции демону Docker хоста, указывая ему, какие контейнеры запускать. Вы монтируете docker-compose.yml
файл в корневом каталоге контейнера, поэтому ./shared
путь /
также интерпретируется относительно.
Это означает, что демон Docker хоста получает запрос на создание контейнера с /shared
подключением /shared1
внутри нового контейнера, а также с /shared
подключением ( ./shared
относительно пути /
) /shared2
. Демон Docker хоста создает этот контейнер, используя пути хоста. Если вы посмотрите на свою хост-систему, вы, вероятно, увидите пустой /shared
каталог в корневой папке файловой системы хоста, и если вы создадите там файлы, они появятся в новых контейнерах /shared1
и /shared2
каталогах.
В общем случае нет способа подключить файловую систему одного контейнера к другой. Если вы пытаетесь запустить docker
(или docker-compose
) из контейнера, вам необходимо иметь внешние знания о том, какие из ваших собственных файловых систем монтируются и что именно было смонтировано.
Если вы можете, избегайте как подходов к контейнерам, запускающим другие контейнеры, так и совместного использования объемов между контейнерами. Если можно запустить другой контейнер, и этот другой контейнер может монтировать произвольные части файловой системы хоста, то вы можете довольно просто запустить весь хост. В дополнение к проблемам безопасности, сложности пути, которые вы здесь отмечаете, трудно обойти. Общий доступ к томам плохо работает в средах, отличных от докеров (например, в Kubernetes трудно получить том для чтения и записи, и контейнеры, как правило, не будут находиться на одном хосте друг с другом), и существуют сложности с разрешениями и наличием нескольких читателей и авторов для одних и тех же файлов.
Вместо этого запускайте docker
и docker-compose
выполняйте команды только на хосте (как привилегированный пользователь в системе, не являющейся разработчиком). Если одному контейнеру требуется односторонняя публикация содержимого, доступного только для чтения, в другой контейнер, например в статические ресурсы, создайте пользовательское изображение COPY --from=
, одно изображение в другое. В противном случае рассмотрите возможность использования специального сетевого хранилища (например, базы данных), которое специально не зависит от файловой системы и знает, как обрабатывать параллельный доступ.