上次我检查时,Docker没有任何方法让容器访问主机串行或USB端口。有什么技巧可以做到吗?
当前回答
除了上面的答案,对于那些想要快速使用外部USB设备(HDD,闪存驱动器)在docker内部工作,而不使用特权模式的人:
在主机上找到你的设备的devpath:
sudo fdisk -l
您可以很容易地从列表中识别您的驱动器的容量。复制该路径(在下例中为/dev/sda2)。
Disque /dev/sda2 : 554,5 Go, 57151488 octets, 111624 secteurs
Unités : secteur de 1 × 512 = 512 octets
Taille de secteur (logique / physique) : 512 octets / 512 octets
taille d'E/S (minimale / optimale) : 512 octets / 512 octets
挂载这个devpath(最好是/media):
sudo mount <drive path> /media/<mount folder name>
然后你可以使用它作为docker运行的参数:
docker run -it -v /media/<mount folder name>:/media/<mount folder name>
或者在docker中合成volumes:
services:
whatevermyserviceis:
volumes:
- /media/<mount folder name>:/media/<mount folder name>
现在,当您运行并进入容器时,您应该能够访问容器中的驱动器/media/<挂载文件夹名>
免责声明:
这可能不适用于串行设备,如网络摄像头等。 我只对USB存储驱动器进行了测试。 如果您需要定期重新连接和断开设备,这 方法将会很烦人,并且除非重置挂载路径并重新启动容器,否则将无法工作。 我使用docker 17.06 +在文档中规定
其他回答
有几个选择。你可以使用——device标志,用户可以在没有——特权模式的情况下访问USB设备:
docker run -t -i --device=/dev/ttyUSB0 ubuntu bash
或者,假设您的USB设备在主机/dev/bus/usb上可用,并且驱动程序正在工作等,您可以使用特权模式和volumes选项将其挂载到容器中。例如:
docker run -t -i --privileged -v /dev/bus/usb:/dev/bus/usb ubuntu bash
注意,顾名思义,——privileged是不安全的,应该小心处理。
我想扩展已经给出的答案,包括对未使用/dev/bus/usb捕获的动态连接设备的支持,以及在使用Windows主机和boot2docker VM时如何使其工作。
如果你正在使用Windows,你需要在VirtualBox管理器中为你想要Docker访问的设备添加任何USB规则。为此,您可以通过以下命令停止虚拟机:
host:~$ docker-machine stop default
打开VirtualBox管理器,根据需要添加带有过滤器的USB支持。
启动boot2docker虚拟机:
host:~$ docker-machine start default
由于USB设备连接到boot2docker虚拟机,因此需要从该机器运行命令。打开虚拟机的终端,运行docker run命令:
host:~$ docker-machine ssh
docker@default:~$ docker run -it --privileged ubuntu bash
注意,当命令像这样运行时,只有以前连接的USB设备将被捕获。只有当您希望在容器启动后连接的设备上工作时,才需要volumes标志。在这种情况下,你可以使用:
docker@default:~$ docker run -it --privileged -v /dev:/dev ubuntu bash
注意,在某些情况下,我必须使用/dev而不是/dev/bus/usb来捕获像/dev/sg2这样的设备我只能假设对于/dev/ttyACM0或/dev/ ttyusb0这样的设备也是如此。
docker运行命令也可以在Linux主机上运行。
还有一种更简单的共享usb设备的方法,没有——privileged标志。这样做:
Docker运行…——device=/dev/bus/usb——device=/dev/usb <container> .使用实例
--device works until your USB device gets unplugged/replugged and then it stops working. You have to use cgroup devices.allow get around it. You could just use -v /dev:/dev but that's unsafe as it maps all the devices from your host into the container, including raw disk devices and so forth. Basically this allows the container to gain root on the host, which is usually not what you want. Using the cgroups approach is better in that respect and works on devices that get added after the container as started.
在Docker中访问USB设备而不使用——特权
这有点难粘贴,但简而言之,你需要获得你的角色设备的主编号,并将其发送到cgroup:
188是/dev/ttyUSB*的主编号,可以通过'ls -l'获得。你的系统和我的系统可能不同:
root@server:~# echo 'c 188:* rwm' > /sys/fs/cgroup/devices/docker/$A*/devices.allow
(A contains the docker containerID)
然后像这样启动你的容器:
docker run -v /dev/bus:/dev/bus:ro -v /dev/serial:/dev/serial:ro -i -t --entrypoint /bin/bash debian:amd64
如果不这样做,容器启动后任何新插入或重新启动的设备将获得一个新的总线ID,并且将不允许访问容器。
如果你想在docker容器已经运行时动态地访问可以插入的USB设备,例如在/dev/video0上访问一个附加的USB摄像头,你可以在启动容器时添加一个cgroup规则。该选项不需要——特权容器,只允许访问特定类型的硬件。
步骤1
检查您想要添加的设备类型的设备主编号。您可以在linux内核文档中查找它。或者你可以检查你的设备。例如,要检查连接到/dev/video0的网络摄像头的设备主设备号,可以执行ls -la /dev/video0。结果如下:
crw-rw----+ 1 root video 81, 0 Jul 6 10:22 /dev/video0
其中第一个数字(81)是设备主设备号。一些常见的设备主号:
81: usb网络摄像头 188: usb到串行转换器
步骤2
在启动docker容器时添加规则:
添加——device-cgroup-rule='c major_number:* rmw'规则用于您想要访问的每种类型的设备 增加对udev信息的访问,这样docker容器就可以通过-v /run/udev:/run/udev:ro来获取usb设备上的更多信息 使用-v /dev:/dev将/dev卷映射到docker容器
总结
因此,要将所有usb网络摄像头和serial2usb设备添加到docker容器,请执行以下操作:
docker run -it -v /dev:/dev --device-cgroup-rule='c 188:* rmw' --device-cgroup-rule='c 81:* rmw' ubuntu bash
推荐文章
- 如何从DockerFile运行docker实例?
- 我是否试图连接到启用TLS的没有TLS的守护进程?
- Docker -一种访问主机USB或串行设备的方法?
- Docker:无效引用格式
- 将AWS凭证传递给Docker容器的最佳方法是什么?
- 如何在docker-compose中设置主机名?
- 为什么Docker容器映像这么大?
- 如何在docker撰写版本3中指定内存和CPU限制
- Docker和安全密码
- 如何让Docker容器在系统引导时自动启动?
- 如何在Docker容器中用模式初始化MySQL数据库?
- PYTHONUNBUFFERED在docker文件中的用途是什么?
- 如何在Dockerfile CMD中使用变量?
- 将主机端口转发到docker容器
- “docker compose”与“docker-compose”的区别