前端一段时间被"容器云"团队抓了"壮丁",去支援了一段时间,恰好有一个需求是通过web页面实现链接容器的命令行工具。这里分享一下相关的实现方案。有兴趣的可以了解一下。
前面提到容器,了解的朋友请忽略,不了解的朋友就把它当做一台虚拟服务器把,虽然他不是。下面的案例也是通过web页面实现和服务器的连接,并不是和容器的连接,但是原理是一样的。
先走一下程序百度科普一下什么是VNC技术,VNC(Virtual Network Computing)网络遥控技术是指由一部计算机(主控端)去控制另一部计算机(被控端),而且当主控端在控制端时,就如同用户亲自坐在被控端前操作一样,可以执行被控端的应用程序,及使用被控端的系统资源。
这种方案相对简单,我们大部分工作是集成,因为作者已经将前端,后端服务都写好了,我们只需要部署上去就能正常的运行起来。当然,只是运行起来,他运行起来是长这样的:
正常情况下这界面是不满足我们需要的,我们需要根据自己的交互稿去修改源文件的前端代码,当然后端也可能需要一定的定制,比如和数据库进行交互…。但是它不用服务端去解析命令输入和目标服务器的连接,这看起来前端的工作好像要大一点了。下面这张图是百度云的webSSH窗口 ,他就是基于noVNC实现的,在这个基础上做了一定的定制。
看起来好像有点简陋,但是人家是一个有内涵的。外观简洁,功能强大,在SSH客户端上能实现的他基本上都能实现,所以有时候我们还是不能只看颜值,内在美也不能忽略。
实现步骤:
vncserver是部署在远程服务器上的服务,通过接收和处理noVNC传输过来的命令,然后实现对目标服务器的操作,然后再将操作结果和过程通过双方建立的tcp通道返回给noVNC,noVNC服务再通过websocket推送给前端页面,前端页面服务显示信息和收集下发命令。下面是一张草图,供参考。
首先需要操作的服务器上装上vncserver
服务,他才是在宿主机上接受命令,然后向Linux操作系统下发命令的,而noVNC只是一个中间代理人的角色,这个后面安装noVNC再讲。
sudo apt-get install vnc4server
安装成功后执行vnc4server
,启动服务
:~$ vncserver //启动vncserver服务
You will require a password to access your desktops.
Password:
Verify:
xauth: file /home/xy/.Xauthority does not exist
New 'tnode07:1 (nsr)' desktop is tnode07:1
Creating default startup script /home/xy/.vnc/xstartup
Starting applications specified in /home/xy/.vnc/xstartup
命令查看vncserver状态
ps axu|grep vnc4
安装好vncServer后,再来安装noVNC,因为我这里只有一台服务器,所以我server和client的服务是部署再一台机器上的,通常情况下这两个是部署在不同服务上的,这里提一下。
noVNC提供浏览器访问的web服务,访问目标服务器vncserver提供的vnc服务
noVNC和vncserver建立TCP连接,浏览器端和noVNC服务之间通过websocket连接,前端通过Canvas录入和接收显示命令和信息。浏览器其实就相当于一个客户端,类似win下面的vncviewer。
git clone https://github.com/kanaka/noVNC
这里我建议在线通过git 将远程仓库克隆下来,因为再克隆的过程中还会下载websocket相关的包,如果通过离线的方式,这些包还需要手动去安装。
下载成功后执行启动服务命令
./noVNC/utils/.launch.sh --vnc localhost:5900
Warning: could not find self.pem
Starting webserver and WebSockets proxy on port 6080
WARNING: no 'numpy' module, HyBi protocol will be slower
WebSocket server settings:
- Listen on :6080
- Flash security policy server
- Web server. Web root: /home/xiaofei/work/noVNC
- No SSL/TLS support (no cert file)
- proxying from :6080 to 192.168.110.179:5901
因为我noVNC和vncServer是安装一台机器上的,所以就是是localhost,如果不是一台机器,就是vncServer所在服务器的地址。5900是vncServer开放的访问端口
这样就安装成功了,然后通过浏览器访问一下,看看是长什么样子。
点击链接,然后输入远程服务器的登陆密码
看起来确实有点抽象,比上面百度云那个看起来抽象多了,这里就是我们前端发挥作用的时候了,我们可以将noVNC的前端源码按照我们的UI输出进行修改,达到我们想要的效果。
到这一步,基本功能就实现了。
在做管理平台时,需求是需要通过noVNC提供的服务来访问任意我们有权访问的远程服务器,但是我们可以发现,前面我们在启动noVNC的时候,我们是通过
./noVNC/utils/.launch.sh --vnc localhost:5900
的形式来启动的,这样是指定了远程服务的ip和端口,那么如何实现noVNC和远程服务器链接的任意切换呢?
答案就是通过配置文件来实现多台服务器的管理,然后通过在访问时带上为每台远程服务的唯一命名,来实现链接不同的远程服务。具体实现如下:
vi ./noVNC/vnc_token
配置格式为hostName:ip:port
,hostName,为远程服务器的名称,配置好后执行
root@instance-364se3r0:/soft/vnc/noVNC/utils/websockify# ./run --web /soft/vnc/noVNC --target-config /soft/vnc/noVNC/vnc_token 6080
/soft/vnc/noVNC/utils/websockify/websockify/websocket.py:30: UserWarning: no 'numpy' module, HyBi protocol will be slower
warnings.warn("no 'numpy' module, HyBi protocol will be slower")
WebSocket server settings:
- Listen on :6080
- Web server. Web root: /soft/vnc/noVNC
- No SSL/TLS support (no cert file)
- proxying from :6080 to targets generated by TokenFile
然后我们访问vnc.html页面
在上面红框处填写填写需要访问的远程服务器名称,noVNC服务端通过参数token来区分需要链接那台远程服务
正常情况下,我们的需求是,进入云服务管理平台后,打开对应的云服务器或容器服务列表,这时会有一个入口用来弹出命令行面板,用来操作远程服务器。但这里是不需要再次进行登陆的,我们再登陆管理平台后,相当于已经一键登陆了。显然上面的noVNC还不满足我们的要求,我们需要实现免密码登陆。如何实现呢?这里讲一下大致流程,应为这里不只涉及到前端,还需要后端服务做一些工作。
这种方案,从大体方向来说和前面提到noVNC的方案神似,主要是在中转服务端和需要访问的目标服务端之间的传输协议不同,noVNC是使用的RFB协议传输,而xtermjs+SSH2+nodejs是依赖ssh安全传输协议。整体交互模式和noVNC是一样的。
实现步骤:
这里并没有在目标服务器上安装类似vncserver一类的服务,是因为该方案是采用的SSH协议,只要我们目标服务上部署了SSH服务就OK了,正常情况下SSHserver是服务器必备的。所以该方案就不必在实现一个类似vncServer的服务了。
下面讲讲具体实现:
实现功能:
具体实现:
其实网上关于xtermjs的使用教程有很多,但是大部分只是说了一下,怎么创建显示区域,和接受输入和现实信息。和后端交互的整个流程提到的比较少,我这里结合实际功能大致提一下整个流程:
后端实现功能:
总的来说这种方式,需要对SSH工具的功能了解的比较透彻,每个功能点都需要我们用代码来实现。所以开发周期回比较长。
由于代码实现的代码量比较大,这里我就不贴代码了,贴一下我自己的一个实现webSSH仓库地址,内容目前还在进一步完善中,但是基本的流程已经完成,有需要的可以看看,欢迎大家提出意见,可以在评论中@我。
该方案,我自己没有搭建起来,在装tty.js的时候,老是报错,最后也没装上,论坛里面看了看,说是nodejs在5.X的时候就不在支持该模块内的相关方法了,现在nodejs的版本都1x.x了,而且还在不断的更新,不能向上兼容的东西,个人觉得也没有必要去弄了。
noVNC和xtermjs+SSH2的方案都有各自的优缺点,这个需要各自团队自己根据实际情况进行评估,像百度就是用noVNC,我们公司是用的后者,虽然后者可以高度定制化开发,但是坑比较多,我们现在都还在坑此坑次的填坑,目前已经有换成noVNC的想法了。公司后端是用的java不是nodejs,我自己个人搭建的时候后端选择的nodejs,毕竟我还是一个前端。
有时间就多折腾一下,了解一下总是好的。 如果你读到了这里,请别介意前面文中的"通假字",谢谢。