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?
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!
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.
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)