符号链接USB设备接入Docker容器失败,/dev/ttyZigbee无法识别排查
主机上通过udev规则创建了USB设备的符号链接/dev/ttyZigbee,主机/dev目录下可见该链接及实际设备:
crw-rw---- 1 root dialout 166, 1 Nov 22 11:49 /dev/ttyACM1 lrwxrwxrwx 1 root root 15 Nov 22 11:49 /dev/ttyZigbee -> bus/usb/002/005
已通过dmesg确认驱动加载正常。使用以下命令创建zigbee2mqtt容器:
docker run -d --init \ -p 8090:8090 \ -e TZ='America/Toronto' \ -v /data/zigbee2mqtt/data:/app/data \ -v /run/udev:/run/udev:ro \ --name zigbee2mqtt \ --device=/dev/ttyZigbee \ docker.io/koenkk/zigbee2mqtt
容器启动后日志报错:
Zigbee2MQTT:error 2023-11-23 04:22:53: Error: Error while opening serialport 'Error: Error: No such file or directory, cannot open /dev/ttyZigbee'
疑问:设备无法直通到容器或无法打开的原因是什么?是否与符号链接、权限有关?
核心原因:符号链接路径指向问题
Docker的--device参数传入符号链接时,只会将链接文件本身挂载到容器内,但链接指向的bus/usb/002/005路径在容器文件系统中不存在(容器的/dev结构与主机独立),导致容器内解析符号链接时找不到目标设备。解决方法1:直接映射实际设备节点
放弃映射符号链接,直接映射实际的ttyACM1设备,同时在zigbee2mqtt的配置文件/data/zigbee2mqtt/data/configuration.yaml中指定设备路径为/dev/ttyACM1。修改后的docker启动命令:docker run -d --init \ -p 8090:8090 \ -e TZ='America/Toronto' \ -v /data/zigbee2mqtt/data:/app/data \ -v /run/udev:/run/udev:ro \ --name zigbee2mqtt \ --device=/dev/ttyACM1 \ docker.io/koenkk/zigbee2mqtt解决方法2:调整udev规则,让符号链接指向/dev下的tty设备
修改udev规则,让/dev/ttyZigbee直接指向/dev/ttyACM1而非bus/usb路径。例如,udev规则可改为:SUBSYSTEM=="tty", ATTRS{idVendor}=="xxxx", ATTRS{idProduct}=="xxxx", SYMLINK+="ttyZigbee"这样使用
--device=/dev/ttyZigbee时,Docker会自动解析符号链接到实际的ttyACM1设备并挂载到容器内,容器内就能正常访问/dev/ttyZigbee。权限排查(辅助步骤)
若调整映射后仍有问题,检查设备权限:主机上ttyACM1属于dialout组,可在启动命令中添加--user root临时测试(不建议长期使用),或修改容器内用户的组权限,确保其拥有设备访问权限。
内容的提问来源于stack exchange,提问作者TSG

