Dispositifs de partage (webcam, clés USB, etc) avec Docker

j'ai besoin de partager des appareils spécifiques de /dev sur ma machine Linux hôte avec mes conteneurs docker.

--privileged flag fonctionne pour partager tous les périphériques dans /dev qui sont présents à la fois docker run est appelé, mais les dispositifs ajoutés ou retirés ultérieurement ne se propagent pas dans le conteneur.

j'ai essayé docker run -v=/dev:/dev ... mais cela a fini par bousiller les permissions et la propriété de fichiers comme / dev / pts, ce qui a conduit la machine hôte à ne pas pouvoir créer nouveau pseudo-terminaux.

j'ai aussi essayé l' --device drapeau, mais qui ne permet pas de partager un périphérique qui n'existe pas encore.

enfin, j'ai essayé de partager des volumes pour des appareils comme -v=/dev/video0:/dev/video0 mais si /dev /video0 n'existe pas avant l'exécution, docker y crée un répertoire et une webcam ne prendra pas/dev / video0 lorsqu'elle est branchée.

Est-il une meilleure manière d'obtenir cette fonctionnalité prise en charge?

20
demandé sur Ryan 2015-12-16 03:39:39

3 réponses

Vous êtes à la recherche vérifiez l'indicateur --device

   --device=[]
      Add a host device to the container (e.g. --device=/dev/sdc:/dev/xvdc:rwm)

bonne journée!

11
répondu Auzias 2015-12-16 06:28:44

je pense qu'en théorie c'est possible en utilisant le --privileged drapeau, que cette chose vous donne la possibilité d'accéder à tous les périphériques hôtes. Si vous installez usbutils ou similaire (selon votre Distribution d'images), vous verrez que le conteneur privilégié est capable de voir des périphériques hotplugged lors de l'exécution lsusb. Malheureusement, bien qu'ils ne se présentent pas sous /dev. Scripting la création de ces descripteurs et de les avoir correctement manipulés par votre logiciel sous / dev peut devenir équitable impliqués malheureusement. Il n'a pas à être de cette façon pour vos appareils.

ce que vous pouvez faire comme première tentative est de simplement les créer en utilisant mknod. J'ai essayé avec mon téléphone HTC et ça a fonctionné (détails non pertinents ici ), il suffit de vérifier la ligne pour le périphérique hotplugged en lsusb:

Bus 003 Device 002: ID 0bb4:0f25 HTC (High Tech Computer Corp.) One M8

allez dans le bon dossier pour le descripteur:

cd /dev/bus/usb/003

vérifiez la version principale pour le pilote usb dans votre noyau à partir de la version existante descripteurs:

root@1a11f7c329a9:/dev/bus/usb/003# ls -la
total 0
drwxr-xr-x 2 root root      160 Dec 26 13:40 .
drwxr-xr-x 6 root root      120 Dec 26 13:30 ..
crw-rw-r-- 1 root root 189, 256 Dec 26 13:30 001
crw-rw-r-- 1 root root 189, 258 Dec 26 13:30 003
crw-rw-r-- 1 root root 189, 259 Dec 26 13:30 004
crw-rw-r-- 1 root root 189, 260 Dec 26 13:30 005
crw-rw-r-- 1 root root 189, 261 Dec 26 13:30 006

=> 189 :) => créez le nod et utilisez la version mineure 0.

mknod 002 c 189 0

=> au moins lsusb -v est maintenant capable d'ouvrir l'appareil. Il devrait en être de même pour la plupart du matériel imo, à quelques exceptions près.

ce que vous pourriez faire comme alternative, bien que peut-être plus lent mais certainement plus sûr et plus dans l'esprit de Docker et containerization est d'utiliser des conteneurs pour accéder à vos appareils lorsque vous les monter à chaud et puis partagez les périphériques avec le conteneur principal qui exécute votre application vidéo via socat tty via tcp.

dites que vous hotplug / dev / video0 sur l'hôte, vous pouvez lancer un nouveau conteneur qui a ce périphérique monté dans cet événement. Ce conteneur (que socat a installé ) pourrait fonctionner:

socat tcp-l:54321,reuseaddr,fork file:/dev/video0,nonblock,waitlock=/var/run/video0.lock

en supposant que cette chose a le nom d'hôte video0-server vous pouvez maintenant créer le descripteur pour video0 sur le client via:

socat pty,link=/dev/video0,waitslave tcp:video0-server:54321

Maintenant, vous devriez être en mesure d'utiliser l'appareil l'amende juste. Pour de nombreux appareils, la socat overhead ne devrait pas être un problème, je pense. Si le script via plusieurs conteneurs qui communiquent dynamiquement avec votre conteneur principal via le réseau est une option et que les performances ne sont pas affectées de manière significative par la surcharge aussi, cette dernière option est plus propre et plus sûre que --privileged mode à mon avis.

10
répondu Armin Braun 2015-12-26 14:15:16

il est difficile de placer le périphérique lorsque le système est en cours d'exécution (détection USB) vous devriez faire un script pour placer les périphériques comme ils sont trouvés et faire le --rm (donc chaque fois que vous sortez de la machine est retiré, et vous avez une nouvelle chance d'importer les périphériques)

0
répondu Kiko Albiol Colomer 2018-03-09 18:52:23