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

325

Что такое «гора крепления»? Как мне сделать один? Для чего это?

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

жилль
источник
2
полезные альтернативные разъяснения между горами и символическими ссылками
Чарли Паркер

Ответы:

564

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

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

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

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

каталоги /some/whereи /else/whereимеют одинаковое содержание.

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

Как мне создать привязку?

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должна быть существующим каталогом, как обычно. Обратите внимание, что ни один из типов файловой системы не указан в любом случае: при выполнении монтирования связывания не требуется драйвер файловой системы, он копирует структуры данных ядра из исходного монтирования.

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

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

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

Вы можете поместить записи 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 позволяет объявлять монтируемые как общие , подчиненные , частные или несвязываемые . Это влияет на то, отражается ли эта операция монтирования под монтированием привязки, которое копирует точку монтирования. Для более подробной информации смотрите документацию ядра .

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

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

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

Я не могу заставить повязки работать!

Если ваша система не поддерживает FUSE, классическим приемом для достижения того же эффекта является запуск NFS-сервера, заставить его экспортировать файлы, которые вы хотите предоставить (разрешить доступ localhost), и смонтировать их на той же машине. Это приводит к значительным накладным расходам с точки зрения памяти и производительности, поэтому монтирование bind имеет определенное преимущество, когда оно доступно (что есть в большинстве вариантов 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происходит чтение-запись. Если это проблема безопасности, сначала создайте монтирование связывания в каталоге, к которому имеет доступ только 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

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

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

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

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

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 обобщают chroot. Привязка - это то, как пространства имен можно заполнять гибкими способами. См. Пример создания процесса для чтения другого файла с тем же именем файла .

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

Другое использование 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 или монтирование bind файловой системы предоставляет каталоги, которые были скрыты за субмонтированием в оригинале.

Например, предположим, что у вас есть смонтированная файловая система 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-сервер не поддерживает обслуживание альтернативного местоположения, вы можете создать привязку для ожидаемого запроса, например

/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 может обойти это: bind-mount /some/where/is/myto /else/where/is/my, а затем realpathсообщит, /else/where/is/my/fileчто находится под /else/where, а не под /some/where.

Побочные эффекты креплений

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

Если вы используете 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 использует другую файловую систему, а не если она собирает другую часть той же файловой системы.

Выходя за рамки крепления

Монтирование привязки обеспечивает просмотр дерева каталогов в другом месте. Они предоставляют одни и те же файлы, возможно, с разными параметрами монтирования и (с bindfs) разными владельцами и разрешениями. Файловые системы, которые представляют измененное представление дерева каталогов, называются наложенными файловыми системами или наращиваемыми файловыми системами . Существует много других наложенных файловых систем, которые выполняют более сложные преобразования. Вот несколько распространенных. Если желаемый вариант использования здесь не описан, проверьте репозиторий файловых систем 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 - сохраняет изменения в представлении в памяти, оставляя исходные файлы без изменений
  • обратный путь - хранить копии всех версий файлов
жилль
источник
1
Можно добавить пример того, как это сделать с помощью systemd: utcc.utoronto.ca/~cks/space/blog/linux/SystemdBindMountUnits
dothebart,
1
Что делает mount --bind /dir1 /dir1? Чем он отличается от случая, когда источник и цель монтажа отличаются?
Отметить
Я не видел никаких записей в / proc / self / mountinfo, используя linux 5.0. Ядро не говорит мне, что это bind mount или нет. И процесс может легко нарушить chroot, изоляция должна быть сделана с помощью пространства имен mount.
德里克 薯条 德里克
@ 炸鱼 薯条 德里克 Я думаю, что связанный вопрос unix.stackexchange.com/questions/295525/… адреса /proc/self/mountinfo. Что касается chroot, он может быть использован для изоляции, но не сам по себе. Вам не нужно монтировать пространства имен, хотя: chroot достаточно для части пространства имен файловой системы. Вы должны убедиться, что ни один процесс в chroot не запускается от имени того же пользователя, что и процесс вне chroot.
Жиль
@Mark Bind-монтирование каталога на себя не очень полезно. Я думаю, вы могли бы использовать это, чтобы скрыть файловые системы, смонтированные в определенном каталоге, но я не могу вспомнить время, когда я хотел сделать это специально.
Жиль
-1

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

Шринивас
источник
Это один из способов использования привязки, но сами привязки не имеют ничего общего с контейнерами. Я упоминаю об этом в своем ответе, но под названием «тюрьма», а не «контейнер»; добавление «контейнера» будет полезным редактированием (я сделаю это). Это также плохое описание: зачем упоминать, что изменения, сделанные снаружи, также доступны внутри, не упоминая наоборот?
Жиль