在应用程序中,我需要临时“切换”到特定的安装命名空间以检查其中的某些内容/proc
,然后切换回应用程序启动时使用的安装命名空间,然后切换到另一个安装命名空间,等等。
应用程序以“root”挂载命名空间在 root 用户下启动(这里有两个不同的 root 概念!)。
在引擎盖下,setns()
用于来回切换。最重要的是我使用 Zalando 的nsenter Python 库。该库允许通过首先打开一个/proc/self/ns/[nstype]
稍后用于切换回来的fd 来“进入”特定的命名空间。然后,它获取文件系统中名称空间的路径,从中打开一个 fd,并通过 加入setns(fd, 0)
。之后,使用第一个fd连接回原来的命名空间,setns()
再次使用。这对于网络命名空间来说非常有效。
但对于跳跃挂载命名空间,在离开之前尝试再次重新进入相同的挂载命名空间时,它会失败。此处跳转意味着:我的应用程序进入一个挂载命名空间,执行一些工作,返回到其原始挂载命名空间,再次切换到挂载命名空间,然后切换回来,等等。
无论如何,问题似乎出在容器中的容器上。
切换挂载命名空间是否有一些限制?可能与用户命名空间有关?这挂载命名空间手册页提到与用户命名空间的一些关系,但我不明白创建容器的挂载命名空间时激活的不同用户命名空间如何影响我的应用程序从具有根权限的根用户命名空间切换到和离开这些容器挂载命名空间。切换到这样的挂载命名空间是否会使我的应用程序失去权限,因此稍后会失败?
所以,向巨人致敬:挂载命名空间跳跃被认为是有害的吗?
答案1
可能是手册页末尾附近的这个小字设置(2)是我困境的关键:
更改挂载命名空间要求调用者在其自己的用户命名空间中同时拥有 CAP_SYS_CHROOT 和 CAP_SYS_ADMIN 功能,并在目标挂载命名空间中拥有 CAP_SYS_ADMIN 功能。
我怀疑我的应用程序/进程在进入另一个容器内的容器挂载命名空间后丢失了一些 CAP,因此它被锁定在挂载命名空间内。 s5ill 仍然让我想知道:尝试与根安装命名空间重新关联时没有错误/异常......
切换的典型用例可能是切换到目标命名空间,然后消失,但永远不会切换回来。在挂载命名空间的情况下,看起来好像没有生命线可以回来。