dispositivo de loop em um contêiner Linux?

14

Estou tentando usar um dispositivo de loop dentro de um contêiner para montar algum arquivo de imagem:

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

/dev/loop0 na verdade não existe, e

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

Como posso fazer isso funcionar? O contêiner precisa de alguma permissão cgroup que talvez não tenha?

Johannes Ernst
fonte

Respostas:

17

Se você estiver usando systemd-nspawn, inicie seu contêiner com a --capability=CAP_MKNODopção de linha de comando. Isso permitirá que você crie nós de dispositivo dentro do seu contêiner. Em seguida, crie um dispositivo de loop como este:

# mknod /dev/loop0 b 7 0

Lembre-se de que este dispositivo de loop é compartilhado com o host e também é chamado /dev/loop0lá. E que agora é possível acessar dispositivos host se você souber os números maiores e menores. Também pode haver outras consequências nas quais eu não pensei. Esteja avisado.

Troels Folke
fonte
Alguém pode confirmar que --capability=CAP_MKNODainda funciona? Para mim, parece não ter efeito, eu me Operation not permittedigualo a ele, assim como esse usuário e esse usuário .
NH2
2
Eu consegui que funcionasse agora, mas, além de doar --capability=CAP_MKNOD, tive que instalar DeviceAllow=block-loop rwmna unidade systemd-nspawn para fazê-la funcionar (peguei essa ideia daqui ).
NH2
Eu tive que adicionar --device-cgroup-rule="b 7:* rmw"para docker runpermitir acesso total aos dispositivos de loopback (mas não a outros, pois não há --privilege). Encontrado através docs.docker.com/edge/engine/reference/commandline/create/... e testado em janela de encaixe 18.06.1-CE (o documento reivindicações para aplicar somente a borda de encaixe)
RobM
9

Os dispositivos de loop são fornecidos por um módulo do kernel. Portanto, você precisa de privilégios especiais para acessá-los. Você também precisa que eles sejam expostos ao seu contêiner ou precisa criar manualmente os arquivos do dispositivo.

A resposta rápida

docker run --privileged=true ...

Uma alternativa

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

Isso quase funciona

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

No entanto, recebo este erro:

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

Veja este link para mais informações .


Uma observação na página de manual systemd-nspawn:

systemd-nspawn limita o acesso a várias interfaces do kernel no contêiner para somente leitura, como / sys, / proc / sys ou / sys / fs / selinux. As interfaces de rede e o relógio do sistema não podem ser alterados de dentro do contêiner. Os nós do dispositivo não podem ser criados. O sistema host não pode ser reinicializado e os módulos do kernel podem não ser carregados de dentro do contêiner.

Matt
fonte