通过 Docker 进行 X11 套接字时出错“无法打开显示”[Ubuntu 22.04 上的 Docker 桌面,无 ssh/vnc]

问题描述 投票:0回答:1

我在从运行的 Docker 容器中打开任何 X11 窗口(也从 Python OR ROS 脚本绘制窗口)时遇到问题。简而言之,我总是从不同的应用程序中收到类似的“无法打开显示”错误。

我不是在寻找模拟桌面环境、ssh 转发或 VNC 虚拟化。

平台

主机:Ubuntu 22.04 码头工人:码头工人桌面4.15 图片:在普通的 ubuntu:latest 或 debian:latest 图像上尝试过 firefox、xeyes 等(例如 gns3/xeyessshipway/xclock)。甚至我用 Dockerfiles 从头开始构建了几个。

运行命令

docker run -it --network=host -e DISPLAY -v "/tmp/.X11-unix:/tmp/.X11-unix:rw" <image name>

我也试过:

  • xhost +local:root
    ,
    xhost +local:docker
    , 甚至
    xhost +
    在运行容器之前
  • --privileged
  • --runtime=runc
  • DISPLAY=127.0.1.1:1
    (即
  • DISPLAY=unix$DISPLAY

额外信息

  • 在容器中显示环境变量:
    DISPLAY=:1
  • 在主机上,没有
    ~/.Xauthority
    ,而是
    xauth
    目标
    /run/user/1000/gdm/Xauthority
  • 我已经检查了解决方案 1解决方案 2解决方案 3,但我仍然遗漏了一些东西。

QEMU/KVM 虚拟化层是否是问题的根源,因为它是 Docker Desktop(不仅仅是 Docker Engine)?

docker x11 docker-desktop ubuntu-22.04 x11-forwarding
1个回答
0
投票

我有你的exact设置(ubuntu 20.04除外,不是22.04),并尝试了许多解决方案超过一整天。

这是我过去一天的发现

  1. X 服务器默认不监听 TCP
  2. --network=host
    没有像我想的那样工作,
    :1
    127.0.0.1:1
    都没有解决问题
  3. 当我从 docker 容器中 ping 任何站点(例如
    ping google.com
    )时,它会将其解释为
    198.18.0.1

我不清楚底层机制,但经过尝试,我解决了这个问题

  1. 通过简单地修改
    /etc/gdm3/custom.conf
  2. 让X服务器默认监听TCP
[security]
DisallowTCP=false

[xdmcp]
ServerArguments=-listen TCP

(假设您的桌面管理器是

gdm
,这可能是 Ubuntu 17 的默认管理器)并重新启动
gdm

  • 要检查这一点,请使用命令
    nmap localhost
    查看是否显示
    6001
    (假设
    $DISPLAY=:1
    )或
    X11
    (或任何类似的命令,如
    netstat -an | grep 6001
    ps -ef | grep X
    可用于查看是否
    Xorg 
    使用
    -listen tcp
    参数运行)
  1. 使用
  2. 成功运行 docker 容器
xhost +
docker run \
    -it \
    --rm \
    -e DISPLAY=198.18.0.1$DISPLAY \
    xclock

其中

xclock
是由这样的
Dockerfile

定义的简单图像
FROM ubuntu:20.04
RUN apt-get update
RUN apt-get install -y x11-apps
RUN apt-get install -y iproute2 \
    curl \
    iputils-ping \
    net-tools
CMD xclock

(最后一层apt用于之前的网络调试,可以省略),然后你应该在你的显示器上看到一个GUI时钟。

这个

198.18.0.1
是什么意思,目前我知道的是

  1. 它包含在
    ifconfig
  2. 的输出中
  3. 它是前缀
    198.18.0
    包含在从 docker 容器内调用的
    ping
    的输出中

因此,我猜想它与充当主机和docker容器之间桥梁的某些网络接口有关。然而,这个猜测似乎与我对主机模式的理解相冲突(因此我删除了

--network=host
)。

此外,我最终没有映射UNIX套接字文件

/tmp/.X11-unix
,因为我发现它不影响结果。我不确定连接是否完全通过 TCP 而不是 UNIX 传输 套接字文件。

记得在试用后

xhost -
。不需要禁用防火墙,所以只需通过
sudo ufw enable
保持打开状态即可。同样,我不确定该机制或其安全问题。

我的问题解决后很快就把这个答案贴出来了,以后有什么新发现或者错误可能会修改。希望哪位高手指正我的不足和问题

© www.soinside.com 2019 - 2024. All rights reserved.