是否可以加入两个不同的进程名称空间?

是否可以加入两个不同的进程名称空间?

我想知道是否可以在 Linux 中加入两个进程名称空间。为了证明我的意思,以下是一个场景:

  1. 进程在其自己单独的命名空间中运行。我们将此过程称为 A。

  2. 现在进程 A 正在做它的事情,我启动了另一个进程 B,该进程被隔离在自己单独的命名空间内。

  3. 现在进程 A 和进程 B 都有自己独立的命名空间,但我希望将它们的进程命名空间“合并”为一个。即,我希望进程 B 能够看到 A 的命名空间并发送信号/与 A 的进程交互。

这样做的用例是,我最终希望将一个容器附加到另一个正在运行的容器,以便附加的容器可以与正在运行的容器交互。

我考虑过,setns()但这行不通,因为进程 B 不知道进程 A 的名称空间句柄 ( /proc/PID/ns/pid),因为它也是隔离的。我正在尝试思考从主机系统实现这一目标的最佳方法是什么。

这已经在docker中实现了这里但我无法理解其背后的逻辑。还讨论了一些实施方面的问题这里如果有帮助的话。

谢谢你的时间!

答案1

当我们谈论 Linux 命名空间时,我们实际上谈论的是许多不同的名称空间,所有这些都可以单独设置:

  1. 进程 ID
  2. 共享内存
  3. 联网
  4. 主机名等
  5. 用户 ID
  6. 文件系统

当一个进程使用正确的标志调用setns()orclone()时,就会产生一个新的名称空间,并带有“假”的世界视图。

现在,如果我们想再次将它们合并在一起,这可能会导致问题。

让我们采用“进程 ID”命名空间,因为它很简单。

当您创建新的 PID 命名空间时,第一个进程在该命名空间内获得 PID 1。如果你有两个新的命名空间,那么你就有两个认为它们的 PID 为 1 的进程。如果你想合并它们,那么就会发生冲突;只有其中一个可以保持 PID 1,你必须改变正在运行的进程的 PID 意外。这可能会产生意想不到的后果。

与 IPC 类似;两个独立的共享内存块在各自的命名空间内可以具有相同的地址;如果我们尝试合并它们,那么我们将看到内存损坏(即使您更改了一个段的地址,流程仍保留旧地址)。

因此合并两个现有的命名空间充满了危险。

补丁的作用docker防止容器启动时创建新的命名空间。这与合并两个现有容器不同;它发生在容器启动时。

答案2

据我所知,没有办法加入不同的进程命名空间。setns在 PID 命名空间上只允许进程在不同的命名空间中生成子进程,并且该不同的命名空间必须是该进程的命名空间的后代,所以我认为这对您没有帮助。

但是,在您的场景中,两个命名空间看起来位于密切相关的树中。所以你可以从共同的祖先开始进行这种操作。

您引用的有关 Docker 的线程没有讨论合并命名空间:它们是关于不创建子命名空间(因此它仍然是一个大命名空间)。

相关内容