Что такое привязка монтирования?

Вопрос или проблема

Что такое “bind mount”? Как сделать это? Для чего это нужно?

Мне сказали использовать bind mount для чего-то, но я не понимаю, что это такое и как им пользоваться.

Что такое bind mount?

Bind mount — это альтернативный вид на дерево каталогов. Классически монтирование создает вид устройства хранения в виде дерева каталогов. Bind mount вместо этого берет существующее дерево каталогов и реплицирует его в другом месте. Каталоги и файлы в bind mount такие же, как и оригинальные. Любое изменение на одной стороне сразу же отражается на другой стороне, так как оба вида показывают одни и те же данные.

Например, после выполнения команды Linux:

mount --bind /some/where /else/where

каталоги /some/where и /else/where имеют одинаковое содержимое, которое есть содержимое /some/where. (Если /else/where был не пуст, его прежнее содержимое теперь скрыто.)

В отличие от жесткой или символической ссылки, bind mount не влияет на то, что хранится на файловой системе. Это свойство активной системы.

Как создать bind mount?

bindfs

Файловая система bindfs — это файловая система FUSE, которая создает вид на дерево каталогов. Например, команда

bindfs /some/where /else/where

делает /else/where точкой монтирования, под которой видно содержимое /some/where.

Поскольку bindfs — это отдельная файловая система, файлы /some/where/foo и /else/where/foo выглядят как разные файлы для приложений (файловая система bindfs имеет собственное значение st_dev). Любое изменение на одной стороне “волшебным образом” отражается на другой стороне, но тот факт, что файлы одинаковые, очевиден только когда знаешь, как работает bindfs.

Bindfs не знает точек монтирования, поэтому если есть точка монтирования под /some/where, она выглядит как еще один каталог под /else/where. Монтирование или демонтаж файловой системы под /some/where будет отображаться под /else/where как изменение соответствующего каталога.

Bindfs может изменить некоторые метаданные файлов: он может показывать фальшивые права доступа и владение файлами. См. руководство для подробностей, и ниже примеры.

Файловая система bindfs может быть смонтирована пользователем, не имеющим права root, вам нужны только привилегии для монтирования файловых систем FUSE. В зависимости от вашей дистрибуции, для этого может потребоваться входить в группу fuse, либо это может быть доступно всем пользователям. Для демонтажа файловой системы FUSE используйте fusermount -u вместо umount, например:

fusermount -u /else/where

nullfs

FreeBSD предоставляет файловую систему nullfs, которая создает альтернативный вид файловой системы. Следующие две команды эквивалентны:

mount -t nullfs /some/where /else/where
mount_nullfs /some/where /else/where

После выполнения любой из команд /else/where становится точкой монтирования, в которой видно содержимое /some/where.

Поскольку nullfs — это отдельная файловая система, файлы /some/where/foo и /else/where/foo выглядят как разные файлы для приложений (файловая система nullfs имеет собственное значение st_dev). Любое изменение на одной стороне “волшебным образом” отражается на другой стороне, но тот факт, что файлы одинаковые, очевиден только когда знаешь, как работает nullfs.

В отличие от FUSE bindfs, который действует на уровне дерева каталогов, nullfs FreeBSD работает глубже в ядре, поэтому точки монтирования под /else/where не видны: только дерево, которое входит в ту же точку монтирования, что и /some/where, отражается под /else/where.

Файловая система nullfs может быть доступна под другими вариантами BSD (OS X, OpenBSD, NetBSD), но она не включена в систему по умолчанию.

Linux bind mount

В Linux bind mounts доступны как функция ядра. Вы можете создать его с помощью команды mount, используя либо параметр командной строки --bind, либо параметр монтирования bind. Следующие две команды эквивалентны:

mount --bind /some/where /else/where
mount -o bind /some/where /else/where

Здесь устройство /some/where не является разделом диска, как в случае с файловой системой на диске, а представляет собой существующий каталог. Точка монтирования /else/where должна быть существующим каталогом как обычно. Обратите внимание, что тип файловой системы не указан ни в одном из случаев: создание bind mount не связано с драйвером файловой системы, оно копирует структуры данных ядра из оригинального монтирования.

mount --bind также поддерживает монтирование не каталога на не каталог: /some/where может быть обычным файлом (в этом случае /else/where тоже должен быть обычным файлом).

Linux bind mount в основном неотличим от оригинала. Команда df -T /else/where показывает те же устройство и тип файловой системы, что и df -T /some/where. Файлы /some/where/foo и /else/where/foo неотличимы, как если бы они были жесткими ссылками. Можно размонтировать /some/where, в этом случае /else/where останется смонтированным.

В старых ядрах (не знаю точно, когда, думаю до некоторых версий 3.x) bind mounts были действительно неотличимы от оригинала. Недавние ядра отслеживают bind mounts и отображают информацию через /proc/PID/mountinfo, что позволяет findmnt указывать bind mounts как таковые.

Вы можете добавить записи bind mount в /etc/fstab. Просто включите bind (или rbind и т.д.) в параметры, вместе с любыми другими опциями, которые вы хотите. “Устройство” — это существующее дерево. Столбец файловой системы может содержать none или bind (это игнорируется, но использование имени файловой системы будет сбивать с толку). Например:

/some/where /readonly/view none bind,ro

Если под /some/where находятся точки монтирования, их содержимое не видно под /else/where. Вместо bind вы можете использовать rbind, чтобы также реплицировать точки монтирования под /some/where. Например, если /some/where/mnt является точкой монтирования, то

mount --rbind /some/where /else/where

эквивалентно

mount --bind /some/where /else/where
mount --bind /some/where/mnt /else/where/mnt

Кроме того, Linux позволяет объявлять монтирования как shared, slave, private или unbindable. Это влияет на то, будет ли это монтирование отражено под bind mount, который реплицирует точку монтирования. Для подробностей смотрите документацию ядра.

Linux также предоставляет способ перемещения монтирований: где --bind копирует, --move перемещает точку монтирования.

Можно установить разные параметры монтирования в двух каталогах, смонтированных с помощью bind. Однако есть нюанс: создание bind mount и установка параметров монтирования не могут быть выполнены атомарно, их нужно делать двумя последовательными операциями. (Старые ядра не позволяли этого.) Например, следующие команды создают вид только для чтения, но есть небольшое окно времени, в течение которого /else/where находится в режиме чтения-записи:

mount --bind /some/where /else/where
mount -o remount,ro,bind /else/where

Я не могу заставить bind mounts работать!

Если ваша система не поддерживает FUSE, классический трюк, чтобы добиться такого же эффекта, заключается в запуске NFS-сервера, экспортировании файлов, которые вы хотите предоставить, и монтировании их на ту же машину. Это имеет значительное влияние на память и производительность, поэтому bind mounts имеют явное преимущество там, где они доступны (что касается большинства вариантов Unix благодаря FUSE).

Сценарии использования

Вид только для чтения

Может быть полезно создать вид файловой системы только для чтения, либо по соображениям безопасности, либо просто как уровень безопасности, чтобы обеспечить невозможность случайного изменения.

С bindfs:

bindfs -r /some/where /mnt/readonly

В Linux простым способом:

mount --bind /some/where /mnt/readonly
mount -o remount,ro,bind /mnt/readonly

Это оставляет короткий интервал времени, в течение которого /mnt/readonly находится в режиме чтения-записи. Если это проблема безопасности, сначала создайте bind mount в каталоге, доступ к которому только root может иметь, сделайте его только для чтения, затем переместите его в общую точку монтирования. В приведенном ниже отрывке кода обратите внимание, что важно, чтобы /root/private (каталог выше точки монтирования) был закрытым; исходные разрешения на /root/private/mnt не имеют значения, так как они скрыты за точкой монтирования.

mkdir -p /root/private/mnt
chmod 700 /root/private
mount --bind /some/where /root/private/mnt
mount -o remount,ro,bind /root/private/mnt
mount --move /root/private/mnt /mnt/readonly

Преобразование пользователей и групп

Файловые системы записывают пользователей и группы по их числовым идентификаторам. Иногда вы сталкиваетесь с несколькими системами, которые назначают разные идентификаторы пользователей одному и тому же человеку. Это не проблема при сетевом доступе, однако это делает идентификаторы пользователей бессмысленными, когда вы переносите данные с одной системы на другую на диске. Предположим, что у вас есть диск, созданный с много-пользовательской файловой системой (например, ext4, btrfs, zfs, UFS и т.д.) на системе, где у Алисы идентификатор пользователя 1000, а у Боба 1001, и вы хотите сделать этот диск доступным на системе, где у Алисы идентификатор пользователя 1001, а у Боба 1000. Если вы смонтируете диск напрямую, файлы Алисы будут выглядеть как принадлежащие Бобу (так как идентификатор пользователя 1001), а файлы Боба будут выглядеть как принадлежащие Алисе (так как идентификатор пользователя 1000).

