上次我检查时,Docker没有任何方法让容器访问主机串行或USB端口。有什么技巧可以做到吗?
当前回答
--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,并且将不允许访问容器。
其他回答
有几个选择。你可以使用——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是不安全的,应该小心处理。
--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中,你可以使用——device标志来实现你想要的,而不需要访问所有的USB设备。
例如,如果你想在Docker容器中只使/dev/ttyUSB0可访问,你可以这样做:
docker run -t -i --device=/dev/ttyUSB0 ubuntu bash
还有一种更简单的共享usb设备的方法,没有——privileged标志。这样做:
Docker运行…——device=/dev/bus/usb——device=/dev/usb <container> .使用实例
我们很难将特定的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
也许会有帮助。
推荐文章
- 试图连接到https://index.docker.io时,网络超时
- 为每个Docker图像查找图层和图层大小
- 如何避免在为Python项目构建Docker映像时重新安装包?
- 如何用docker-compose更新现有图像?
- 如何在构建docker期间设置环境变量
- 拉访问拒绝存储库不存在或可能需要docker登录
- 如何在ENTRYPOINT数组中使用Docker环境变量?
- Docker:容器不断地重新启动
- Mac/OS X上的/var/lib/docker在哪里
- 如何用docker-compose标记docker图像
- 从环境文件中读入环境变量
- 禁用特定RUN命令的缓存
- 从Docker容器获取环境变量
- E: gnupg, gnupg2和gnupg1似乎没有安装,但是这个操作需要其中一个
- 如何从docker更改默认docker注册表。IO到我的私人注册表?