【云桌面】novnc远程连接桌面部署讲解与一键部署脚本

2,531 阅读4分钟

背景

最近公司在做云桌面的项目,其中一个需求是通过web页面访问虚拟机,领导丢了一句话“用novnc实现”就走了,留我一个前端码农在风中凌乱。
作为一枚前端,别说novnc,就连Linux命令也没敲过两行,但是看看部门就几个兄弟,这一个大项目就指着我们来做,心中默念“合理的要求是锻炼,不合理的要求是历练”,赶鸭子上架也得上,于是开始研究novnc到底是何方神圣。

预研

经过预研,总结了几个要点:
1、novnc可以作为网页连接虚拟机/PC的一个通道,让用户不需要安装额外的客户端就能进入虚拟机/PC
2、novnc通道的实现需要一个叫websockify的代理服务,Websockify会将网页发出的WebSocket消息转成tcp,以此进行和虚拟机/PC通信
3、为了实现整个流程,还需要在虚拟机/PC上安装nvc server,本项目中使用Tightvnc

两种方案

经过两天恶补知识,知道了novnc的实现有两种方案:

  • 方案一:每台虚拟机/PC都部署noVNC代理服务(即websockify),每台虚拟机/PC都安装VNC通信工具(即Tightvnc),可理解为一对一
    优势:支持全部都是Windows的场景
    劣势:部署复杂
  • 方案二:一台虚拟机/PC部署noVNC服务做代理服务器,每台虚拟机/PC都安装VNC通信工具,可理解为一对多
    优势:部署简单
    劣势:本方案需要代理服务,Windows不支持noVNC的代理服务,所以需要一台Linux服务器

方案二的拓扑图如下:
image.png

开始部署

工欲善其事,必先利其器,我们先准备好需要的设备和工具:

  • 一台CentOS 8(可根据实际情况调整),用于部署noVNC代理服务websockify
  • n台Windows,
  • Tightvnc,用于安装在Windows上,下载地址:www.tightvnc.com/download.ph…

安装python3环境

因为websockify需要在python3环境运行,所以先查看CentOS是否有python3环境

python -V
or
python3 -V

如果没有python环境, 请按如下步骤安装
建议先把python下载到本地:www.python.org/ftp/python/…

yum -y install gcc gcc-c++

yum -y install gcc automake autoconf libtool make

yum groupinstall -y 'Development Tools'

yum install -y gcc openssl-devel bzip2-devel libffi-devel

cd /root
wget https://www.python.org/ftp/python/3.8.2/Python-3.8.2.tgz
# 也可以到python官⽹下载版本:https://www.python.org/downloads/
tar -zxvf Python-3.8.2.tgz

cd Python-3.8.2

#进⼊解压后的Python⽬录,⽤脚本检验整个编译环境
./configure prefix=/usr/local/python3 --enable-optimizations

# ⽤make命令编译安装
make && make install

# 修改环境变量
export PATH=$PATH:/usr/local/python3/bin/

# 安装pip
curl https://bootstrap.pypa.io/get-pip.py -o get-pip.py
python3 get-pip.py

# 安装完成,测试是否成功
python3 -V

Windows安装Tightvnc

安装包一路next,根据实际情况设置。此处用默认设置,即端口是5900,连接不加密。

Linux上部署代理服务

拉取noVNC代码,如果是内网环境,请用其他设备下载后再传到CentOS

cd /data
yum install git -y
git clone https://github.com/novnc/noVNC.git
cd noVNC

记录每一台PC的信息

# 创建token.conf文件
vi /data/noVNC/token.conf

# token.conf格式如下:
# PC_NAME: PC_IP:port
# 解释:PC_NAME 是对每一台PC的命名(全局唯一),PC_IP是每一台PC的IP,port是PC上vnc server的端口(默认是5900)。"PC_NAME:"和"PC_IP"中间有个空格
# 例如:
# name1: 192.168.1.123:5900

配置后保存退出。实际项目中写token.conf文件可由业务代码来完成。
下载websckify项目至utils目录下

cd /data/noVNC/utils
git clone https://github.com/novnc/websockify.git

执行启动代理服务命令

/data/noVNC/utils/websockify/run --web=/data/noVNC --target-config=/data/noVNC/token.conf 6080

字段解释: /noVNC/utils/websockify/run指的是websockify目录下的run指令
--web指的是noVNC文件夹的根目录
--target-config指的是token配置文件的路径
6080是noVNC默认端口
至此,noVNC服务搭建完成。

启动停止服务脚本

上面那样是非后台运行,会导致无法敲其他命令和断开后服务就停止,现在我们来写启动脚本,让服务在后台运行。

vi /data/noVNC/novnc_start.sh

# 启动脚本内容如下:
#!/bin/bash
/data/noVNC/utils/websockify/run --web=/data/noVNC --target-config=/data/noVNC/token.conf 6080&

# 保存后把文件修改为可执行
chmod +x /data/noVNC/novnc_start.sh

有了启动脚本就需要停止脚本,不然就无法停止服务,停止脚本如下

vi /data/noVNC/novnc_stop.sh

# 停止脚本如下:
pgrep -f python | xargs kill -9

# 保存后把文件修改为可执行
chmod +x /data/noVNC/novnc_stop.sh

开机自启动

vi /etc/rc.d/rc.local

#文件尾添加两行:
export PATH=$PATH:/usr/local/python3/bin/
/data/noVNC/novnc_start.sh

#添加后保存退出,设置权限
chmod +x /etc/rc.d/rc.local

至此服务全部部署完成,可在网页访问token.conf配置的pc了

服务器访问

浏览器输入如下地址即可访问对应的虚拟机/PC:

http://代理服务IP:6080/vnc.html?path=websockify/?token=name1