Вы можете использовать bindfs, чтобы применять преобразование идентификаторов пользователей. Сперва смонтируйте раздел диска в закрытом каталоге, к которому только root имеет доступ. Затем создайте вид bindfs в общественной области, с преобразованием идентификаторов пользователей и групп, которое меняет местами идентификаторы пользователей и групп Алисы и Боба.

mkdir -p /root/private/alice_disk /media/alice_disk
chmod 700 /root/private
mount /dev/sdb1 /root/private/alice_disk
bindfs --map=1000/1001:1001/1000:@1000/1001:@1001/1000 /root/private/alice_disk /media/alice_disk

Смотрите Как можно законно получить доступ к файлам в домашнем каталоге пользователя на не загруженной системе? и mount –bind другого пользователя как себя для других примеров.

Монтирование в тюрьму или контейнер

Chroot jail или контейнер запускает процесс в поддереве системного дерева каталогов. Это может быть полезно для запуска программы с ограниченным доступом, например, запуска сетевого сервера с доступом только к его собственным файлам и файлам, которые он обслуживает, но не к другим данным, хранящимся на том же компьютере. Ограничение chroot в том, что программа ограничена одним поддеревом: она не может получить доступ к независимым поддеревам. Bind mounts позволяют присоединять другие поддеревья к основному дереву. Это делает их основными для большинства практических применений контейнеров под Linux.

Например, предположим, что на машине работает сервис /usr/sbin/somethingd, который должен иметь доступ только к данным под /var/lib/something. Наименьшее дерево каталогов, которое содержит оба этих файла, это корень. Как можно ограничить доступ сервиса? Один из вариантов — сделать жесткие ссылки на все файлы, которые нужны сервису (по крайней мере /usr/sbin/somethingd и несколько общих библиотек) под /var/lib/something. Но это неудобно (жесткие ссылки нужно обновлять, когда файл обновляется), и не работает, если /var/lib/something и /usr находятся на разных файловых системах. Лучшее решение — создать временный корень и заполнить его, используя монтирования:

mkdir /run/something
cd /run/something
mkdir -p etc/something lib usr/lib usr/sbin var/lib/something
mount --bind /etc/something etc/something
mount --bind /lib lib
mount --bind /usr/lib usr/lib
mount --bind /usr/sbin usr/sbin
mount --bind /var/lib/something var/lib/something
mount -o remount,ro,bind etc/something
mount -o remount,ro,bind lib
mount -o remount,ro,bind usr/lib
mount -o remount,ro,bind usr/sbin
chroot . /usr/sbin/somethingd &

Linux’овые пространства имен монтирования обобщают chroots. Bind mounts позволяют упорядочивать пространства имен гибкими способами. Смотрите Как заставить процесс читать другой файл для того же имени файла для примера.

Запуск другой дистрибуции

Еще одно применение chroots — это установка в каталоге другой дистрибуции и запуск программ из нее, даже если они требуют файлов с жестко прописанными путями, которые отсутствуют или имеют другое содержимое в базовой системе. Это может быть полезно, например, для установки 32-битной дистрибуции на 64-битную систему, которая не поддерживает смешанные пакеты, установки старых выпусков дистрибуции или других дистрибуций для тестирования совместимости, установки нового выпуска для тестирования последних функций при поддержании стабильной базовой системы и т.д. Смотрите Как я могу запустить 32-битные программы на 64-битном Debian/Ubuntu? для примера на Debian/Ubuntu.

Предположим, что у вас есть установка последних пакетов вашей дистрибуции под каталогом /f/unstable, где вы запускаете программы, переходя в этот каталог с помощью chroot /f/unstable. Чтобы сделать домашние каталоги доступными из этой установки, смонтируйте их в chroot:

mount --bind /home /f/unstable/home

Программа schroot делает это автоматически.

Доступ к файлам за точкой монтирования

Когда вы монтируете файловую систему на каталог, это скрывает то, что находится за каталогом. Файлы в этом каталоге становятся недоступными, пока каталог не будет размонтирован. Поскольку BSD nullfs и Linux bind mounts оперируют на более низком уровне, чем инфраструктура монтирования, nullfs mount или bind mount файловой системы предоставляют доступ к каталогам, которые были скрыты за вложенными монтированиями в оригинале.

