¿Qué es un montaje de unión?

326

¿Qué es un "montaje de unión"? ¿Cómo hago uno? ¿Para que sirve?

Me han dicho que use un montaje de enlace para algo, pero no entiendo qué es o cómo usarlo.

Gilles
fuente
2
aclaración alternativa útil entre monturas y enlaces simbólicos: quora.com/…
Charlie Parker

Respuestas:

565

¿Qué es un montaje de unión?

Un montaje de enlace es una vista alternativa de un árbol de directorios. Clásicamente, el montaje crea una vista de un dispositivo de almacenamiento como un árbol de directorios. En cambio, un montaje de enlace toma un árbol de directorio existente y lo replica bajo un punto diferente. Los directorios y archivos en el montaje de enlace son los mismos que los originales. Cualquier modificación en un lado se refleja inmediatamente en el otro lado, ya que las dos vistas muestran los mismos datos.

Por ejemplo, después de emitir el comando Linux

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

los directorios /some/wherey /else/wheretienen el mismo contenido.

A diferencia de un enlace duro o un enlace simbólico, un montaje de enlace no afecta lo que está almacenado en el sistema de archivos. Es una propiedad del sistema en vivo.

¿Cómo creo un montaje de enlace?

bindfs

El bindfssistema de archivos es un sistema de archivos FUSE que crea una vista de un árbol de directorios. Por ejemplo, el comando

bindfs /some/where /else/where

crea /else/whereun punto de montaje bajo el cual los contenidos de /some/whereson visibles.

Desde bindfs es un sistema de archivos por separado, los archivos /some/where/fooy /else/where/fooaparecen como diferentes archivos de aplicaciones (el bindfs sistema de archivos tiene su propio st_devvalor). Cualquier cambio en un lado se refleja "mágicamente" en el otro lado, pero el hecho de que los archivos son los mismos solo es evidente cuando uno sabe cómo funciona bindfs.

Bindfs no tiene conocimiento de los puntos de montaje, por lo que si hay un punto de montaje debajo /some/where, aparece como otro directorio debajo /else/where. Montar o desmontar un sistema de archivos debajo /some/whereaparece /else/wherecomo un cambio del directorio correspondiente.

Bindfs puede alterar algunos de los metadatos del archivo: puede mostrar permisos falsos y propiedad de los archivos. Consulte el manual para obtener más información y los ejemplos a continuación.

Un sistema de archivos bindfs se puede montar como usuario no root, solo necesita el privilegio para montar sistemas de archivos FUSE. Dependiendo de su distribución, esto puede requerir estar en el fusegrupo o estar permitido a todos los usuarios. Para desmontar un sistema de archivos FUSE, use en fusermount -ulugar de umount, por ejemplo

fusermount -u /else/where

nullfs

FreeBSD proporciona el nullfssistema de archivos que crea una vista alternativa de un sistema de archivos. Los siguientes dos comandos son equivalentes:

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

Después de emitir cualquiera de los comandos, se /else/whereconvierte en un punto de montaje en el que los contenidos de /some/whereson visibles.

Desde nullfs es un sistema de archivos por separado, los archivos /some/where/fooy /else/where/fooaparecen como diferentes archivos de aplicaciones (el nullfs sistema de archivos tiene su propio st_devvalor). Cualquier cambio en un lado se refleja "mágicamente" en el otro lado, pero el hecho de que los archivos son los mismos solo es evidente cuando uno sabe cómo funciona nullfs.

A diferencia de los bindfs FUSE, que actúan al nivel del árbol de directorios, los nullfs de FreeBSD actúan más profundamente en el núcleo, por lo que los puntos de montaje debajo /else/whereno son visibles: solo el árbol que forma parte del mismo punto de montaje que /some/wherese refleja debajo /else/where.

El sistema de archivos nullfs puede utilizarse con otras variantes BSD (OS X, OpenBSD, NetBSD) pero no se compila como parte del sistema predeterminado.

Montaje de enlace de Linux

En Linux, los montajes de enlace están disponibles como una característica del núcleo. Puede crear uno con el mountcomando, pasando la --bindopción de línea de comando o la bindopción de montaje. Los siguientes dos comandos son equivalentes:

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

