在每个计算节点,设计到的配置项
[vnc]
enabled = True
vncserver_listen = 0.0.0.0
vncserver_proxyclient_address = 10.200.129.56
novncproxy_base_url =
http://10.200.129.101:6080/vnc_auto.html
控制节点
[vnc]
enabled = True
vncserver_listen = 0.0.0.0
vncserver_proxyclient_address = 0.0.0.0
如若涉及到公网映射:
计算节点:
[vnc]
enabled = True
vncserver_listen = 0.0.0.0
vncserver_proxyclient_address = 10.203.4.221
novncproxy_base_url =
http://183.136.220.18:6080/vnc_auto.html
控制节点:
[vnc]
vncserver_listen = 0.0.0.0
vncserver_proxyclient_address = 0.0.0.0
在控制节点有俩服务
nova-xvpvncproxy 6081端口,java用
nova-novncproxy 6080端口
一、流程如图

二、过程分析
VNC Proxy的功能:
- 将公网(public network)和私网(private network)隔离
- VNC client运行在公网上,VNCServer运行在私网上,VNC Proxy作为中间的桥梁将二者连接起来
- VNC Proxy通过token对VNC Client进行验证
- VNC Proxy不仅仅使得私网的访问更加安全,而且将具体的VNC Server的实现分离,可以支持不同Hypervisor的VNC Server但不影响用户体验
VNC Proxy的部署
- 在Controller节点上部署nova-consoleauth 进程,用于Token验证
- 在Controller节点上部署nova-novncproxy 服务,用户的VNC Client会直接连接这个服务
- Controller节点一般有两张网卡,连接到两个网络,一张用于外部访问,我们称为public network,或者API network,这张网卡的IP地址是外网IP,如图中172.24.1.1,另外一张网卡用于openstack各个模块之间的通信,称为management network,一般是内网IP,如图中10.10.10.2
- 在Compute节点上部署nova-compute,在nova.conf文件中有下面的配置
- vnc_enabled=True
- vncserver_listen=0.0.0.0 //VNC Server的监听地址
- vncserver_proxyclient_address=10.10.10.2 //nova vnc proxy是通过内网IP来访问vnc server的,所以nova-compute会告知vnc proxy用这个IP来连接我。
- novncproxy_base_url=http://172.24.1.1:6080/vnc_auto.html //这个url是返回给客户的url,因而里面的IP是外网IP
- 注:
也可以将控制节点放在内网,专门设置一个api节点,这时,nova-consoleauth就需要安装在控制节点上,novnc
python-novnc包安装在api节点上。
VNC Proxy的运行过程:
- 一个用户试图从浏览器里面打开连接到虚拟机的VNC Client
- 浏览器向nova-api发送请求,要求返回访问vnc的url
- nova-api调用nova-compute的get vnc console方法,要求返回连接VNC的信息
- nova-compute调用libvirt的get vnc console函数
- libvirt会通过解析虚拟机运行的/etc/libvirt/qemu/instance-0000000c.xml文件来获得VNC Server的信息
- libvirt将host, port等信息以json格式返回给nova-compute
- nova-compute会随机生成一个UUID作为Token
- nova-compute将libvirt返回的信息以及配置文件中的信息综合成connect_info返回给nova-api
- nova-api会调用nova-consoleauth的authorize_console函数
- nova-consoleauth会将instance –> token, token –> connect_info的信息cache起来
- nova-api将connect_info中的access url信息返回给浏览器:http://172.24.1.1:6080/vnc_auto.html?token=7efaee3f-eada-4731-a87c-e173cbd25e98&title=helloworld%289169fdb2-5b74-46b1-9803-60d2926bd97c%29
- 浏览器会试图打开这个链接
- 这个链接会将请求发送给nova-novncproxy
- nova-novncproxy调用nova-consoleauth的check_token函数
- nova-consoleauth验证了这个token,将这个instance对应的connect_info返回给nova-novncproxy
- nova-novncproxy通过connect_info中的host, port等信息,连接compute节点上的VNC Server,从而开始了proxy的工作
三、源码分析
按照过程分析:
浏览器带上vm的uuid作为参数向nova-api请求,要求返回vnc的url,
2~3:nova-api后台的响应函数为 //nova/api/openstack/compute/remote_console.py,会调用nova-compute,要求返回连接vnc的信息
4~8:nova-compute响应函数为//nova/compute/api.py,会调用libvirt,返回给nova-api
//nova/compute/rpcapi.py
上面的cctxt.call的远程调用的相应函数为//nova/compute/manager.py
//nova/virt/libvirt/driver.py 读取xml
//nova/consoleauth/rpcapi.py
上面cctxt.call函数的响应函数为//nova/consoleauth/manager.py
以上步骤完成1-12,13-16由//nova/console/websocketproxy.py