其中 name1 是在 token.conf 里配置的PC名称。
打开后界面如下,点击连接即可进入桌面 image.png
如果无法访问,请检查CentOS的防火墙设置,需要把6080端口开放。

输出部署脚本

完成整个流程的我看着复杂的步骤陷入沉思,如果每次都要人工操作,996就不是梦了。为了让部门的兄弟们早点下班,我紧急花了半天时间学习shell语法,再根据以上部署步骤,编写了一键部署脚本。
在虚拟机上任意目录(建议/root)创建文件novnc-server-install.sh,文件内容如下,其中port和dir可根据项目要求配置

#!/bin/bash

# 代理服务端口
port=6080
# novnc代码安装路径
dir=/data

function go_on_or_cancel(){
    echo "上一条命令执行失败,是否继续执行?"
    read -p "y继续执行,ctrl+c停止:" yn
    echo "输入的是$yn"
    if [ $yn = 'y' ]
      then
        echo 继续执行
      else
        echo 重新输入
        go_on_or_cancel
    fi
}

function success_or_fail(){
  if [ $? -eq 0 ]
  then
    echo 成功,开始执行下一条命令
  else
    go_on_or_cancel
  fi
}


echo ------------------------------------
echo 安装python步骤开始
echo ------------------------------------

echo 安装gcc gcc-c++

yum -y install gcc gcc-c++
  success_or_fail


echo 安装install gcc automake autoconf libtool make
yum -y install gcc automake autoconf libtool make
  success_or_fail


echo 安装'Development Tools'
yum groupinstall -y 'Development Tools'
  success_or_fail


echo 安装gcc openssl-devel bzip2-devel libffi-devel
yum install -y gcc openssl-devel bzip2-devel libffi-devel
  success_or_fail

cd /root

echo 远程拉取python包

wget https://www.python.org/ftp/python/3.8.2/Python-3.8.2.tgz
  success_or_fail

echo 解压
tar -zxvf Python-3.8.2.tgz 

cd Python-3.8.2

echo 进入解压后的Python目录,用脚本检验整个编译环境
./configure prefix=/usr/local/python3 --enable-optimizations
  success_or_fail

echo 用make命令编译安装
make && make install
  success_or_fail

echo ------------------------------------
echo 修改环境变量
#export PATH=$PATH:/usr/local/python3/bin/
cat>>/etc/profile<<EOF
export PATH=$PATH:/usr/local/python3/bin/
EOF
  success_or_fail
source /etc/profile
echo ------------------------------------

echo 安装pip
curl https://bootstrap.pypa.io/get-pip.py -o get-pip.py
python3 get-pip.py
  success_or_fail

echo ------------------------------------
echo 安装完成,python版本是:
python3 -V
echo 马上开始安装novnc代理服务,请稍等……
sleep 3s
echo ------------------------------------



echo ------------------------------------
echo 部署novnc代理服务
echo ------------------------------------

cd $dir
yum install git -y
success_or_fail

git clone https://github.com/novnc/noVNC.git
success_or_fail
cd noVNC
touch $dir/noVNC/token.conf

cd $dir/noVNC/utils
git clone https://github.com/novnc/websockify.git
success_or_fail

# $dir/noVNC/utils/websockify/run --web=$dir/noVNC --target-config=$dir/noVNC/token.conf $port &
# success_or_fail


echo ------------------------------------
echo 开放novnc代理服务端口
firewall-cmd --permanent --add-port=$port/tcp
firewall-cmd --permanent --list-ports
firewall-cmd --reload
echo ------------------------------------

echo ------------------------------------
echo 创建/覆盖novnc代理服务启动脚本
cat>$dir/noVNC/novnc_start.sh<<EOF
#!/bin/bash
$dir/noVNC/utils/websockify/run --web=$dir/noVNC --target-config=$dir/noVNC/token.conf $port&
EOF
echo ------------------------------------


echo ------------------------------------
echo 创建/覆盖novnc代理服务停止脚本
cat>$dir/noVNC/novnc_stop.sh<<EOF
pgrep -f python | xargs kill -9
EOF
echo ------------------------------------

echo ------------------------------------
echo 添加开机自启动配置
echo 往/etc/rc.d/rc.local追加内容
cat>>/etc/rc.d/rc.local<<EOF
# 开机后 /etc/rc.d/rc.local 比 /etc/profile 先执行,故需要先配置环境变量
export PATH=$PATH:/usr/local/python3/bin/
$dir/noVNC/novnc_start.sh
EOF
echo ------------------------------------

chmod +x /etc/rc.d/rc.local
chmod +x $dir/noVNC/novnc_start.sh
chmod +x $dir/noVNC/novnc_stop.sh


echo ------------------------------------
$dir/noVNC/novnc_start.sh
echo 正在启动novnc代理服务
sleep 3s
echo ------------------------------------

echo ------------------------------------
echo novnc代理服务部署完成
echo 检测端口进程
lsof -i:$port
echo ''
echo "请到$dir/noVNC/token.conf添加pc配置"
echo token.conf配置格式如:
echo pcname1: pcip:vncport
echo 示例:
echo winserver-ad: 192.168.1.123:5900
echo ------------------------------------

echo ------------------------------------
echo 请检查 /etc/rc.d/rc.local 内没有重复的配置
echo ------------------------------------

一键部署脚本中增加了报错判断,如果报错需要人工介入,选择继续执行还是取消执行,这边建议取消执行,避免影响后面的步骤。
用上了脚本就不用担心兄弟们粗心大意了,节省下来的时间摸鱼不香吗?

如果这一篇对大家有用希望鼓励一下吼,接下来准备把虚拟化平台ovirt的知识也搬到掘金来分享~