Aquí, el "dispositivo" /some/whereno es una partición de disco como en el caso de un sistema de archivos en disco, sino un directorio existente. El punto de montaje /else/wheredebe ser un directorio existente como de costumbre. Tenga en cuenta que no se especifica ningún tipo de sistema de archivos de ninguna manera: hacer un montaje de enlace no implica un controlador de sistema de archivos, copia las estructuras de datos del núcleo del montaje original.

mount --bindtambién admite el montaje de un no directorio en un no directorio: /some/wherepuede ser un archivo normal (en cuyo caso también /else/wheredebe ser un archivo normal).

Un montaje de enlace de Linux es en su mayoría indistinguible del original. El comando df -T /else/wheremuestra el mismo dispositivo y el mismo tipo de sistema de archivos que df -T /some/where. Los archivos /some/where/fooy /else/where/fooson indistinguibles, como si fueran enlaces duros. Es posible desmontar /some/where, en cuyo caso /else/wherepermanece montado.

Con núcleos más antiguos (no sé exactamente cuándo, creo que hasta algunos 3.x), los montajes de unión eran realmente indistinguibles del original. Los núcleos recientes rastrean los montajes de enlace y exponen la información a través de PID / mountinfo, que permite findmntindicar el montaje de enlace como tal .

Puede poner entradas de montaje de enlace /etc/fstab. Simplemente incluya bind(o rbindetc.) en las opciones, junto con cualquier otra opción que desee. El "dispositivo" es el árbol existente. La columna del sistema de archivos puede contener noneo bind(se ignora, pero usar un nombre de sistema de archivos sería confuso). Por ejemplo:

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

Si hay puntos de montaje debajo /some/where, su contenido no será visible debajo /else/where. En lugar de bind, puede usar rbind, también replicar puntos de montaje debajo /some/where. Por ejemplo, si /some/where/mntes un punto de montaje, entonces

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

es equivalente a

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

Además, Linux permite que los montajes se declaren como compartidos , esclavos , privados o no vinculables . Esto afecta si esa operación de montaje se refleja debajo de un montaje de enlace que replica el punto de montaje. Para más detalles, consulte la documentación del núcleo .

Linux también proporciona una forma de mover monturas: donde las --bindcopias --movemueven un punto de montaje.

Es posible tener diferentes opciones de montaje en dos directorios montados en enlace. Sin embargo, hay una peculiaridad: hacer que el montaje de enlace y establecer las opciones de montaje no se puedan hacer atómicamente, tienen que ser dos operaciones sucesivas. (Los núcleos más antiguos no permitían esto). Por ejemplo, los siguientes comandos crean una vista de solo lectura, pero hay una pequeña ventana de tiempo durante la cual /else/wherees de lectura y escritura:

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

¡No puedo conseguir monturas de unión para trabajar!

Si su sistema no admite FUSE, un truco clásico para lograr el mismo efecto es ejecutar un servidor NFS, hacer que exporte los archivos que desea exponer (permitiendo el acceso localhost) y montarlos en la misma máquina. Esto tiene una sobrecarga significativa en términos de memoria y rendimiento, por lo que los montajes de enlace tienen una ventaja definitiva cuando está disponible (que está en la mayoría de las variantes de Unix gracias a FUSE).

Casos de uso

Vista de solo lectura

Puede ser útil crear una vista de solo lectura de un sistema de archivos, ya sea por razones de seguridad o simplemente como una capa de seguridad para garantizar que no lo modificará accidentalmente.

Con bindfs:

bindfs -r /some/where /mnt/readonly

Con Linux, la forma simple:

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

Esto deja un breve intervalo de tiempo durante el cual /mnt/readonlyes lectura-escritura. Si esto es un problema de seguridad, primero cree el montaje de enlace en un directorio al que solo pueda acceder la raíz, hágalo de solo lectura y luego muévalo a un punto de montaje público. En el fragmento a continuación, tenga en cuenta que es importante que /root/private(el directorio sobre el punto de montaje) sea privado; los permisos originales en /root/private/mntson irrelevantes ya que están ocultos detrás del punto de montaje.

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

