Рассмотрим следующий контейнер Docker:
docker run --rm -it -v /tmp:/mnt/tmp alpine sh
Это монтирует каталог хоста / tmp в / mnt / tmp внутри контейнера alpine.
Теперь в хост-системе я монтирую том NFS в каталог / tmp:
mkdir /tmp/nfs
mount -t nfs4 192.168.1.100:/data /tmp/nfs
Монтирование работает на хост-системе, и я вижу следующее:
# ls /tmp/nfs
file1 file2 file3
#
Но в Docker Container я вижу пустой каталог:
# ls /mnt/tmp/nfs
#
Я знаю, что могу обойти это, выполнив монтирование непосредственно в Docker Container. Но мне действительно интересно знать, почему монтирование работает на контейнере хоста, а не в контейнере докера?
Ответы:
Это происходит потому, что том использует
private
распространение монтирования. Это означает, что после монтирования любые изменения, происходящие на стороне источника (например, на стороне хоста в случае Docker), не будут видны под монтированием.Есть несколько способов справиться с этим:
Сначала смонтируйте NFS, затем запустите контейнер. Монтирование будет распространяться на контейнер, однако, как и прежде, любые изменения в монтировании не будут видны контейнеру (включая размонтирование).
Используйте «рабское» распространение. Это означает, что после создания монтирования любые изменения на стороне источника (хост-докер) будут видны в цели (в контейнере). Если вы делаете вложенные монтирования, вы захотите использовать
rslave
(r
для рекурсии).Существует также «совместное» распространение. Этот режим будет вносить изменения в точку монтирования изнутри контейнера, распространяющегося на хост, а также наоборот. Поскольку ваш пользователь даже не будет иметь привилегий для внесения таких изменений (если вы не добавите CAP_SYS_ADMIN), это, вероятно, не то, что вы хотите.
Вы можете установить режим распространения при создании монтирования следующим образом:
Другой альтернативой будет использование тома, а не хоста. Вы можете сделать это так:
Это гарантирует, что вы всегда будете монтировать в контейнере, не полагаясь на настройку хоста каким-либо особым образом или на распространение монтирования.
примечание : в
:
начале пути к устройству требуется что-то странное в модуле ядра nfs.примечание : Docker в настоящее время не разрешает
<nfs host>
DNS-имя (оно будет в 1.13), поэтому вам нужно указать здесь IP-адрес.Более подробная информация о монтировании «разделяемого поддерева»: https://www.kernel.org/doc/Documentation/filesystems/sharedsubtree.txt
источник
Включите распространение общего монтирования на томе, добавив флаг: shared в конце аргумента тома:
Если Docker был установлен через менеджер пакетов или сценарий установки для systemd, вам может потребоваться настроить аргумент демона MountFlags. Для этого найдите файл docker.service:
В моем случае в Ubuntu 16.04 он был расположен по адресу /etc/systemd/system/multi-user.target.wants/docker.service. Отредактируйте этот файл с помощью vi или nano и убедитесь, что опция MountFlags гласит:
Сохраните файл, перезагрузите аргументы демона и перезапустите докер:
Теперь у вас должна быть возможность установить общий флаг распространения монтирования на томах при использовании «запуска Docker».
источник
Начиная с Docker 17.06, вы можете подключать общие ресурсы NFS к контейнеру непосредственно при его запуске, без необходимости дополнительных возможностей.
Кроме того, вы можете создать том перед контейнером:
Получил подсказку с https://github.com/moby/moby/issues/28809
источник