上次我检查时,Docker没有任何方法让容器访问主机串行或USB端口。有什么技巧可以做到吗?
当前回答
还有一种更简单的共享usb设备的方法,没有——privileged标志。这样做:
Docker运行…——device=/dev/bus/usb——device=/dev/usb <container> .使用实例
其他回答
在当前版本的Docker中,你可以使用——device标志来实现你想要的,而不需要访问所有的USB设备。
例如,如果你想在Docker容器中只使/dev/ttyUSB0可访问,你可以这样做:
docker run -t -i --device=/dev/ttyUSB0 ubuntu bash
我们很难将特定的USB设备绑定到同样特定的docker容器上。如你所见,推荐的实现方式是:
docker run -t -i --privileged -v /dev/bus/usb:/dev/bus/usb ubuntu bash
它将把所有设备绑定到这个容器。它是不安全的。每个集装箱都被授予操作所有这些。
另一种方法是通过devpath绑定设备。它可能看起来像:
docker run -t -i --privileged -v /dev/bus/usb/001/002:/dev/bus/usb/001/002 ubuntu bash
或者——device(最好没有特权):
docker run -t -i --device /dev/bus/usb/001/002 ubuntu bash
更安全。但实际上很难知道特定设备的devpath是什么。
我写了这个repo来解决这个问题。
https://github.com/williamfzc/usb2container
部署此服务器后,您可以通过HTTP请求轻松获得所有连接设备的信息:
curl 127.0.0.1:9410/api/device
并获得:
{
"/devices/pci0000:00/0000:00:14.0/usb1/1-13": {
"ACTION": "add",
"DEVPATH": "/devices/pci0000:00/0000:00:14.0/usb1/1-13",
"DEVTYPE": "usb_device",
"DRIVER": "usb",
"ID_BUS": "usb",
"ID_FOR_SEAT": "xxxxx",
"ID_MODEL": "xxxxx",
"ID_MODEL_ID": "xxxxx",
"ID_PATH": "xxxxx",
"ID_PATH_TAG": "xxxxx",
"ID_REVISION": "xxxxx",
"ID_SERIAL": "xxxxx",
"ID_SERIAL_SHORT": "xxxxx",
"ID_USB_INTERFACES": "xxxxx",
"ID_VENDOR": "xxxxx",
"ID_VENDOR_ENC": "xxxxx",
"ID_VENDOR_FROM_DATABASE": "",
"ID_VENDOR_ID": "xxxxx",
"INTERFACE": "",
"MAJOR": "189",
"MINOR": "119",
"MODALIAS": "",
"PRODUCT": "xxxxx",
"SEQNUM": "xxxxx",
"SUBSYSTEM": "usb",
"TAGS": "",
"TYPE": "0/0/0",
"USEC_INITIALIZED": "xxxxx",
"adb_user": "",
"_empty": false,
"DEVNAME": "/dev/bus/usb/001/120",
"BUSNUM": "001",
"DEVNUM": "120",
"ID_MODEL_ENC": "xxxxx"
},
...
}
把它们绑在你的容器上。例如,您可以看到该设备的DEVNAME为/dev/bus/usb/001/120:
docker run -t -i --device /dev/bus/usb/001/120 ubuntu bash
也许会有帮助。
我想扩展已经给出的答案,包括对未使用/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> .使用实例
除了上面的答案,对于那些想要快速使用外部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 +在文档中规定
推荐文章
- E: gnupg, gnupg2和gnupg1似乎没有安装,但是这个操作需要其中一个
- 如何从docker更改默认docker注册表。IO到我的私人注册表?
- Docker- compose无法连接到Docker Daemon
- 单个命令停止和删除docker容器
- 使用GPU从docker容器?
- 如何使用本地映像作为dockerfile的基本映像?
- 谁能解释一下docker.sock
- 多重from是什么意思
- 通过映像名称停止Docker容器- Ubuntu
- 如果dockerfile的名称不是dockerfile,我如何构建一个dockerfile ?
- 守护进程的错误响应:已被集装箱使用"
- 如何从DockerFile运行docker实例?
- 我是否试图连接到启用TLS的没有TLS的守护进程?
- Docker -一种访问主机USB或串行设备的方法?
- Docker:无效引用格式