Reasignación de usuarios y grupos

Los sistemas de archivos registran usuarios y grupos por su ID numérico. A veces terminas con múltiples sistemas que asignan diferentes ID de usuario a la misma persona. Esto no es un problema con el acceso a la red, pero hace que las ID de los usuarios no tengan sentido cuando transporta datos de un sistema a otro en un disco. Suponga que tiene un disco creado con un sistema de archivos multiusuario (por ejemplo, ext4, btrfs, zfs, UFS, ...) en un sistema donde Alice tiene la identificación de usuario 1000 y Bob tiene la identificación de usuario 1001, y desea que ese disco sea accesible en un sistema donde Alice tiene la ID de usuario 1001 y Bob tiene la ID de usuario 1000. Si monta el disco directamente, los archivos de Alice aparecerán como propiedad de Bob (porque la ID de usuario es 1001) y los archivos de Bob aparecerán como propiedad de Alice (porque el ID de usuario es 1000).

Puede usar bindfs para reasignar ID de usuario. Primero monte la partición del disco en un directorio privado, donde solo la raíz puede acceder. Luego, cree una vista de bindfs en un área pública, con la reasignación de ID de usuario e ID de grupo que intercambie las ID de usuario e ID de grupo de Alice y Bob.

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

Consulte ¿Cómo se accede de manera permisible a los archivos en la carpeta de inicio del usuario del sistema sin arranque? y montar: vincular a otro usuario como a mí mismo otros ejemplos.

Montaje en una cárcel o contenedor

Una cárcel o contenedor chroot ejecuta un proceso en un subárbol del árbol de directorios del sistema. Esto puede ser útil para ejecutar un programa con acceso restringido, por ejemplo, ejecutar un servidor de red con acceso solo a sus propios archivos y a los archivos que sirve, pero no a otros datos almacenados en la misma computadora). Una limitación de chroot es que el programa está limitado a un subárbol: no puede acceder a subárboles independientes. Las monturas de unión permiten injertar otros subárboles en ese árbol principal. Esto los hace fundamentales para el uso más práctico de contenedores en Linux.

Por ejemplo, suponga que una máquina ejecuta un servicio /usr/sbin/somethingdque solo debería tener acceso a los datos en /var/lib/something. El árbol de directorios más pequeño que contiene ambos archivos es la raíz. ¿Cómo se puede limitar el servicio? Una posibilidad es hacer enlaces duros a todos los archivos que necesita el servicio (al menos /usr/sbin/somethingdy varias bibliotecas compartidas) /var/lib/something. Pero esto es engorroso (los enlaces duros necesitan actualizarse cada vez que se actualiza un archivo), y si no funciona /var/lib/somethingy /usrse encuentran en diferentes sistemas de ficheros. Una mejor solución es crear una raíz ad hoc y llenarla con monturas:

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 &

Los espacios de nombres de montaje de Linux generalizan chroots. Los montajes de enlace son cómo los espacios de nombres se pueden completar de forma flexible. Consulte Hacer que un proceso lea un archivo diferente para el mismo nombre de archivo para obtener un ejemplo.

Ejecutando una distribución diferente

Otro uso de chroots es instalar una distribución diferente en un directorio y ejecutar programas desde él, incluso cuando requieren archivos en rutas codificadas que no están presentes o tienen contenido diferente en el sistema base. Esto puede ser útil, por ejemplo, para instalar una distribución de 32 bits en un sistema de 64 bits que no admite paquetes mixtos, para instalar versiones anteriores de una distribución u otras distribuciones para probar la compatibilidad, para instalar una versión más nueva para probar las últimas características manteniendo un sistema base estable, etc. Vea ¿Cómo ejecuto programas de 32 bits en un Debian / Ubuntu de 64 bits? para un ejemplo en Debian / Ubuntu.

Suponga que tiene una instalación de los últimos paquetes de su distribución en el directorio /f/unstable, donde ejecuta programas cambiando a ese directorio con chroot /f/unstable. Para hacer que los directorios de inicio estén disponibles desde estas instalaciones, bind montarlos en el chroot:

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

El programa schroot hace esto automáticamente.

Acceso a archivos ocultos detrás de un punto de montaje

