我认为理论上这肯定可以使用--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 :) => 创建点头,同时使用次要版本 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-server,你现在可以通过以下方式在客户端上为 video0 创建描述符:
socat pty,link=/dev/video0,waitslave tcp:video0-server:54321
现在您应该可以正常使用该设备了。对于许多设备,我认为 socat 开销应该不是问题。
如果通过多个通过网络与主容器动态通信的容器编写脚本是一个选项,并且开销也不会以任何有意义的方式影响性能,那么在我看来,后一个选项比--privileged 模式更干净、更安全。