简介:客户前期使用的旧异构实例面临更新换代,新的推荐异构实例性能更强,客户的业务软件运行时,GPU使用率不高,需要探索多开方案,提高GPU使用率,提高实例性价比。
背景:客户前期使用的旧异构实例面临更新换代,新的推荐异构实例性能更强,客户的业务软件运行时,GPU使用率不高,需要探索多开方案,提高GPU使用率,提高实例性价比。此外,客户的业务软件多开后,必然涉及到多开的每个业务软件分别给不同的用户使用的场景,因此,在一个桌面中多开业务软件的方案不可行(操作及画面显示均互相冲突),需要探索整个Linux桌面多开的方案。
Linux图形应用容器化
在不考虑桌面多开时,参考阿里云官方文档Linux图形应用最佳实践,Linux图形应用容器化时,有两种方案:
1)在Host(注:此处的Host是相对于容器来说的,容器为Guest,下文不再作重复解释)上运行X Server:Host上安装并启动Xorg,将X Server的unix socket目录(/tmp/.X11-unix)映射到容器中并设置好权限,容器中设置好DISPLAY环境变量后,即可通过共享的unix socket向Host上的X Server发送图像渲染命令。此方案下,如果要查看显示结果,可以在Host上运行x11vnc,然后使用VNC Client软件连接。
该方案优缺点:
∙ 优点:多个容器可以同时共享Host上的X Server;
∙ 缺点:多个容器的图像都是渲染到同一个X Server上的,互相之间会遮挡影响;
2)在容器中运行X Server:Host上只需要安装GPU驱动,不做任何配置,在容器中安装并运行Xorg。
该方案优缺点:
∙ 优点:Host不用做任何配置,定制修改都在容器中,便于保存和迁移;
∙ 缺点:GPU是单个容器独占的,不能多个容器共享;
Linux桌面多开方案
单显卡上启动多个X Server进程实现多开
测试了三种方案:
∙ 在Host上运行多个X Server进程;
∙ 在Host上和容器中同时运行X Server进程;
∙ Host上不运行X Server,在多个容器中同时运行X Server进程;
均不成功,后启动的X Server会接管硬件,使得后启动的X Server画面正常,而先启动的X Server画面黑屏。
Multiseat方案
Multiseat方案(MultiseatX、MultiseatOneCard、Multiseat - X.Org、MultiSeatTerminal – X.org、Multiseat - Gentoo Wiki)是在多个显卡或者单个显卡的多个输出的基础上,实现多个独立桌面的方案,它受硬件的限制较大,多开数量有限,配置也相对复杂,暂不考虑该方案。
Xephyr方案
Xephyr是一个嵌套的X Server,它本身运行在X Server中,对X Server来说它是一个应用程序,同时,它自身又是一个X Server,为其他的应用提供服务。
Xephyr方案的最大缺点是,目前不支持GPU硬件加速。
Xpra方案
Xpra和Xephyr类似,是嵌套的X Server,主要区别是,Xephyr会将它提供的嵌套X Server作为一个窗口显示在当前X Server中,而Xpra倾向于提供一个虚拟的X Server环境,将显示转发到客户端去。参考:What's the difference between Xpra and Xephyr?
和Xephyr一样,Xpra的最大缺点也是,不支持GPU硬件加速。
VirtualGL方案
方案描述:
VirtualGL(官方文档)是一个为Linux/Unix远程显示软件启用OpenGL硬件加速的开源工具。
通常,一个Linux/Unix OpenGL应用程序会发送它所有的(包括2D和3D)图形渲染命令和数据到一个X Server。VirtualGL通过在运行时将动态共享对象(Dynamic Shared Object, DSO) VirtualGL Faker预加载到OpenGL应用程序中来实现将3D命令和数据从OpenGL应用程序重定向到应用所在服务器中的GPU。VirtualGL Faker拦截并修改某些GLX、EGL、OpenGL、X11和XCB函数调用,将OpenGL渲染从3D应用程序的窗口转移到VirtualGL在GPU显存中创建的离屏缓冲区(off-screen buffer)。
当3D应用程序交换OpenGL绘图缓冲区或刷新OpenGL命令缓冲区以表示它已完成渲染帧时,VirtualGL从离屏缓冲区读取渲染好的帧并(通过X Proxy,比如TurboVNC)将它传输出去。
使用VirtualGL时,GPU可以给多个用户共享。
VirtualGL方案的很大一个优点是它的非侵入性。VirtualGL监视一些X11命令和事件,以确定窗口何时被调整大小等等,但它不会以任何方式干扰X11 2D绘图命令到X Server的传递。在大多数情况下,VirtualGL也不会干扰OpenGL命令到GPU的传递。VirtualGL只是强制将OpenGL命令传递给应用服务器上的GPU(通过3D X Server或与GPU的EGL设备),而不是传递给2D绘图命令的X Server(2D X Server)。
VirtualGL内建支持两种图像传输协议(还支持协议扩展),VGL传输协议和X11传输协议。
VGL传输协议
当2D X Server不在应用程序服务器上时(比如2D X Server运行在客户端机器上),最常使用VGL传输协议。VirtualGL在专用的TCP socket上使用自己的(VGL)协议将渲染的帧发送到客户端,VirtualGL客户端将帧解码并将它们组合到适当的X窗口中。VGL传输协议可以以未压缩的形式(RGB编码)传输帧,也可以使用high-speed JPEG编解码器实时压缩帧。它还支持立体图像对的交付,可以通过VirtualGL客户端将其重建为立体帧。整个框架如下图所示。
图 1 VirtualGL使用VGL传输协议框架图
X11传输协议
X11传输协议本身只是使用XPutImage()或类似的X11命令将渲染好的帧绘制到适当的X窗口中。在使用X11传输协议时,VirtualGL本身通常不执行任何图像压缩或编码。相反,它依赖于一个X Proxy(比如VNC)来编码帧并将它们交付给客户端。由于使用X Proxy不需要通过网络发送X11命令,因此在高延迟或者低带宽网络上使用VirtualGL时推荐使用X11传输协议。整个框架如下图所示。
图 2 VirtualGL使用X11传输协议框架图
相对来说,VGL协议设置更复杂(客户端需要同时安装2D X Server和VirtualGL Client),且通过网络传输X11命令,受网络影响更大,因此本文后续选择使用X11传输协议。
VirtualGL的Backend
图 1和图 2中的绿色线条表示VirtualGL支持两种Backend,GLX和EGL。VirtualGL最初只支持GLX Backend,它需要一个运行的3D X Server(最常见的如Xorg),多个用户通过VirtualGL共享GPU时,由于它们都具有X Server访问权限,会存在互相影响以及安全问题。从0版本开始,VirtualGL支持了EGL Backend,使得VirtualGL脱离了对3D X Server的依赖。
安装与设置
本文安装环境为阿里云ecs.gn7i-c8g2xlarge实例,Host OS为Ubuntu 18.04。
使用GLX Backend
Host安装与设置
Host上安装与设置步骤如下:
∙ 安装Xorg、桌面环境(本文安装xfce4)、x11vnc;
∙ 安装NVIDIA驱动;
∙ 启动X Server(Xorg);
∙ 启动xfce4桌面;
∙ 启动x11vnc Server;
∙ 安装nvidia-docker2;
∙ 下载NVIDIA官方docker镜像(比如nvidia/cuda:14.3-base-ubuntu18.04);
∙ 启动容器(启动时,需要将/tmp/.X11-unix映射到容器中);
容器安装与设置
容器中安装与设置步骤如下:
∙ 安装桌面环境(本文安装xfce4);
∙ 从VirtualGL官方网站下载VirtualGL和TurboVNC安装包进行安装;
∙ 配置VirtualGL:/opt/VirtualGL/bin/vglserver_config -config +s +f +t
∙ 安装NVIDIA用户态驱动(容器中安装驱动时,不要安装内核态驱动),命令示例:./NVIDIA-Linux-x86_64-470.80run -a -q --ui=none --no-kernel-module
∙ 启动运行TurboVNC:
export TVNC_VGLRUN="vglrun -d :0 +wm"
/opt/TurboVNC/bin/vncserver -wm xfce -vgl -geometry 1920x1080 -depth 24
其中:0对应Host上创建的桌面监听的DISPLAY;
然后,客户端下载TurboVNC,使用TurboVNC Viewer连接容器中TurboVNC监听的端口即可看到桌面。
带你读《弹性计算技术指导及场景应用》——1. 单实例上运行Linux桌面多开解决方案(2):https://developer.aliyun.com/article/1423691