Cuando monta un sistema de archivos en un directorio, esto oculta lo que hay detrás del directorio. Los archivos en ese directorio quedan inaccesibles hasta que se desmonta el directorio. Debido a que los montajes de enlace BSD nullfs y Linux operan a un nivel más bajo que la infraestructura de montaje, un montaje nullfs o un montaje de enlace de un sistema de archivos expone directorios que estaban ocultos detrás de submontajes en el original.

Por ejemplo, suponga que tiene un sistema de archivos tmpfs montado en /tmp. Si había archivos debajo /tmpcuando se creó el sistema de archivos tmpfs, estos archivos aún pueden permanecer, efectivamente inaccesibles pero ocupando espacio en disco. correr

mount --bind / /mnt

(Linux) o

mount -t nullfs / /mnt

(FreeBSD) para crear una vista del sistema de archivos raíz en /mnt. El directorio /mnt/tmpes el del sistema de archivos raíz.

Exportaciones NFS en diferentes caminos

Algunos servidores NFS (como el servidor NFS del kernel de Linux antes de NFSv4) siempre anuncian la ubicación real del directorio cuando exportan un directorio. Es decir, cuando un cliente lo solicita server:/requested/location, el servidor sirve el árbol en la ubicación /requested/location. A veces es deseable permitir que los clientes soliciten, /request/locationpero en realidad sirven archivos bajo /actual/location. Si su servidor NFS no es compatible con una ubicación alternativa, puede crear un montaje de enlace para la solicitud esperada, por ejemplo

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

en /etc/exportsy lo siguiente en /etc/fstab:

/actual/location /requested/location bind bind

Un sustituto de enlaces simbólicos

A veces le gustaría hacer un enlace simbólico para que /some/where/is/my/fileaparezca un archivo /else/where, pero la aplicación que usa fileexpande los enlaces simbólicos y los rechaza /some/where/is/my/file. Un enlace sin montura puede evitar esto: bind-montaje /some/where/is/mya /else/where/is/my, y luego realpathinformará /else/where/is/my/filea estar bajo /else/where, no bajo /some/where.

Efectos secundarios de las monturas de unión

Recorridos recursivos de directorios

Si utiliza montajes de enlace, debe ocuparse de las aplicaciones que atraviesan el árbol del sistema de archivos de forma recursiva, como las copias de seguridad y la indexación (por ejemplo, para construir una base de datos de localización ).

Por lo general, los montajes de enlace deben excluirse de los recorridos recursivos de directorios, de modo que cada árbol de directorios solo se recorra una vez, en la ubicación original. Con bindfs y nullfs, configure la herramienta transversal para ignorar estos tipos de sistema de archivos, si es posible. Los montajes de enlace de Linux no pueden reconocerse como tales: la nueva ubicación es equivalente a la original. Con los montajes de enlace de Linux, o con herramientas que solo pueden excluir rutas y no tipos de sistemas de archivos, debe excluir los puntos de montaje para los montajes de enlace.

Recorridos que se detienen en las fronteras del sistema de archivos (por ejemplo find -xdev, rsync -x, du -x, ...) se detendrán automáticamente cuando se encuentran con un bindfs o nullfs punto de montaje, debido a que el punto de montaje es un sistema de archivos diferente. Con los montajes de enlace de Linux, la situación es un poco más complicada: hay un límite de sistema de archivos solo si el montaje de enlace está injertando un sistema de archivos diferente, no si está injertando otra parte del mismo sistema de archivos.

Ir más allá de las monturas de unión

Los montajes de enlace proporcionan una vista de un árbol de directorios en una ubicación diferente. Exponen los mismos archivos, posiblemente con diferentes opciones de montaje y (con bindfs) diferentes propiedades y permisos. Los sistemas de archivos que presentan una vista alterada de un árbol de directorios se denominan sistemas de archivos superpuestos o sistemas de archivos apilables . Hay muchos otros sistemas de archivos superpuestos que realizan transformaciones más avanzadas. Aquí hay algunos comunes. Si su caso de uso deseado no está cubierto aquí, consulte el repositorio de los sistemas de archivos FUSE .