Например, предположим, что у вас есть файловая система tmpfs, смонтированная на /tmp. Если под /tmp были файлы, когда файловая система tmpfs была создана, эти файлы могут еще оставаться, фактически недоступные, но занимающие место на диске. Выполните

mount --bind / /mnt

(Linux) или

mount -t nullfs / /mnt

(FreeBSD) чтобы создать вид корневой файловой системы на /mnt. Каталог /mnt/tmp — это тот, который из корневой файловой системы.

Экспорт NFS по разным путям

Некоторые NFS-серверы (например, NFS-сервер ядра Linux до NFSv4) всегда рекламируют фактическое местоположение каталога, когда они экспортируют каталог. То есть, когда клиент запрашивает server:/requested/location, сервер обслуживает дерево по местоположению /requested/location. Иногда может быть желательно позволить клиентам запрашивать /request/location, но фактически обслуживать файлы под /actual/location. Если ваш NFS-сервер не поддерживает обслуживание альтернативного местоположения, вы можете создать bind mount для ожидаемого запроса, например:

/requested/location *.localdomain(rw,async)

в /etc/exports и следующее в /etc/fstab:

/actual/location /requested/location bind bind

Замена символическим ссылкам

Иногда вам нужно создать символическую ссылку, чтобы файл /some/where/is/my/file отображался под /else/where, но приложение, которое использует file, разворачивает символические ссылки и отвергает /some/where/is/my/file. Bind mount может обойти это: биндовым способом смонтируйте /some/where/is/my в /else/where/is/my, и тогда realpath сообщит, что /else/where/is/my/file находится под /else/where, а не под /some/where.

Побочные эффекты от bind mounts

Рекурсивные обходы каталогов

Если вы используете bind mounts, вам нужно заботиться о приложениях, которые рекурсивно обходят дерево файловой системы, таких как резервные копии и индексация (например, для создания базы данных locate).

Обычно bind mounts должны быть исключены из рекурсивных обходов каталогов, чтобы каждое дерево каталогов обходилось только один раз, в оригинальном местоположении. С bindfs и nullfs настройте инструмент обхода так, чтобы он игнорировал эти типы файловых систем, если это возможно. Linux’овые bind mounts нельзя распознать как таковые: новое местоположение эквивалентно оригинальному. С Linux’овыми bind mounts, или с инструментами, которые могут исключать только пути, а не типы файловых систем, вам нужно исключать точки монтирования для bind mounts.

Обходы, которые останавливаются на границах файловых систем (например, find -xdev, rsync -x, du -x и т.д.) автоматически остановятся, когда столкнутся с точкой монтирования bindfs или nullfs, так как эта точка монтирования — это другая файловая система. С Linux’овыми bind mounts ситуация немного сложнее: существует граница файловой системы только в том случае, если bind mount присоединяет другую файловую систему, а не если он присоединяет другую часть той же файловой системы.

Превзойти bind mounts

Bind mounts предоставляют вид на дерево каталогов в другом месте. Они показывают те же файлы, возможно, с другими параметрами монтирования и (с bindfs) другим владением и разрешениями. Файловые системы, которые представляют измененный вид на дерево каталогов, называются overlay filesystems или stackable filesystems. Есть много других overlay file-систем, которые выполняют более сложные преобразования. Вот несколько известных. Если ваш желаемый сценарий использования не описан здесь, посмотрите репозиторий FUSE-файловых систем.

Фильтрация видимых файлов

  • clamfs — запуск файлов через антивирусный сканер при их чтении

  • filterfs — скрытие частей файловой системы

  • rofs — вид только для чтения. Похоже на bindfs -r, только немного легче.

  • Унионные монтирования — представьте несколько файловых систем (называемых ветвями) в одном каталоге: если tree1 содержит foo, а tree2 содержит bar, то их объединенный вид содержит и foo, и bar. Новые файлы записываются в определенную ветвь, или в ветвь, выбранную в соответствии с более сложными правилами. Существует несколько реализаций этой концепции, включая:

Изменение имен файлов и метаданных

  • ciopfs — регистронезависимые имена файлов (может быть полезно для монтирования файловых систем Windows)
  • convmvfs — преобразование имен файлов между кодировками (пример)
  • posixovl — хранение Unix-имен файлов и других метаданных (разрешений, владения и т.д.) на более ограниченных файловых системах, таких как VFAT (пример)

