Docker 从Azure IoT边缘模块实现Raspberry Pi GPIO

Docker 从Azure IoT边缘模块实现Raspberry Pi GPIO,docker,raspberry-pi,node-red,azure-iot-edge,Docker,Raspberry Pi,Node Red,Azure Iot Edge,我有一个简单的Node-RED项目示例,在这个项目中,我试图在一个运行Raspberry Pi的Buster上与一些GPIO交互。如果我直接在Pi上运行该项目,它工作得很好。如果我通过Azure IoT Edge部署将其作为一个模块运行,我将无法与相同的GPIO交互,即使我已使用这些容器创建选项进行部署 { "HostConfig": { "PortBindings": { "1880/tcp": [ { "HostPort": "80

我有一个简单的Node-RED项目示例,在这个项目中,我试图在一个运行Raspberry Pi的Buster上与一些GPIO交互。如果我直接在Pi上运行该项目,它工作得很好。如果我通过Azure IoT Edge部署将其作为一个模块运行,我将无法与相同的GPIO交互,即使我已使用这些容器创建选项进行部署

{
  "HostConfig": {
    "PortBindings": {
      "1880/tcp": [
        {
          "HostPort": "80"
        }
      ]
    },
    "Privileged": true
  }
}
…来自Docker Hub上的
/kpmartinhfi/gpio poc:latest
,使用
Docker buildx构建--平台linux/arm/v7-t kpmartinhfi/gpio poc:latest构建--按

设备上的Node RED editor UI可在:80处访问,因此基本上可以正常工作,但尝试使用GPIO时会出现访问/权限错误:

16 Sep 19:21:33 - [info] Starting flows
16 Sep 19:21:33 - [info] Started flows
16 Sep 19:21:33 - [info] [rpi-gpio out:Buzzer (GPIO20)] err: Traceback (most recent call last):
  File "/usr/src/node-red/node_modules/@node-red/nodes/core/hardware/nrgpio.py", line 84, in <module>
 :
16 Sep 19:21:33 - [info] [rpi-gpio out:Buzzer (GPIO20)] err:     GPIO.setup(pin,GPIO.OUT)
RuntimeError: No access to /dev/mem.  Try running as root!
 :
16 Sep 19:21:33 - [info] [rpi-gpio out:Relay (GPIO26)] err: Traceback (most recent call last):
  File "/usr/src/node-red/node_modules/@node-red/nodes/core/hardware/nrgpio.py", line 84, in <module>
    GPIO.setup(pin,GPIO.OUT)
RuntimeError: No access to /dev/mem.  Try running as root!
 :
16 Sep 19:21:33 - [info] [rpi-gpio out:Buzzer (GPIO20)] closed
16 Sep 19:21:33 - [info] [rpi-gpio out:Relay (GPIO26)] closed
16 Sep 19:21:33 - [info] [rpi-gpio out:Relay (GPIO16)] err: Traceback (most recent call last):
  File "/usr/src/node-red/node_modules/@node-red/nodes/core/hardware/nrgpio.py", line 84, in <module>
 :
16 Sep 19:21:33 - [info] [rpi-gpio out:Relay (GPIO16)] err:     GPIO.setup(pin,GPIO.OUT)
RuntimeError: No access to /dev/mem.  Try running as root!
 :
16 Sep 19:21:33 - [info] [rpi-gpio out:Relay (GPIO16)] closed
16 Sep 19:21:36 - [info] [rpi-gpio out:Relay (GPIO16)] out: 0
16 Sep 19:21:36 - [error] [rpi-gpio out:Relay (GPIO16)] nrpgio python command not running
16 Sep 19:21:37 - [info] [rpi-gpio out:Relay (GPIO16)] out: 1
16 Sep 19:21:37 - [error] [rpi-gpio out:Relay (GPIO16)] nrpgio python command not running
16 Sep 19:21:33-[info]启动流程
9月16日19:21:33-[信息]已启动流
9月16日19:21:33-[信息][rpi gpio输出:蜂鸣器(GPIO20)]错误:回溯(最近一次呼叫最后一次):
文件“/usr/src/node red/node_modules/@node red/nodes/core/hardware/nrgpio.py”,第84行,在
:
9月16日19:21:33-[信息][rpi gpio输出:蜂鸣器(GPIO20)]错误:gpio.setup(pin,gpio.out)
运行时错误:无法访问/dev/mem。尝试以root用户身份运行!
:
9月16日19:21:33-[info][rpi gpio out:Relay(GPIO26)]err:Traceback(最后一次呼叫):
文件“/usr/src/node red/node_modules/@node red/nodes/core/hardware/nrgpio.py”,第84行,在
GPIO.setup(引脚,GPIO.OUT)
运行时错误:无法访问/dev/mem。尝试以root用户身份运行!
:
9月16日19:21:33-[信息][rpi gpio输出:蜂鸣器(GPIO20)]关闭
9月16日19:21:33-[信息][rpi gpio输出:继电器(GPIO26)]关闭
9月16日19:21:33-[info][rpi gpio out:Relay(GPIO16)]err:Traceback(最后一次呼叫):
文件“/usr/src/node red/node_modules/@node red/nodes/core/hardware/nrgpio.py”,第84行,在
:
9月16日19:21:33-[信息][rpi gpio输出:继电器(GPIO16)]错误:gpio.setup(引脚,gpio.out)
运行时错误:无法访问/dev/mem。尝试以root用户身份运行!
:
9月16日19:21:33-[信息][rpi gpio输出:继电器(GPIO16)]关闭
9月16日19:21:36-[信息][rpi gpio输出:中继(GPIO16)]输出:0
9月16日19:21:36-[error][rpi gpio out:Relay(GPIO16)]nrpgio python命令未运行
9月16日19:21:37-[信息][rpi gpio输出:中继(GPIO16)]输出:1
9月16日19:21:37-[error][rpi gpio out:Relay(GPIO16)]nrpgio python命令未运行
解决这一问题的最佳方法是什么,而不是让系统处于极度不安全的状态

我尝试使用
Privileged:true
的目的是为了让事情顺利进行,但我怀疑这不是一个好的“生产”方式


我想知道是否需要在
Dockerfile
中执行一些操作,比如将默认节点RED用户添加到具有GPIO访问权限的组中,但是由于每次尝试都需要花费相当长的时间,我想我应该先问一下。:)

我不确定这是否能准确解决您的问题,但要从您的物联网边缘模块访问RPI的GPIO引脚,您必须做的一件事是将它们绑定到模块。例如,我用python编写了一个模块,该模块与物联网边缘的SenseHat附件集成。与许多库一样,它使用i2c总线与GPIO引脚通信,因此我使用这些“创建选项”将这些引脚映射到我的容器中

如果这不起作用,根据Node Red访问管脚的方式,您也可以尝试

{"HostConfig":{"Binds":["/dev/gpiomem:/dev/gpiomem"],"Privileged":true}}
或者(我认为这是“分享一切”的方法)


感谢@steve busby msft和@hardillb的回复。我已经在容器的创建选项中尝试了
“绑定”:[“/dev/gpiomem:/dev/gpiomem”]
“绑定”:[“/sys:/sys”]
,行为没有任何变化。我想知道Buster中是否有不同之处,因为我也无法执行
echo“out”“>/sys/class/gpio/gpio16/direction
(我得到
-bash:/sys/class/gpio/gpio16/direction:如果我这样做,就没有这样的文件或目录
)。根据@hardillb在其他地方的建议,我尝试设置
gpiod
,并使用gpiod节点,如果我在节点中硬编码IP地址,这确实有效。我在这里提到这一点只是为了证明硬件和节点的RED安装和代码似乎确实在工作,而我在上面所问的问题似乎是一个试图直接访问GPIO的真正问题。在Buster中很可能会有所不同,因为我只在raspbian stretch中完成了这项工作,而且从未遇到过将GPIO引脚暴露到容器中的问题。对不起,我不知道该怎么办。
{"HostConfig":{"Binds":["/dev/gpiomem:/dev/gpiomem"],"Privileged":true}}
{"HostConfig":{"Binds":["/sys:/sys"],"Privileged":true}}