Монтирование тома с докера в докер? - PullRequest
3 голосов
/ 25 апреля 2019

У меня есть Docker-контейнер «A», который запускает другой контейнер «B» (при монтировании тома /var/run/docker.sock).Теперь эти контейнеры должны обмениваться файлами.

Контейнер "B" ожидает, что файлы будут смонтированы на томе, и самый простой способ сделать это - привязать монтирование из "A" к "B", но Docker не можетсделать это (bind mounts всегда происходит из файловой системы хоста).

Существует ли простой способ для контейнера совместно использовать файлы с созданным им контейнером, не полагаясь на файловую систему хоста и не создавая "B "изображение из" A "?

Я экспериментировал с созданием томов и копированием в него файлов, но решения, как правило, сложные и хрупкие.В идеале я хотел бы поместить решение в файл docker-compose для запуска внутри «A», но это выглядит практически невозможным.

Для справки, это еще одна идея, которая бы идеально решила мою проблему:https://github.com/docker/compose/issues/3593#issuecomment-272089143

1 Ответ

3 голосов
/ 25 апреля 2019

Когда вы монтируете докер-сокет, он в действительности не докер в докере, а просто клиент, делающий запросы к демону на хосте через API, и этот демон не знает, откуда поступают запросы.Таким образом, вы можете упростить этот вопрос до «можете ли вы монтировать файлы из одного контейнера в другой контейнер».К сожалению, нет простого ответа на это без использования томов, которые являются внешними для обоих контейнеров.Это связано с тем, что файловые системы контейнеров зависят от драйвера графа, используемого для сборки различных слоев изображений и контейнеров, поэтому даже решение, которое может работать для overlay2, будет работать на других драйверах и зависеть от внутренних компонентов докера, которые могут измениться без предупреждения.

Как только вы попадаете на внешний том, я могу придумать несколько возможных решений.

Вариант A: общий каталог хоста. Я использую это довольно частос тем, что я считаю прозрачными контейнерами на своем ноутбуке, скрывая тот факт, что я запускаю команды внутри контейнера.Я монтирую общий каталог с полным путем в моем контейнере, например -v $HOME:$HOME.Эту же технику можно использовать внутри контейнера «A» и «B», если вы смонтировали одинаковые каталоги хоста в каждомЕсли вы используете монтирование тома, как указано выше, для контейнера «A», это будет работать с составным файлом, поскольку путь внутри контейнера такой же, как и на хосте.

Опция B:volume_from. Я не решаюсь даже упомянуть это как вариант, потому что он постепенно прекращается, когда пользователи переходят в режим роя, но есть возможность монтировать все тома в контейнере "A" в контейнер "B".Для этого по-прежнему необходимо определить том в контейнере «A», но теперь вам нет дела до источника тома, это может быть хост, именованный или анонимный том.

Опция C: shared named volume. Именованные тома позволяют docker управлять хранилищем данных, по умолчанию в / var / lib / docker / volume на хосте.Вы можете запустить оба контейнера с одинаковым именованным томом, что позволяет передавать данные между контейнерами.Вам нужно иметь имя тома в контейнере «A», чтобы выполнить команду для контейнера «B» с тем же именем.Именованные тома также инициализируют содержимое именованного тома из образа при первом использовании именованного тома, что может быть полезно, особенно для владения файлами и прав доступа.Просто помните, что при следующем использовании тома с тем же именем он не будет повторно инициализироваться поверх любых существующих данных, вместо этого предыдущие данные будут постоянными.В случае составного файла вам нужно будет определить именованный том как внешний.

Опция D: созданный вручную именованный том. Если вы пытаетесь только вставить некоторые файлы в контейнер «B»из контейнера «A» есть множество способов внедрить это через интерфейс докера.Я видел файлы, сохраненные в переменных среды на «A», а затем переменная среды, записанная обратно в файл в точке входа для «B».Для больших файлов или для того, чтобы избежать изменения точки входа «B», вы можете создать именованный том и заполнить его, передав данные по каналам stdin / stdout докера в работающий контейнер и упаковывая / распаковывая эти данные с помощью tar для отправки черезтрубы ввода / вывода.Это будет работать изнутри контейнера «A», так как одна половина команды tar выполняется внутри файловой системы этого контейнера.Затем контейнер "B" будет монтировать этот именованный том.Чтобы импортировать данные из контейнера «A» в именованный том, который выглядит следующим образом:

tar -cC source_dir . | \
  docker run --rm -i -v target_vol:/target busybox tar -xC /target

И чтобы вернуть данные из именованного тома, процесс выполняется в обратном порядке:

docker run --rm -v source_vol:/source busybox tar -cC /source . | \
  tar -xC target_dir

Подобно опции C, вам нужно определить этот именованный том как внешний в вашем файле компоновки.

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