zoukankan      html  css  js  c++  java
  • nova分析(9)—— nova-novncproxy

    nova提供了novncproxy代理支持用户通过vnc来访问虚拟机,用户可以通过websocket、java客户端或者spicehtml5来访问。通过websket访问虚拟机的功能已经集成到horizon中,而通过java客户端则需要先安装相应的软件。为了方便用户访问虚拟机,nova通过有一个proxy来实现,proxy通常同nova-api一起部署。

    vnc访问的实现方法如下,首先是启动一个虚拟机时启用vnc,这可以通过给kvm加上vnc参数即可。这样,kvm就会启动一个vncserver监听虚拟机。通过websocket来访问虚拟时,其步骤如下:

    1. 通过nova-api获取访问url,url的格式是:http://ip:port/?token=xxx,该地址实际上就是vnc proxy的地址。
    2. 浏览器连接到vnc proxy
    3. vnc proxy连接到nova-consoleauth来验证token,并将token映射到虚拟机所在的宿主机的ip地址和某个端口,该端口就是虚拟机启动时所监听的端口。
    4. vnc proxy与虚拟机所在的宿主机的vncserver建立连接,并开始代理,直到浏览器session结束。

    在nova.conf中,计算节点可以指定vncserver的监听地址及vnc proxy应该通过那个地址连接到vncserver,该选项就是vncserver_proxyclient_address。vnc proxy充当了公网和计算节点之间的桥梁,此外还需要对vnc协议进行封装。

    vnc proxy配置方法

    通常情况下,为了提供完整的vnc功能,需要部署三个服务:

    • nova-consoleauth: 提供token验证,维护token与ip地址、端口号的映射。
    • nova-novncproxy: 支持基于浏览器的vnc 客户端,通常与nova-api部署在一起。
    • nova-xvpvncproxy: 支持基于java的vnc客户端,,通常与nova-api部署在一起。

    此外还需要对计算节点进行设当的配置。具体如下:

    • vnc_enabled=True   启用虚拟机的vnc功能。
    • vncserver_listen=0.0.0.0   默认是127.0.0.1,即只可以从本机进行访问,通常情况下是配置为管理网的IP地址。设置为0.0.0.0主要是考虑到动态迁移时,目的宿主机没有相应的IP地址,动态迁移会失败。
    • vncserver_proxyclient_address  该地址指明vnc proxy应该通过那个IP地址来连接vncserver,通常是管理网IP地址。
    • novncproxy_base_url=http://$SERVICE_HOST:6080/vnc_auto.html  指定浏览器client应该连接的地址。$SERVICE_HOST通常是一个公网IP地址。
    • xvpvncproxy_base_url=http://$SERVICE_HOST:6081/console  指定java client应该连接的地址。$SERVICE_HOST通常是一个公网IP地址。

    vnc proxy的配置则相对简单,只需要设置其监听的主机和端口即可。具体如下:

    • novncproxy_host=$SERVICE_HOST  通常为一个公网IP。
    • novncproxy_host=6080
    • xvpvncproxy_host=$SERVICE_HOST 通常为一个公网IP。
    • xvpvncproxy_port=6081

    以novncproxy为例来看看是怎么实现的:

    class NovaWebSocketProxy(websockify.WebSocketProxy):
        #继承自websockify中的WebSocketProxy,而WebSocketProxy则继承自WebSocketServer
        def __init__(self, *args, **kwargs):
            #继承父类init方法
         
        def new_client(self):
            #将会在websocket连接建立完毕后执行
            #1)从cookie中获取目标host,port
            #2)handshake as necessary
            #3)创建一个socket connect to vnc 
            #4)do_proxy
    
    def do_proxy(self, target):
        ...
        rlist = [self.client, target]#self.client是websocket连接后生成的
                             #target就是上面创建后传入的socket,连接到vnc addr
         
        while True:
            wlist = []
            if tqueue: wlist.append(target)
            if cqueue or c_pend: wlist.append(self.client)
            ins, outs, excepts = select(rlist, wlist, [], 1)
             
            if self.client in outs:
                #将数据发送给client
            if self.client in ins
                #从client接受数据
            if target in outs:
                #将client data 发送到目标vnc地址
            if target in ins:
                #从目标vnc地址接受数据

    参考文档

    http://zhengtianbao.com/?p=144

  • 相关阅读:
    js Array的方法及属性总结
    js 继承
    js 判断数据类型
    序列化和反序列化
    express 常用方法和插件
    node 常用的对象
    node.js 守护进程
    CentOS7安装Python3.8.1和ansible
    MAC终端终极美化方案
    Linux之top命令详解
  • 原文地址:https://www.cnblogs.com/feisky/p/3876151.html
Copyright © 2011-2022 走看看