Совместное использование устройств (веб-камера, USB-накопители и т.д.) С помощью Docker

Мне нужно обмениваться определенными устройствами с /dev на моей машине с хостом Linux с моими контейнерами докеров.

Флаг --privileged работает для совместного использования любых устройств в /dev, которые присутствуют в момент вызова docker run, но любые последующие добавленные или удаленные устройства не распространяются в контейнер.

Я попробовал docker run -v=/dev:/dev ..., но это закончилось тем, что оно зависало с разрешениями и правами на файлы, такие как /dev/pts, что привело к тому, что хост-машина не смогла создать новые psuedo-терминалы.

Я также попробовал флаг --device, но это не позволяет вам совместно использовать устройство, которое еще не существует.

Наконец, я попробовал использовать тома для таких устройств, как -v=/dev/video0:/dev/video0, но если /dev/video 0 не существует перед запуском, docker создает там директорию, и веб-камера не будет принимать /dev/video 0 при подключении.

Есть ли лучший способ получить эту поддерживаемую функциональность?

Ответы

Ответ 1

Я думаю, что теоретически это возможно, используя флаг --privileged, поскольку эта вещь дает вам доступ ко всем устройствам хоста. Если вы устанавливаете usbutils или аналогичные (в зависимости от дистрибутива изображений), вы увидите, что привилегированный контейнер может видеть устройства с горячим подключением при запуске lsusb. К сожалению, хотя они не отображаются под /dev. Сценарии создания этих дескрипторов и их надлежащее управление вашим программным обеспечением под управлением /dev могут стать довольно запутанными, к сожалению. Однако это не должно быть для ваших устройств.

Что вы можете сделать в качестве первой попытки - просто создать их с помощью mknod. Я пробовал это с помощью своего телефона HTC, и он вроде как работал (подробности здесь не актуальны), просто проверьте строку для hotplugged устройства в lsusb:

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

перейдите в нужную папку для дескриптора:

cd /dev/bus/usb/003

проверьте основную версию драйвера usb в своем ядре из существующих дескрипторов:

[email protected]:/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:) = > создать кивок и при этом использовать младшую версию 0.

mknod 002 c 189 0

= > не менее lsusb -v теперь может открывать устройство. То же самое должно работать для большинства аппаратных imo, за некоторыми исключениями.

Что вы могли бы сделать в качестве альтернативы, хотя, возможно, медленнее, но, безусловно, безопаснее и более в духе Docker и контейнеризации, это использовать контейнеры для доступа к вашим устройствам при их горячей установке, а затем совместно использовать устройства с основным контейнером ваше видео приложение через socat tty через tcp.

Скажите, что у вас есть hotplug/dev/video0, вы можете создать новый контейнер, на котором установлено это устройство в этом случае. Этот контейнер (который имеет установленный язык) может работать:

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

Предполагая, что эта вещь имеет имя хоста video0-server, теперь вы можете создать дескриптор для видео0 на клиенте с помощью:

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

Теперь вы сможете использовать устройство просто отлично. Для многих устройств накладные расходы со стороны сообщества не должны быть проблемой, я думаю. Если сценарий это через несколько контейнеров, которые динамически взаимодействуют с вашим основным контейнером через сеть, является опцией, и производительность не влияет на какой-либо значимый способ также накладные расходы, последний вариант является более чистым и более безопасным, чем режим --privileged, на мой взгляд.

Ответ 2

Посмотрите флажок --device

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

Приятного дня!