现象
在容器启动之前插入USB相机,在容器内能正确识别和访问,然后热插拔相机,或者相机重启,或者容器启动后在插入的相机,相机均无法识别,表现为可以扫到该设备,但是不能打开该设备,查找设备经过的端口号也会失败。
分析处理
version: "3.0"
services:
ros:
image: ros_in_docker/noetic:${CONTAINER_NAME:-noetic}
user: ${USER_NAME:-user}
network_mode: "host"
environment:
- DISPLAY=$DISPLAY
- UDEV=1
privileged: true # 给与容器访问权限
devices:
- '/dev/:/dev' # 映射/dev目录,旨在让/dev的变动直接同步到容器中
volumes:
- ${ROS_BAGS:-/dev/tmp}:/home/user/ros_ws/bags/:ro
- /tmp/.X11-unix:/tmp/.X11-unix
- /run/user/1000/gdm/Xauthority:/home/user/.Xauthority
- /etc/timezone:/etc/timezone:ro
- /etc/localtime:/etc/localtime:ro
- /home/ccc/asdfg/foo/data:/data
这个配置的问题在于 privileged 只给了容器启动前的host的/dev下设备的访问权限,热插拔的设备,容器没有对应的访问权限
修改方案:
device_cgroup_rules:
- 'a *:* rmw' # 给与全部访问权限,这个权限和privileged不同的是,动态创建设备的权限同样也会被给与
volumes: # 挂载/dev/bus/usb 目录,使得动态创建的设备能被容器看见
- type: bind # bind host usb-devices to container, using mount command, DO NOT modify.
source: /dev/bus/usb # host source
target: /dev/bus/usb # container target
- /run/udev/control:/run/udev/control # 映射udev control 文件,使得hostplug的事件能通知到容器,该文件可以理解为和系统服务udev 沟通的口子
修改完成,重启验证OK