dispositivo de bucle en un contenedor de Linux?

14

Estoy tratando de usar un dispositivo de bucle dentro de un contenedor, para montar algún archivo de imagen:

> sudo losetup /dev/loop0 test.img
losetup: /dev/loop0: failed to set up loop device: No such file or directory

/dev/loop0 de hecho no existe, y

> sudo mknod /dev/loop0 b 7 0
mknod: ‘/dev/loop0’: Operation not permitted

¿Cómo puedo hacer que esto funcione? ¿El contenedor necesita algún permiso de cgroup que podría no tener?

Johannes Ernst
fuente

Respuestas:

17

Si está usando systemd-nspawn, inicie su contenedor con el --capability=CAP_MKNODinterruptor de línea de comando. Esto le permitirá crear nodos de dispositivo dentro de su contenedor. Luego cree un dispositivo de bucle como este:

# mknod /dev/loop0 b 7 0

Recuerde que este dispositivo de bucle se comparte con el host y también se llama /dev/loop0allí. Y que ahora es posible acceder a los dispositivos host si conoce los números mayores y menores. También podría haber otras consecuencias en las que no he pensado. Ten cuidado.

Troels Folke
fuente
¿Alguien puede confirmar que --capability=CAP_MKNODtodavía funciona? Para mí parece no tener ningún efecto, me pongo a la Operation not permittedpar con él, y también lo hacen este usuario y este usuario .
nh2
2
Lo puse a trabajar ahora, pero además de darlo --capability=CAP_MKNOD, tuve que configurar DeviceAllow=block-loop rwmla unidad systemd-nspawn para que funcionara (obtuve esa idea de aquí ).
nh2
Tuve que agregar --device-cgroup-rule="b 7:* rmw"para docker runpermitir el acceso completo a los dispositivos de bucle invertido (pero no a otros, ya que no hay --privilege). Encontrado a través de docs.docker.com/edge/engine/reference/commandline/create/… y probado en docker 18.06.1-ce (el documento afirma que solo se aplica a Docker Edge)
RobM
9

Los dispositivos de bucle son proporcionados por un módulo del núcleo. Por lo tanto, necesita privilegios especiales para acceder a ellos. También necesita que estén expuestos en su contenedor, o necesita crear manualmente los archivos del dispositivo.

La respuesta rápida

docker run --privileged=true ...

Una alternativa

sudo losetup /dev/loop0 test.img
mount /dev/loop0 /mnt
docker run -v /mnt:/mnt ...

Esto casi funciona

docker run --device=/dev/loop-control:/dev/loop-control --device=/dev/loop0:/dev/loop0 --cap-add SYS_ADMIN ...

Sin embargo me sale este error:

root@5c033d5f8625:/# sudo mount /dev/loop0 /mnt
mount: block device /dev/loop0 is write-protected, mounting read-only
mount: cannot mount block device /dev/loop0 read-only

Vea este enlace para más información .


Una nota en la página del manual systemd-nspawn:

systemd-nspawn limita el acceso a varias interfaces del kernel en el contenedor a solo lectura, como / sys, / proc / sys o / sys / fs / selinux. Las interfaces de red y el reloj del sistema no se pueden cambiar desde el contenedor. Nodos de dispositivo no pueden ser creados. El sistema host no se puede reiniciar y los módulos del kernel no se pueden cargar desde el contenedor.

Mate
fuente