périphérique en boucle dans un conteneur Linux?

14

J'essaie d'utiliser un périphérique de boucle à l'intérieur d'un conteneur, pour monter un fichier image:

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

/dev/loop0 en effet n'existe pas, et

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

Comment puis-je faire fonctionner cela? Le conteneur a-t-il besoin d'une autorisation de groupe de contrôle qu'il pourrait ne pas avoir?

Johannes Ernst
la source

Réponses:

17

Si vous utilisez systemd-nspawn, démarrez votre conteneur avec le --capability=CAP_MKNODcommutateur de ligne de commande. Cela vous permettra de créer des nœuds de périphérique à l'intérieur de votre conteneur. Créez ensuite un périphérique de boucle comme celui-ci:

# mknod /dev/loop0 b 7 0

N'oubliez pas que ce périphérique de boucle est partagé avec l'hôte et y est également appelé /dev/loop0. Et qu'il est désormais possible d'accéder aux appareils hôtes si vous connaissez les nombres majeurs et mineurs. Il pourrait également y avoir d'autres conséquences auxquelles je n'ai pas pensé. Être averti.

Troels Folke
la source
Quelqu'un peut-il confirmer que cela --capability=CAP_MKNODfonctionne toujours? Pour moi, cela semble n'avoir aucun effet, je m'en sors Operation not permitted, et cet utilisateur et cet utilisateur aussi .
nh2
2
Je l'ai fait fonctionner maintenant, mais en plus de donner, --capability=CAP_MKNODj'ai dû définir DeviceAllow=block-loop rwmdans l'unité systemd-nspawn pour le faire fonctionner (j'ai eu cette idée d' ici ).
nh2
J'ai dû ajouter --device-cgroup-rule="b 7:* rmw"à docker runpour permettre un accès complet aux périphériques de bouclage (mais pas d'autres, car il n'y en a pas --privilege). Trouvé via docs.docker.com/edge/engine/reference/commandline/create/… et testé sur docker 18.06.1-ce (le document prétend ne s'appliquer qu'à Docker Edge)
RobM
9

Les périphériques en boucle sont fournis par un module du noyau. Par conséquent, vous avez besoin de privilèges spéciaux pour y accéder. Vous avez également besoin qu'ils soient exposés dans votre conteneur, ou vous devez créer manuellement les fichiers de l'appareil.

La réponse rapide

docker run --privileged=true ...

Une alternative

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

Cela fonctionne presque

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

Cependant, j'obtiens cette erreur:

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

Voir ce lien pour plus d' informations .


Remarque sur la page de manuel de systemd-nspawn:

systemd-nspawn limite l'accès aux différentes interfaces du noyau dans le conteneur en lecture seule, comme / sys, / proc / sys ou / sys / fs / selinux. Les interfaces réseau et l'horloge système ne peuvent pas être modifiées à partir du conteneur. Les nœuds de périphérique ne peuvent pas être créés. Le système hôte ne peut pas être redémarré et les modules du noyau peuvent ne pas être chargés à partir du conteneur.

Mat
la source