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

时间:2015-12-16 00:39:40

标签: linux docker device

我需要在我的主机Linux机器上使用我的docker容器从/dev共享特定设备。

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

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

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

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

有没有更好的方法来获得这种支持的功能?

3 个答案:

答案 0 :(得分:14)

您正在查看国旗--device

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

度过美好的一天!

答案 1 :(得分:10)

我认为理论上可以确保使用--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

=&GT; 189 :) =&gt;创建点头,同时使用次要版本0。

mknod 002 c 189 0

=&GT;至少lsusb -v现在能够打开设备。对于大多数硬件imo,同样应该可以解决,但有一些例外。

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

在主机上说你hotplug / 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

现在你应该可以正常使用该设备了。对于许多设备,我认为社交开销不应成为问题。 如果通过网络与主容器动态通信的多个容器编写脚本是一个选项,性能也不会受到开销的任何有意义的影响,在我看来,后一个选项比--privileged模式更清晰,更安全

答案 2 :(得分:0)

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