我在 Fedora 计算机上使用官方 ISC Bind9 容器映像(似乎基于 Debian Linux),但我在权限方面遇到问题。
我按如下方式启动容器:
podman run --name bind9 \
-p 11153:53/udp \
-p 11153:53/tcp \
-v /home/devops/work/dns/primary/etc:/etc/bind/:rw,Z,U \
-v /home/devops/work/dns/primary/cache:/var/cache/bind:rw,Z,U \
-v /home/devops/work/dns/primary/lib:/var/lib/bind:rw,Z,U \
-v /home/devops/work/dns/primary/log:/var/log:rw,Z,U \
internetsystemsconsortium/bind9:9.20 -4 -g -c /etc/bind/named.conf
没有 podman 日志可供参考,因此我在
named
上设置了 -g 标志,以便将错误发送到 stderr。 我收到以下错误消息,这些消息似乎是我的主机和容器之间的访问问题???
09-Nov-2024 21:26:44.329 the working directory is not writable
09-Nov-2024 21:26:44.330 loading configuration: permission denied
09-Nov-2024 21:26:44.330 exiting (due to fatal error)
深入研究容器层,我发现在容器中,
bind
用户用于在容器的ENTRYPOINT部分运行named
。
...
23 VOLUME [/etc/bind /var/cache/bind /var/lib/bind /var/log] 0 B
24 EXPOSE map[443/tcp:{} 53/tcp:{} 53/udp:{} 853/tcp:{} 0 B
25 ENTRYPOINT ["/usr/sbin/named" "-u" "bind"] 0 B
26 CMD ["-f" "-c" "/etc/bind/named.conf" "-L" 0 B
...
我知道我可以覆盖
CMD
并且我在上面的 podman 命令中这样做了,但是是否可以覆盖 ENTRYPOINT
,以便它不是 bind
用户而是 root
用户? 我想知道这是否有帮助。
此外,我可以做些什么来处理容器中不在容器主机上的用户帐户吗? 我猜这更像是 podman 的事情,它只能与 Docker 一起使用...但是对于 podman,我真的必须在主机上创建一个具有与容器中相同的 UID:GID 的
bind
用户吗?只是为了让它发挥作用??
注意:我在 Fedora 机器上由
devops
用户将其作为无根容器运行,并且所有已安装的卷都位于用户的主目录树中。
编辑:
我在故障排除方面取得了一些进展。 如果确实是 UID 权限类型问题...我确实发现了容器中
bind
用户的 UID:
podman run -d --name=bind9 -p 11153:53/udp -p 11153:53/tcp internetsystemsconsortium/bind9:9.20
podman exec -it bind9 /bin/sh
/ # cat /etc/passwd...
bind:x:100:101:Linux User,,,:/var/cache/bind:/sbin/nologin
编辑:
我尝试将
--userns=keep-id:uid=100,gid=101
添加到 podman run 命令中,但我仍然遇到同样的问题。 我不确定接下来要尝试什么。
您遇到的所有问题在无根运行容器中都是众所周知的。从根本上来说,这是因为无根运行只是 Docker 设计时的事后想法,因此整个容器镜像生态系统都需要 root 权限。因此,Podman 必须使用用户命名空间来解决这个问题。
我将向您推荐这两篇优秀的 RedHat 文章,解释无根容器背后的技巧以及您可能遇到的麻烦:
请阅读这两篇文章,但总而言之,您在主机上看到
nobody
是因为用户命名空间(以及容器)中的 UID 100
被映射到其他某个 UID(可能是 500,000+
;检查您在主机上的 /etc/subuid
),该主机在您的主目录中没有权限。
我真的必须在主机上创建一个与容器中具有相同 UID:GID 的绑定用户才能使其正常工作吗??
不要这样做。永远不要这样做。这将你的可移植性降低到基本为零,更不用说它将容器的实现细节暴露给主机,这很容易引起冲突。
所有这些都是为什么建议使用卷挂载来满足几乎所有无根容器的持久存储需求的部分原因。您只需在命名空间内正确设置权限,然后让 Podman 处理所有 UID 和 GID 映射。本文展示了如何做到这一点:
在实践中,我建议创建两个卷:一个安装在
/etc/bind/
上,另一个安装在 /var/
上。所以你的运行命令看起来像这样:
...
-v bind-etc:/etc/bind/:rw,Z \
-v bind-var:/var/:rw,Z \
...
理想情况下,我会使用一个卷并在不同的子路径上安装
/etc/bind/
和 /var/
,但 Podman 尚不支持这一点。但似乎今天早些时候提交了一个 PR,很高兴看到。根据您阅读此答案的时间以及您安装的 Podman 版本,您可能希望这样做。