Просмотр измененного содержимого файлов

Изменение способа хранения содержимого

  • chironfs — реплицирование файлов на несколько подпамяти (RAID-1 на уровне дерева каталогов)
  • copyfs — хранение копий всех версий файлов
  • encfs — шифрование файлов
  • pcachefs — кеширующий слой на диске для медленных удаленных файловых систем
  • simplecowfs — хранение изменений через предоставленный вид в памяти, оставляя оригинальные файлы нетронутыми
  • wayback — хранение копий всех версий файлов

Я нашел следующее объяснение очень полезным, так как оно не создает представление о том, что оно действительно копирует/дублирует данные:

Bind mounts можно рассматривать как своего рода символическую ссылку на уровне файловой системы. Используя mount --bind, можно создать вторую точку монтирования для существующей файловой системы, делая эту файловую систему видимой в другом месте в пространстве имен.

Таким образом, bind mounts полезны для создания специфических видов пространства имен файловой системы; можно, например, создать bind mount, который делает часть файловой системы видимой в среде, которая иначе закрыта с помощью chroot().

Источник: https://lwn.net/Articles/281157/

Просто, при использовании bind mount, файл или каталог на хост-машине монтируется в контейнер таким образом, что любые изменения, внесенные в файл каталога на хост-машине, автоматически становятся доступными в контейнере в каталоге.

Ответ или решение

Что такое bind mount?

Теория

Bind mount, также известный как привязочное монтирование, представляет альтернативный способ организации доступа к файловой системе в Unix-подобных операционных системах. В отличие от классического монтирования, которое создает вид файловой системы на основе конкретного устройства хранения, bind mount позволяет реплицировать уже существующее дерево директорий в другой точке файловой системы. Это означает, что файлы и директории, расположенные в исходной директории, становятся доступными под новым путём доступа, не создавая дубликатов данных.

Такой метод монтирования обладает уникальной способностью создавать альтернативное представление существующих данных: изменения, произведенные в одной точке, мгновенно отображаются в другой. Это отличает bind mounts от жестких и символических ссылок, которые, в отличие от them, затрагивают файловую систему на уровне хранимых данных.

Пример

Рассмотрим пример использования команды в Linux:

mount --bind /some/where /else/where

Здесь директория /some/where будет временно "дублирована" под новым путем /else/where. Все изменения, произведенные в одной из этих директорий, будут мгновенно отразятся в другой, что позволяет создавать гибкие варианты организации доступа к данным. Но стоит помнить, что если /else/where уже содержала данные, они будут временно скрыты до момента размонтирования.

Применение

Bind mounts активно используются в ряде сценариев, наиболее распространенные из которых включают:

  1. Контейнеризация и виртуализация: Bind mounts позволяют изолировать и ограничивать доступ к файлам конкретных программ, работающих в среде chroot или контейнерах, таких как Docker. Благодаря им, программное обеспечение может иметь доступ лишь к строго определенным файлам, минимизируя риск несанкционированного доступа к остальным системным данным.

  2. Упрощение доступа и организации данных: Они позволяют организовывать более удобный и понятный доступ к файловым системам, особенно в случае сложных сетевых конфигураций или при необходимости предоставления альтернативных точек доступа к данным для пользователей.

  3. Создание защищенных от записи представлений данных: Используя bind mount, администраторы могут создавать защищенные от изменений вьюпы данных, что важно для предотвращения случайного или намеренного их изменения, например, в конфигурации серверного ПО.

  4. Управление пользователями и группами: Они могут помочь в ситуациях, когда необходимо изменить отображаемые права доступа или владельцев без изменения самих базовых файлов. Это может быть полезно при переносе дисков межу системами с разными UID/GID.

  5. Тестирование и управление совместимостью ПО: Позволяют запускать программы, разработанные для другой ОС, путём создания изолированных сред выполнения. Например, запуск приложений 32-bit на 64-bit системах, тестирование различного ПО без смены основной системы и т.д.

Таким образом, bind mounts представляют собой мощный инструмент в арсенале системного администратора, способный значительно упростить управление файловыми системами и обеспечить более гибкое и безопасное использование данных в сложных IT-инфраструктурах.

Оцените материал
Добавить комментарий

Капча загружается...