当前位置: 首页 > 知识库问答 >
问题:

共享X11套接字的Docker:为什么它可以在容器之外“启动”Firefox?

龚招
2023-03-14

我有以下场景:

  1. 我设置了一个可以访问X11套接字的Docker容器,实际上我这样做了:https://stackoverflow.com/a/25334301
  2. 然后,我在容器中安装了Firefox,并使用bash中的“Firefox”命令启动它

我注意到:如果当我在容器中启动Firefox时,它已经在我的主机上运行了,那么它实际上“逃离”了容器,因为它只是打开了Firefox的主机实例的一个新窗口。因此,它可以访问主机上的所有内容,容器变得毫无用处。

反之亦然:如果Firefox没有在主机上运行,而我在容器中启动了一个实例,那么它实际上是在容器中运行的。如果我随后在主机上启动Firefox,那么新实例也在容器内运行。

然而,我无法用gvim而不是Firefox重现这种行为。

我很清楚X11套接字共享固有的安全问题,但是我无法解释我上面描述的场景。为什么容器可以在其受限环境之外启动一个“进程”——或者更确切地说是一个窗口?我的主机系统怎么可能仅仅因为同一个程序已经在容器中运行,就在容器中启动一个进程呢?

(请注意,除了“进程”,我不知道如何调用这样一个程序的图形化实例,尽管在这种情况下它可能不是一个真正的html" target="_blank">进程...)

系统:Ubuntu GNOME 14.10,Docker 1.5,ubuntu:最新的Docker镜像。

更新:如果我使用-new-example标志启动Firefox,则不会发生这种情况,因此它似乎更多的是Firefox问题而不是X11套接字问题。

更新2:似乎在其他场景中也会发生这种情况,例如将ssh与X-转发一起使用:
https://unix.stackexchange.com/questions/104476/why-starting-firefox-from-command-line-in-vm-starts-the-firefox-in-the-host-ma

https://superuser.com/questions/462055/launching-firefox-on-remote-server-causes-local-firefox-to-open-the-page-instead

现在的问题是,火狐到底是怎么做到的?他们使用哪种 X11 巫术来查明 Firefox 是否已经在运行?

共有1个答案

冯敏达
2023-03-14

因为您将x11套接字转发到容器中,所以任何图形程序,无论是在容器内部还是外部,都将与同一个Xorg服务器进行对话。这与将ssh与X-forwarding一起使用时是一样的。

现在假设一个firefox实例已经启动并与该xserver通信。如果我们是第二个启动的firefox进程,我们可以通过从根目录导航窗口树来找到第一个进程。我们可以通过设置在firefox窗口上的一些属性来识别属于firefoxs的窗口。一旦我们找到属于firefox的窗口,我们可能会向拥有该窗口的进程发送一条消息,要求它添加一个新选项卡。

也许,如果我们找到这样一个流程并要求它打开一个新的选项卡,我们就会随着工作的完成而消失。

当然,我们总是可以只看源代码,发现火狐确实基本上做到了这一点。特别是他们:

  • 查找现有窗口
  • 然后通知它

但他们不会通过客户端消息通知它。他们通过更改窗口属性来执行此操作。据推测,创建窗口的进程也会订阅属性更改通知。如果您感到好奇,代码的完整路径是:

  • 从解析命令行开始,StartRemote teClient
  • 它创建一个客户端(注意他们也通过d-bus/wayland执行此操作),然后调用SendCommand dLine()
  • 这是一个虚函数,所以找到它覆盖了XRemoteClient
  • 在那里您可以看到它在哪里调用链接到FindBestWindow()DoSendCommand dLine()的前两个函数。
 类似资料:
  • 问题内容: 我在一个具有不同进程的应用程序上工作,并被要求包含那些进程以实现更多隔离。 问题在于,进程与单个“管理程序”进程共享内存以便交换数据(它们使用经典的共享缓冲区)。该解决方案是为满足性能要求而实施的,因为它在用户空间中运行,因此在用户空间和内核空间之间没有内容切换。 如果我没看错,则不可能在单个IPC名称空间内运行多个docker容器,但是我不知道单个docker容器是否可能属于不同的I

  • 我有一个文件,它创建了两个实例,一个用于,另一个用于。 当我运行时,我会得到这样的输出: 如果我运行: 我看到两个服务共享。在我的中,我设置了: 在创建前运行一些

  • 问题内容: 嗨,我正在使用Docker部署一些服务,在这里我想在不同的Docker容器之间共享Docker卷。 假设我有一个Docker容器A在/ data挂载了一个卷。这是A的Dockerfile 据我了解,这会将一个卷附加到容器,但不会将主机目录装载到该容器。因此,该卷内的数据仍位于容器A内。 我有另一个提供ftp服务的容器B。它访问卷/ public下的数据。B的Dockerfile是 现在

  • 我正在使用Docker部署一些服务,我想在不同的容器之间共享Docker卷。 假设我有一个Docker容器a,它在/data处挂载了一个卷。下面是它的DockerFile: 根据我的理解,这会将卷附加到容器,但不会将主机目录挂载到容器。所以这个卷里面的数据仍然在容器A里面。

  • 有没有人知道Docker中容器之间共享数据库的最佳实践是什么? 我的意思是我想在Docker中创建多个容器。然后,这些容器将以相同的身份在相同的数据库上执行CRUD。 到目前为止,我有两个想法。一种是创建一个单独的容器来运行数据库。另一种方法是直接在安装Docker的主机上安装数据库。

  • 我有一个带有ASP.NET核心的docker容器和一个带有MySQL的容器。现在,我需要使用ASP.NET核心容器等待,mysql容器已经启动并准备就绪(这两个容器都是通过docker-compose.yml启动的)。 这是我的DockerFile: