以非“root”的指定用户身份运行时具有设备 [GPIO] 访问权限的 Docker

以非“root”的指定用户身份运行时具有设备 [GPIO] 访问权限的 Docker

我们的多平台软件库有一个内部测试系统,该系统及其大量第三方工具在 [Ubuntu] Docker 容器内运行。

为了简单起见,主机和 Docker 容器都以同一个用户运行,test_user固定为 UID 1000/GID 1000;这样,卷就可以在两者之间映射而不会出现问题。

但是,我现在需要 Docker 容器能够访问设备在主机上(例如 GPIO)。这似乎只有在我专门以用户身份运行 Docker 容器时才有效root,即这成功允许访问主机上的 GPIO(如 所示gpiodetect,它使用libgpio我们现在要测试的 API):

docker run -t --rm -i -u root --privileged -v /sys:/sys -v /dev:/dev docker_image /bin/bash
root@f1f7ca240c1e:/workdir# gpiodetect
gpiochip0 [pinctrl-bcm2711] (58 lines)
gpiochip1 [raspberrypi-exp-gpio] (8 lines)

...然而,如果我添加test_userroot组中,则两者都在 Docker 容器内在主机上,这些都不会:

docker run -t --rm -i -u test_user --privileged -v /sys:/sys -v /dev:/dev docker_image /bin/bash
test_user@57130c86c196:/workdir$ gpiodetect
gpiodetect: unable to access GPIO chips: Permission denied
docker run -t --rm -i -u 1000:1000 --privileged -v /sys:/sys -v /dev:/dev docker_image /bin/bash`
test_user@57130c86c196:/workdir$ gpiodetect
gpiodetect: unable to access GPIO chips: Permission denied

不幸的是,将 Docker 容器作为 运行root,而且并不理想,也不是一个简单的选择,因为它会搞乱与主机的映射(来自 Git 等的可疑用户的大量喊叫)。

有没有办法让 Docker 相信root其运行的[非]用户具有root特权,因此可以访问 GPIO?

仅供参考,在主机上:

host:~ $ groups test_user
test_user: test_user root

...以及在 Docker 容器中:

test_user@1716f343e8c7:/workdir$ groups test_user
test_user: test_user root
test_user@1716f343e8c7:/workdir$

答案1

不要说服 Docker 做任何事情,只需授予test_user对主机和 docker_image 上的 gpiochips 的访问权限即可。然后你就可以像test_user以前一样运行Docker了。

通常在 Pi 上,gpios 位于gpio组中,因此在主机和 docker_image 中都将其添加test_user到该组( )。adduser test_user gpio

不确定这对于 Pi 上的 Ubuntu 是否有效(我自己也是 Raspberry Pi OS 用户)。如果没有,您还需要在 gpiochips 上设置一个组。但只要test_user在主机和 docker 镜像中拥有访问 gpiochip 设备的适当权限,就应该没问题。

例如,这对我有用,无需root参与:

pi@devpi4:~ $ docker run -t --rm -i -u test_user --privileged -v /sys:/sys -v /dev:/dev libgpiod_axs gpiodetect
gpiochip0 [pinctrl-bcm2711] (58 lines)
gpiochip1 [raspberrypi-exp-gpio] (8 lines)

其中libgpiod_axs映像是已安装的映像libgpiod,并且具有test_user组成员身份,主机上的用户gpio也是如此(同样可以命名为)。请注意,docker 镜像和主机中的组必须匹配。pitest_userGID

答案2

@kent-gibson 上面的答案是生意。明确地说,我添加到我们的Dockerfile

RUN groupadd -g 997 gpio &&                                                                   \
    echo SUBSYSTEM=="gpio", GROUP="gpio", MODE="0660" >> /etc/udev/rules.d/99-com.rules

...(997是底层Raspbian操作系统中组的ID gpio,我想知道我是否需要规则udev,只需要匹配组ID...?)然后在 的末尾,创建的Dockerfile位置test_user我添加了它对于gpio团队和工作来说是一件好事,他们test_user可以从 Docker 镜像中访问 GPIO。

另外,正如 Kent 指出的那样,我删除了/sys到 Docker 容器的映射,因为它完全没有必要。

相关内容