添加链接
link管理
链接快照平台
  • 输入网页链接,自动生成快照
  • 标签化管理网页链接

X持久化远程应用Xpra快速起步

Xpra是一个开源跨平台持久化远程显示服务器以及用于转发应用程序和桌面屏幕的客户端。

Xpra提供了远程访问独立应用或者完整桌面的能力。对于X11,它就好像X11的 screen : 允许你在远程主机上运行程序,直接将程序显示在本地主机。这个功能和X11的服务器运行在本地,计算客户端运行在远程服务器上相同。但是,神奇的是,当你断开运行的程序,然后从客户端(可以是相同主机或不同主机)再次连接到远程服务器,所有的工作状态不会丢失。这就同时具备了X11的轻量级运行速度和VNC不丢失运行程序状态(随时可以继续)的优点,非常适合移动开发工作。

Xpra甚至可以转发所有桌面,从X11服务器,MS Windows或者Mac OS X。而且Xpra甚至可以转发声音,剪贴板和打印服务。

Xpra可以通过SSH访问,也可以使用或不使用SSL加密而仅使用密码保护的明文TCP连接。

  • Linux不同发行版都有二进制软件包可以使用,从 Xpra Linux Download 可以获得下载信息

  • xpra platforms 提供了各发行版支持情况:

  • Fedora 34+

  • CentOS / RHEL 8.x

  • Ubuntu: Bionic, Focal, Hirsute, Impish

  • Debian: Stretch, Buster, Bullseye, Bookworm, Sid

  • 支持 x86_64 和 arm64

  • macOS 10.9 (v3.x) 和 10.12.x (v4.x)

  • 以下案例是Ubuntu Bionic版本的安装:

    # install https support for apt (which may be installed already):
    sudo apt-get update
    sudo apt-get install apt-transport-https
    # add Xpra GPG key
    wget -q https://xpra.org/gpg.asc -O- | sudo apt-key add -
    # add Xpra repository
    sudo add-apt-repository "deb https://xpra.org/ bionic main"
    # install Xpra package
    sudo apt-get update
    sudo apt-get install xpra
    

    可以看到服务运行监听端口是 14500:

    CGroup: /system.slice/xpra.service
               ├─361123 /usr/libexec/platform-python /usr/bin/xpra proxy :14500 --daemon=no --tcp-auth=sys --ssl-cert=/etc/xpra/ssl-cert.pem --ssl=on --bind=none>
               └─361148 /usr/bin/dbus-daemon --syslog-only --fork --print-pid 4 --print-address 6 --session
    

    此时,这个远程服务器上运行的xterm就会直接映射显示到本地主机的X桌面上

  • 另一种方式是将步骤分开执行,分别在服务器上启动xterm会话,然后在本地主机去连接远程服务器上已经启动的会话:

  • 在远程服务器上启动程序:

    xpra start :100 --start=xterm
    

    聚合桌面应用(最佳方案)

    通过将 心仪 的应用程序集中在某个桌面显示屏,例如 :7 ,这样只需要一次 xpra 连接,就可以同时访问多个X程序,并且和本地桌面(例如macOS)完全融合。

  • 启动xpra服务器使用显示屏 :7

    xpra start :7
    
  • 将firefox运行在xpra server中:

    DISPLAY=:7 firefox
    
  • 将rxvt运行在xpra server中:

    DISPLAY=:7 rxvt
    
  • VS Code 运行在xpra server中:

    DISPLAY=:7 code
    

    聚合桌面应用(最佳方案-screen)

    结合服务器端的screen程序,可以实现更为方便的启动程序。也就是只要在 DISPLAY=:7 中启动了 screen 程序,后续在 screen 中启动的应用都会自动连入 xpra 桌面,也就简化了启动命令

  • 启动xpra服务器和screen会话,所有在screen中的应用程序都是使用X,将定向到xpra服务器:

    xpra start :7 && DISPLAY=:7 screen -S xpra
    

    集成ssh-key

    我在 SSH ProxyCommand实现穿透主机访问后端服务器 结合使用了 ssh密钥 方式认证,通过 ssh-agent 来实现一次输入密钥密码就可以多次任意访问不同服务器上SSH服务。不过, xpra 默认没有使用本地 ssh 认证,也就是没有使用 ssh-agent 缓存的密钥。

    要解决这个兼容性,即让 xpra 能够使用操作系统已经加载的 ssh-agent 中缓存的密钥,需要使用 --ssh=ssh 参数,也就是让xpra直接使用本地现有ssh。所以,客户端访问命令可以修订成:

    xpra --ssh=ssh attach ssh://z-dev/7
    

    注意,这里 z-dev 是使用了 私有云SSH访问 配置了 ~/.ssh/config ,已经启用了ssh的 ProxyCommand

    直接TCP访问(不推荐)

  • 如果内部网络非常安全,可以采用直接TCP访问,设置xpra直接监听TCP端口:

    xpra start --start=xterm --bind-tcp=0.0.0.0:10000
    
  • 然后客户端就直接访问TCP端口:

    xpra attach tcp://SERVERHOST:10000/
    
  • 如果要增加安全性,可以在服务器端启动时加上密码认证 --tcp-auth=file,filename=mypassword.txt

  • 完整桌面转发

    Xpra也支持将整个桌面输出,类似VNC访问。以下是启动fluxbox桌面方法:

    xpra start-desktop --start-child=fluxbox
    

    我使用 i3窗口管理器 桌面

    可以考虑对Windows或macOS桌面进行转发,通过服务器运行Windows/macOS虚拟机,实现不占用本地资源,尽享服务器高性能计算。

    克隆已经存在显示

    Xpra的 shadow 方式可以用来访问已经存在的桌面:

    xpra shadow ssh://SERVERHOST/
    

    这样就可以看到远程桌面。默认是X11的会话 :0 或者 :1 。如果有多个会话,也可以指定访问桌面:

    xpra shadow ssh://SERVERHOST/DISPLAY
    

    默认Xpra可以转发声音、剪贴板和光标,就好像应用程序的窗口,不过这些功能也可以关闭但是保留剪贴同步,例如:

    xpra shadow --no-printing --no-windows --no-speaker --no-cursors ssh://SERVERHOST/
    

    甚至可以将打印机转发到另一个服务器上,只需要启动一个远程会话但是不启动应用程序,并确保打印机转发激活:

    xpra shadow --no-windows --no-speaker --no-cursors ssh://SERVERHOST/ --printing=yes
    

    现在的使用经验

    最新的 xpra for macOS已经非常稳定(如果配置正确),只需要执行:

    xpra attach ssh://huatai@192.168.6.253/7
    

    就可以连接上文在服务器端启动在 :7 显示桌面的 xpra 会话,无缝访问会话中所有启动的Linux服务器上的图形程序,并且融入到本地操作系统中,就像本地原生程序。

    以前的使用经验

    macOS早期旧版本xpra不能直接使用 xpra 命令行。提供的图形界面Xpra,理论上应该是SSH服务器的22端口,访问的xpra是 :100 ,配置如下:

    然而,本地却始终看不到 xterm 窗口弹出(服务器端已经如上文启动了 xpra start :100 --start=xterm )

    我测试了多次,发现直接通过TCP访问远程xpra直接启动绑定端口的xterm是正常的,看起来问题在于SSH端口转发。所以,我采用手工方式在本地发起ssh的端口访问。

  • 修改 ~/.ssh/config 添加配置:

    Host worker7-x
        HostName 192.168.1.7
        User huatai
        LocalForward 1100 127.0.0.1:1100
    
  • 然后本地执行 ssh worker7-x 登陆到远程服务器上,就开启了SSH端口转发。此时,访问本地127.0.0.1的1100端口,就相当于访问远程服务器 192.168.1.7 的 1100 端口。

  • 在远程服务器上执行以下命令,将xpra启动的应用程序绑定到 1100 端口上:

    xpra start --start=/opt/GoLand-2020.2.3/bin/goland.sh --bind-tcp=127.0.0.1:1100
    
  • 本地启用Xpra客户端,设置TCP访问方式,直接访问本地回环地址 127.0.0.1 端口 1100 ,由于本地已经做了SSH端口转发,就可以直接访问远程服务器Xpra运行的X应用程序:

  • 你没有看错,你可以在服务器上运行任何X程序,包括非常消耗计算资源的开发IDE,Jetbrains全家桶。我这里的案例就是在远程服务器上开发Go程序,无论何时何地,随时可以连接到服务器上,利用服务器强大的计算资源进行开发。

    可以在服务器上运行多个大型程序,只需要使用不同端口运行,后续客户端通过SSH访问服务器端口转发到不同端口,就可以同时做很多计算密集型工作。

    需要注意的是,所有启动 xpra 服务端命令都只能绑定 127.0.0.1 本地回环地址,避免端口暴露。所有访问都必须通过SSH加密,避免安全隐患。

    目前还有一点遗憾是尚未设置好高分辨率,因为本地是MacBook Pro高清屏幕,远程映射过来的分辨率略低,字体不够清晰锐利。这个问题应该是服务器端显卡问题,我觉得后续可以通过 NVIDIA Virtual GPU (vGPU) 方式,在虚拟机中通过注入 NVIDIA 高性能显卡来实现性能提升。

  • 运行 VS Code GoLand等工具:

    xpra start --start=/opt/GoLand-2020.2.3/bin/goland.sh --bind-tcp=127.0.0.1:1100
    xpra start --start=code --bind-tcp=127.0.0.1:1110
    

    z-dev环境

    在host主机 zcloud 上执行iptables端口转发:

    iptables -A PREROUTING -t nat -i eno49 -p tcp --dport 25322 -j DNAT --to 192.168.6.253:22
    iptables -A FORWARD -p tcp -d 192.168.6.253 --dport 22 -j ACCEPT
    

    这里执行端口转发是因为通过 zcloud 对外网络接口能够转发到内部局域网的 z-dev 虚拟机上端口,如果客户端和服务器处于相同内网可以忽略这步

    推荐采用单个xpra会话

    我在 Fedora开发环境初始化 完整部署了一个支持中文输入的 xpra 会话,可以在Linux服务器上运行大量高资源消耗的图形程序,同时可以使用非常简单的瘦客户端进行连接(实际上还支持浏览器访问桌面的方式,甚至不需要客户端)。

    单独的连接端口方式(已不使用)

    私有云架构z-dev 虚拟机中运行Fedora 35,安装 xpra ,并启动对应服务程序:

    xpra start :100 --start=rxvt-unicode
    xpra start :101 --start=firefox
    

    对应客户端连接:

    xpra attach ssh://huatai@192.168.6.200:25322/100
    xpra attach ssh://huatai@192.168.6.200:25322/101
    

    只要网络足够快速,可以实现非常流畅的使用体验,以及开发工作。

    Docker Atlas 为我们带来一致性的运行环境体验,有一种快速部署开发工作环境的方式是将所有工作都封装在docker镜像中,然后通过

  • Wikipedia - Xpra

  • Xpra Wiki

  • Connecting to a linux workstation by Xpra - 剑桥大学化学分部有一篇如何使用Xpra访问Linux工作站的指导文档写得非常详尽,可以看出剑桥大学的计算机使用Linux工作站来运行应用程序,通过Xpra远程连接工作站进行科研。

  •