与Docker共享设备(网络摄像头、USB驱动器等)



我需要将主机Linux机器上/dev的特定设备与docker容器共享。

--privileged标志用于共享/dev中在调用docker run时存在的任何设备,但任何随后添加或移除的设备都不会传播到容器中。

我尝试了docker run -v=/dev:/dev ...,但最终破坏了/dev/pts等文件的权限和所有权,导致主机无法创建新的psuedo终端。

我还尝试了--device标志,但它不允许您共享一个尚不存在的设备。

最后,我尝试为-v=/dev/video0:/dev/video0等设备共享卷,但如果/dev/video0在运行前不存在,docker会在那里创建一个目录,网络摄像头在插入时不会占用/dev/video0。

有什么更好的方法可以获得这种支持的功能吗?

您正在查看检查标志--device

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

祝你今天愉快!

我认为从理论上讲,使用--privileged标志肯定可以做到这一点,因为这使您能够访问所有主机设备。如果您安装usbutils或类似软件(取决于您的映像分发),您将看到特权容器在运行lsusb时能够看到热插拔设备。不幸的是,尽管它们没有显示在/dev下。不幸的是,编写这些描述符的创建脚本并让您的软件在/dev/下正确处理它们可能会变得相当复杂。不过,对于你的设备来说,不一定非得这样。

作为第一次尝试,您可以使用mknod创建它们。我用我的HTC手机尝试了一下,它有点起作用(这里没有相关的细节),只需在lsusb:中检查热插拔设备的线路

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

转到描述符的正确文件夹:

cd /dev/bus/usb/003

从现有描述符中检查内核中usb驱动程序的主要版本:

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:)=>创建nod,同时使用次要版本0。

mknod 002 c 189 0

=>现在至少lsusb -v能够打开设备。除了一些例外,大多数硬件imo也应该如此。

作为一种替代方案,尽管可能更慢,但肯定更安全,更符合Docker和容器化的精神,你可以在热安装设备时使用容器访问设备,然后通过socat tty和tcp与运行视频应用程序的主容器共享设备。

假设您在主机上热插拔/dev/video0,则可以启动一个新容器,在该事件中安装该设备。这个容器(安装了socat)可以运行:

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

假设这个东西的主机名是video0服务器,您现在可以通过在客户端上创建video0的描述符

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

现在你应该可以很好地使用这个设备了。我认为,对于许多设备来说,socat开销应该不是一个问题。如果可以选择通过多个容器编写脚本,这些容器通过网络与主容器动态通信,并且性能也不会受到开销的任何有意义的影响,那么在我看来,后一种选择比--privileged模式更干净、更安全。

在系统运行时很难放置设备(USB检测),您应该制作一个脚本,在找到设备时放置设备,并执行--rm(因此每次退出机器时都会删除设备,您有新的机会导入设备)

最新更新