Ejecuto un contenedor docker simple con sudo docker run -it ubuntu:latest /bin/bash
Cuando examino el sistema de archivos montado, con: df -h , uno
Filesystem Size Used Avail Use% Mounted on overlay 63G 4.3G 56G 8% / tmpfs 64M 0 64M 0% /dev tmpfs 1000M 0 1000M 0% /sys/fs/cgroup /dev/sda1 63G 4.3G 56G 8% /etc/hosts .... No entiendo la última línea, es decir, /dev/sda1 -> /etc/hosts , cuando ejecuto df -h en la máquina host, obtengo el montaje /dev/sda1 -> / .
Entonces /dev/sda1 es en realidad mi disco duro, ¿por qué está montado en /etc/hosts en el contenedor y cómo es que /etc/hosts en el contenedor es un archivo con el contenido correcto?
¿Alguna explicación de lo que está pasando aquí? ¿Cómo funciona esto?
Tiene dos preguntas en su publicación, déjeme cubrirlas secuencialmente.
1) ¿Por qué los archivos /etc/{hosts,hostname,resolv.conf} se montan desde el exterior?
Veo al menos una razón para esto.
Imagínese lo que sucedería si el motor del contenedor simplemente escribiera estos archivos en el sistema de archivos del contenedor y el usuario decidiera montar /etc como un volumen (lo cual es perfectamente legal y bastante útil; montar /etc le permitiría al usuario proporcionar al contenedor múltiples archivos de configuración en un argumento -v para la docker run ):
/etc del contenedor;/etc ). Después de iniciar este contenedor, el usuario intenta iniciar uno más con el mismo volumen de /etc (nuevamente, esto es perfectamente legal y útil; por ejemplo, el usuario escala algún servicio y comparte archivos de configuración en /etc entre instancias), y... El segundo contenedor sobrescribe los archivos hostname , hosts y resolv.conf en el volumen, lo que afecta al primer contenedor.
Ahora considere lo que sucede cuando se usa el montaje de enlace en lugar de las escrituras directas:
/etc del contenedor;/etc/{hosts,hostname,resolv.conf} desde algún lugar del host al sistema de archivos del contenedor; 2) ¿Por qué veo /dev/sda1 como la fuente de estos montajes?
Compruebe findmnt(8) en lugar de df(1) :
$ docker run -it ubuntu root@5a8ab4d6e716:/# findmnt TARGET SOURCE ... |-/etc/resolv.conf /dev/sda1[/var/lib/docker/containers/5a8ab4d6e71691f279cbbcf5a295b5fa90fd138f10418c996ad7ea4440452816/resolv.conf] |-/etc/hostname /dev/sda1[/var/lib/docker/containers/5a8ab4d6e71691f279cbbcf5a295b5fa90fd138f10418c996ad7ea4440452816/hostname] `-/etc/hosts /dev/sda1[/var/lib/docker/containers/5a8ab4d6e71691f279cbbcf5a295b5fa90fd138f10418c996ad7ea4440452816/hosts] En realidad, cada línea de salida aquí muestra tres campos (mount target /etc/hosts , mount source /dev/sda1 y FS root /var/lib/<...>/hosts ), y df(1) no muestra el tercero df(1) .
De acuerdo con el párrafo man procfs sobre el archivo /proc/PID/mountinfo (que es la fuente de información sobre montajes para utilidades):
(4) root: the pathname of the directory in the filesystem which forms the root of this mount. (5) mount point: the pathname of the mount point relative to the process's root directory. ... (10) mount source: filesystem-specific information or "none". Para la mayoría de los montajes, la raíz FS es / (porque monta todo el sistema de archivos), por lo que no pierde demasiada información cuando mira la salida df(1) . Sin embargo, este no es el caso de los montajes de enlace de archivos específicos.