我需要/dev
使用我的docker容器在我的主机Linux机器上共享特定设备.
该--privileged
标志用于共享/dev
当时存在的任何设备docker run
,但随后添加或删除的任何设备都不会传播到容器中.
我试过docker run -v=/dev:/dev ...
但最终搞砸了/ dev/pts等文件的权限和所有权,导致主机无法创建新的伪终端.
我也试过了--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:)=>创建点头,同时使用次要版本0.
mknod 002 c 189 0
=>至少lsusb -v
现在能够打开设备.对于大多数硬件imo,同样应该可以解决,但有一些例外.
您可以做什么作为替代方案,虽然可能更慢但更安全,更符合Docker和容器化的精神,就是在热安装时使用容器访问您的设备,然后与运行视频应用程序的主容器共享设备通过tcp通过socat tty.
假设您在主机上热插拔/ 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
,我认为后一种选择比模式更清晰,更安全.