Filtrar archivos visibles

  • clamfs : ejecuta archivos a través de un antivirus cuando se leen
  • filterfs : oculta partes de un sistema de archivos
  • rofs : una vista de solo lectura. Similar a bindfs -r, solo un poco más liviano.
  • Montajes de unión : presente varios sistemas de archivos (llamados ramas ) en un solo directorio: si tree1contiene fooy tree2contiene, barentonces su vista de unión contiene ambos fooy bar. Los nuevos archivos se escriben en una rama específica, o en una rama elegida de acuerdo con reglas más complejas. Hay varias implementaciones de este concepto, que incluyen:

    • aufs : implementación del kernel de Linux, pero rechazada muchas veces
    • funionfs - implementación FUSE
    • mhddfs - FUSE, escribe archivos en una rama en función del espacio libre
    • overlay : implementación del kernel de Linux, fusionado en sentido ascendente en Linux v3.18
    • unionfs-fuse - FUSE, con funciones de almacenamiento en caché y copia en escritura

Modificar nombres de archivo y metadatos

  • ciopfs : nombres de archivo que no distinguen entre mayúsculas y minúsculas (pueden ser útiles para montar sistemas de archivos de Windows)
  • convmvfs - convierte nombres de archivo entre conjuntos de caracteres ( ejemplo )
  • posixovl : almacena nombres de archivos de Unix y otros metadatos (permisos, propiedad, ...) en sistemas de archivos más restringidos como VFAT ( ejemplo )

Ver contenido alterado del archivo

Modificar la forma en que se almacena el contenido

  • chironfs : replica los archivos en el almacenamiento subyacente múltiple ( RAID-1 en el nivel del árbol de directorios )
  • copyfs : guarda copias de todas las versiones de los archivos
  • encfs - cifrar archivos
  • pcachefs : capa de caché en disco para sistemas de archivos remotos lentos
  • simplecowfs : almacena los cambios a través de la vista proporcionada en la memoria, dejando intactos los archivos originales
  • wayback : guarde copias de todas las versiones de los archivos
Gilles
fuente
1
es posible que desee agregar un ejemplo de cómo hacerlo con systemd: utcc.utoronto.ca/~cks/space/blog/linux/SystemdBindMountUnits
dothebart
1
¿Qué mount --bind /dir1 /dir1hacer? ¿Cómo es diferente del caso en que la fuente y el destino del montaje son diferentes?
Mark
No vi ningún registro en / proc / self / mountinfo, usando linux 5.0. El núcleo no me dice que es Bind Mount o no. Y un proceso puede romper fácilmente chroot, el aislamiento debe hacerse mediante el espacio de nombres de montaje.
炸鱼 薯条 德里克
@ 炸鱼 薯条 德里克 Creo que la pregunta vinculada direcciones unix.stackexchange.com/questions/295525/…/proc/self/mountinfo . En cuanto a chroot, se puede usar para aislamiento, pero no por sí solo. Sin embargo, no necesita montar espacios de nombres: chroot es suficiente para la parte del espacio de nombres del sistema de archivos. Debe asegurarse de que ningún proceso en el chroot se ejecute como el mismo usuario que un proceso fuera del chroot.
Gilles
@Mark Bind-montar un directorio en sí mismo no es muy útil. Supongo que podría usarlo para ocultar sistemas de archivos montados en un determinado directorio, pero no puedo pensar en un momento en que quisiera hacer eso específicamente.
Gilles
-1

Simple, cuando usa bind mount, un archivo o directorio en la máquina host se monta en un contenedor, por lo que cualquier cambio realizado dentro del directorio de archivos en la máquina host estará automáticamente disponible dentro del contenedor en el directorio.

srinivas
fuente
Esa es una de las formas de usar una montura de unión, pero las monturas de unión en sí mismas no tienen nada que ver con los contenedores. Lo menciono en mi respuesta, pero bajo el nombre de "cárcel" en lugar de "contenedor"; agregar "contenedor" sería una edición valiosa (lo haré). Esta también es una descripción pobre: ​​¿por qué mencionar que los cambios realizados en el exterior también están disponibles en el interior sin mencionar lo contrario?
Gilles