Docker 用户命名空间究竟如何工作?

Docker 用户命名空间究竟如何工作?

我已经在 Docker 中启用了用户命名空间,以尝试(我认为)将任何容器使用的任何用户都分配到特定的命名空间。

该用户已被docker创建,并且subuid、subgid中的条目也已创建:

dockremap:362144:65536

虽然dockremap它本身的 ID 是 116,

我现在希望我可以将主机中的任何文件绑定到容器,并且只要该文件归dockremap主机所有或权限足够开放,容器就能够读取它。目录也一样。

相反,我发现自己必须由某个用户成为文件/文件夹的所有者362144(这在主机上没有任何意义,因此lsps等只显示数字 ID)。

这是预期的工作方式吗?因为我做错了,或者从管理的角度来看,这是一场噩梦。

答案1

是的,预计它会这样工作。该subuid文件并不意味着任何东西都会映射到你的账户——恰恰相反,它保留了一系列自由的专门供你的容器使用的“真实”UID,以便它们不重叠与真实系统帐户或其他用户运行的容器无关。

Linux 用户命名空间 ID 映射始终是 1:1;一个范围只能映射到另一个大小相同的范围。这是因为 UID 映射必须双向起作用 - 不仅在为新创建的文件分配真实 UID 时,而且在确定在现有文件的容器内显示哪个所有者时。

例如,鉴于您拥有的 1:1 映射,容器的 UID 1000 所拥有的文件将被存储为具有 363144 作为其真实所有者,以便当容器再次启动并检索信息时,主机的 363144 可以转换回容器的 1000。

如果映射不是 1:1(例如,如果所有容器 UID 都映射到同一个主机 UID),那么哪个容器用户拥有哪个容器文件的信息将会丢失。(理论上,容器所有者可以存储在 xattrs 中,但 Linux 本身并不这样做。我听说 Docker 在 macOS 上使用自己的 FUSE 层实现了这一点,我怀疑它可能会在 Linux 上使用 fuse-overlayfs 来实现这一点,但我从未使用过 Docker 进行过这种程度的开发,所以我并不确定。)

使用最新的 Linux 内核,还可以将 UID 映射应用于挂载,而不仅仅是用户命名空间,因此理论上可以指示容器引擎将目录绑定挂载到容器中,同时将容器的 UID 1000 映射到主机的 UID 1000,或类似的东西。我在 systemd-nspawn 中看到了这个选项,但同样,我不知道在 Docker 中哪里可以找到它——尽管文档表明它将为此目的使用shiftfsfuse-overlayfs,而不是原生 Linux idmapping。

相关内容