我们的多平台软件库有一个内部测试系统,该系统及其大量第三方工具在 [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_user
到root
组中,则两者都在 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 镜像和主机中的组必须匹配。pi
test_user
GID
答案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 容器的映射,因为它完全没有必要。