1.Nova介绍

Nova是openstack最早的两块模块之一,另一个是对象存储swift。在openstack体系中一个叫做计算节点,一个叫做控制节点。这个主要和nova相关,我们把安装为计算节点成为:nova-compute,把除了nova-compute叫做控制节点。nova-compute是创建虚拟机的,只是创建虚拟机,所有的控制都在另一台上。
OpenStack计算组件请求OpenStack Identity服务进行认证;请求OpenStack Image服务提供磁盘镜像;为OpenStack dashboard提供用户与管理员接口。

nova服务的功能和特点:
实例生命周期的管理
管理计算资源
网络和认证管理
REST风格的API
异步的一致性通信
Hypervisor透明:支持Xen,XenServer/XCP,KVM,UML,VMware vSphere and Hyper-V

2.OpenStack计算服务架构:

Nova API:负责接收和响应外部请求。支持Openstack API,EC2 API。外部访问Nova的唯一途径,接受外部请求并通过Message Queue将请求发送给其他的服务组件。

Nova Scheduler:用于云主机调度,决策虚拟机创建应该创建在哪个计算节点上。决策一个虚拟机应该调度到某个物理节点上,需要两步:过滤,计算权值。

Nova Compute:一般运行在计算节点上,通过Message Queue接收并管理KVM的生命周期,Nova compute通过libvirt管理 KVM,通过XenAPI管理Xen。管理虚机的核心服务,通过调用 Hypervisor API 实现虚机生命周期管理。

Hypervisor :计算节点上跑的虚拟化管理程序,虚机管理最底层的程序。 不同虚拟化技术提供自己的 Hypervisor。常用的 Hypervisor 有 KVM,Xen, VMWare 等。

Nova Conductor:计算节点访问数据库的中间件。nova-compute 经常需要更新数据库,比如更新虚机的状态。 
出于安全性和伸缩性的考虑,nova-compute 并不会直接访问数据库,而是将这个任务委托给 nova-conductor。

Nova Consoleauth:用于控制台的授权验证,需要打开vnc需要在Consoleauth进行授权认证。负责对访问虚机控制台请亲提供 Token 认证。

Nova Novncporxy:提供一个代理,用于访问正在运行的实例。通过VNC协议,基于 Web 浏览器的 VNC 访问 。

Nova-spicehtml5proxy:基于 HTML5 浏览器的 SPICE 访问 

Nova-x***vncproxy:基于 Java 客户端的 VNC 访问

Nova Cert:服务器守护进程向Nova Cert服务提供X509证书。用来为euca-bundle-image生成证书。仅仅是在EC2 API的请求中使用。

消息队列:在守护进程之间传递消息的中心。通常使用RabbitMQ实现,也可以使用另一个AMQP消息队列(如ZeroMQ)来实现。在前面我们了解到 Nova 包含众多的子服务,这些子服务之间需要相互协调和通信。 为解耦各个子服务,Nova 通过 Message Queue 作为子服务的信息中转站。

SQL数据库:Nova 会有一些数据需要存放到数据库中。存储云主机在构建时和运行时的状态,为云基础设施,包括有:可用实例类型、使用中的实例、可用网络、项目

3.计算节点的Nova服务部署与测试

(1)修改配置文件/etc/nova/nova.conf

在[DEFAULT]部分,只启用计算和元数据API:

[DEFAULT]
...
enabled_apis = osapi_compute,metadata
在[api_database]和[database]部分,配置数据库的连接:

[api_database]
...
connection = mysql+pymysql://nova:nova@192.168.56.11/nova_api

[database]
...
connection = mysql+pymysql://nova:nova@192.168.56.11/nova

在[DEFAULT]部分,配置RabbitMQ消息队列访问权限:

[DEFAULT]
...
transport_url = rabbit://openstack:openstack@192.168.56.11


在 “[DEFAULT]” 和 “[keystone_authtoken]” 部分,配置认证服务访问:

[DEFAULT]
...
auth_strategy = keystone

[keystone_authtoken]
...
auth_uri = http://192.168.56.11:5000
auth_url = http://192.168.56.11:35357
memcached_servers = 192.168.56.11:11211
auth_type = password
project_domain_name = default
user_domain_name = default
project_name = service
username = nova
password = nova
在 [DEFAULT]部分,启用网络服务支持:

[DEFAULT]
...
use_neutron = True
firewall_driver = nova.virt.firewall.NoopFirewallDriver -->关闭nova防火墙

tips:
默认情况下,计算服务使用内置的防火墙服务。由于网络服务包含了防火墙服务,你必须使用nova.virt.firewall.NoopFirewallDriver防火墙服务来禁用掉计算服务内置的防火墙服务

在[vnc]部分,配置VNC代理使用控制节点的管理接口IP地址 :

[vnc]
...
vncserver_listen = 0.0.0.0
vncserver_proxyclient_address = 192.168.56.11

在 [glance] 区域,配置镜像服务 API 的位置:

[glance]
...
api_servers = http://192.168.56.11:9292

在 [oslo_concurrency] 部分,配置锁路径:

[oslo_concurrency]
...
lock_path = /var/lib/nova/tmp

查看所有配置项:

[root@linux-node1 ~]# grep "^[a-z]" /etc/nova/nova.conf 
auth_strategy=keystone                        #启用keystone进行认证
use_neutron=True                                 #启用网络服务
enabled_apis=osapi_compute,metadata              #启用计算和元数据
firewall_driver = nova.virt.firewall.NoopFirewallDriver
transport_url=rabbit://openstack:openstack@192.168.56.11
connection=mysql+pymysql://nova:nova@192.168.56.11/nova_api
connection=mysql+pymysql://nova:nova@192.168.56.11/nova
api_servers=http://192.168.56.11:9292
auth_uri = http://192.168.56.11:5000
auth_url = http://192.168.56.11:35357
memcached_servers = 192.168.56.11:11211
auth_type = password
project_domain_name = default
user_domain_name = default
project_name = service
username = nova
password = nova
lock_path=/var/lib/nova/tmp
vncserver_listen=0.0.0.0
vncserver_proxyclient_address=192.168.56.11

(2)同步数据库

[root@linux-node1 ~]# su -s /bin/sh -c "nova-manage api_db sync" nova
[root@linux-node1 ~]# su -s /bin/sh -c "nova-manage db sync" nova

同步第二个操作时会有一个WARNING,属于正常。验证查看数据库是否有表
[root@linux-node1 ~]# mysql -h 192.168.56.11 -unova -pnova -e "use nova;show tables;"
[root@linux-node1 ~]# mysql -h 192.168.56.11 -unova -pnova -e "use nova_api;show tables;"

(3)完成安装,启动compute服务并设置开机自启

[root@linux-node1 ~]# systemctl enable openstack-nova-api.service   openstack-nova-consoleauth.service openstack-nova-scheduler.service   openstack-nova-conductor.service openstack-nova-novncproxy.service

[root@linux-node1 ~]#  systemctl start openstack-nova-api.service   openstack-nova-consoleauth.service openstack-nova-scheduler.service   openstack-nova-conductor.service openstack-nova-novncproxy.service

(4)创建服务实体,并在keystone上注册

[root@linux-node1 ~]# openstack service create --name nova   --description "OpenStack Compute" compute
+-------------+----------------------------------+
| Field       | Value                            |
+-------------+----------------------------------+
| description | OpenStack Compute                |
| enabled     | True                             |
| id          | 200e9f78a4654e0394eec200c4dab31d |
| name        | nova                             |
| type        | compute                          |
+-------------+----------------------------------+

[root@linux-node1 ~]# openstack endpoint create --region RegionOne   compute public http://192.168.56.11:8774/v2.1/%\(tenant_id\)s
+--------------+----------------------------------------------+
| Field        | Value                                        |
+--------------+----------------------------------------------+
| enabled      | True                                         |
| id           | dfb98d75fe7e44da898280d48e331a63             |
| interface    | public                                       |
| region       | RegionOne                                    |
| region_id    | RegionOne                                    |
| service_id   | 200e9f78a4654e0394eec200c4dab31d             |
| service_name | nova                                         |
| service_type | compute                                      |
| url          | http://192.168.56.11:8774/v2.1/%(tenant_id)s |
+--------------+----------------------------------------------+

[root@linux-node1 ~]# openstack endpoint create --region RegionOne   compute internal http://192.168.56.11:8774/v2.1/%\(tenant_id\)s
+--------------+----------------------------------------------+
| Field        | Value                                        |
+--------------+----------------------------------------------+
| enabled      | True                                         |
| id           | a656fdf0dce34db39fdce5c3fd3d3e40             |
| interface    | public                                       |
| region       | RegionOne                                    |
| region_id    | RegionOne                                    |
| service_id   | 200e9f78a4654e0394eec200c4dab31d             |
| service_name | nova                                         |
| service_type | compute                                      |
| url          | http://192.168.56.11:8774/v2.1/%(tenant_id)s |
+--------------+----------------------------------------------+
[root@linux-node1 ~]# openstack endpoint create --region RegionOne   compute admin http://192.168.56.11:8774/v2.1/%\(tenant_id\)s
+--------------+----------------------------------------------+
| Field        | Value                                        |
+--------------+----------------------------------------------+
| enabled      | True                                         |
| id           | 85a0a9b5d4db449cab48b7c033aabac3             |
| interface    | admin                                        |
| region       | RegionOne                                    |
| region_id    | RegionOne                                    |
| service_id   | 200e9f78a4654e0394eec200c4dab31d             |
| service_name | nova                                         |
| service_type | compute                                      |
| url          | http://192.168.56.11:8774/v2.1/%(tenant_id)s |
+--------------+----------------------------------------------+
[root@linux-node1 ~]# openstack service list
[root@linux-node1 ~]# openstack endpoint list

(5)验证nova服务是否正常

[root@linux-node1 ~]# openstack host list
+-------------+-------------+----------+
| Host Name   | Service     | Zone     |
+-------------+-------------+----------+
| linux-node1 | consoleauth | internal |
| linux-node1 | conductor   | internal |
| linux-node1 | scheduler   | internal |
+-------------+-------------+----------+

[root@linux-node1 ~]# nova service-list
+----+------------------+-------------+----------+---------+-------+----------------------------+-----------------+
| Id | Binary           | Host        | Zone     | Status  | State | Updated_at                 | Disabled Reason |
+----+------------------+-------------+----------+---------+-------+----------------------------+-----------------+
| 1  | nova-consoleauth | linux-node1 | internal | enabled | up    | 2017-12-12T02:50:09.000000 | -               |
| 2  | nova-conductor   | linux-node1 | internal | enabled | up    | 2017-12-12T02:50:06.000000 | -               |
| 3  | nova-scheduler   | linux-node1 | internal | enabled | up    | 2017-12-12T02:50:05.000000 | -               |
+----+------------------+-------------+----------+---------+-------+----------------------------+-----------------+

4.配置总结:

①数据库连接配置

②RabbitMQ连接配置

③Keystone认证配置

④token缓存配置

⑤glance-api访问配置

⑥防火墙关闭、元数据访问、网络启用配置

⑦锁路径以及VNC代理配置

5.Nova组件如何协调工作?

对于 Nova,这些服务会部署在两类节点上:计算节点和控制节点。 
计算节点上安装了 Hypervisor,上面运行虚拟机。 
由此可知:

  1. 只有 nova-compute 需要放在计算节点上。
  2. 其他子服务则是放在控制节点上的。

通过在计算节点(node2)和控制节点(node1)上运行 ps -elf|grep nova 来查看运行的 nova 子服务

[root@linux-node1 ~]# ps -e |grep nova
 1026 ?        00:15:02 nova-scheduler
 1027 ?        00:13:52 nova-consoleaut
 1028 ?        01:24:20 nova-conductor
 1147 ?        00:02:41 nova-novncproxy
 1564 ?        00:22:51 nova-compute
 3240 ?        01:23:54 nova-api
 3250 ?        00:02:20 nova-api
 3252 ?        00:00:01 nova-api

[root@linux-node2 ~]# ps -e |grep nova
 1310 ?        00:28:50 nova-compute

从上面的查询结果上看,我们发现在在控制节点(node1)上也有一个nova-compute,这就意味着node1 既是一个控制节点,同时也是一个计算节点,也可以在上面运行虚机。我们可以通过nova service-list来查看 nova-* 子服务都分布在哪些节点上。

下面我们从虚拟机创建的流程上看nova的组件服务是如何工作的

OpenStack入门篇(九)之nova服务(控制节点)的部署与测试_linux

①客户向API(nova-api)发送请求:我需要创建一个虚拟机;

②API 对请求进行响应处理,向消息队列(RabbitMQ)发送了一条消息:“让 Scheduler 创建一个虚机”;

③Scheduler(nova-scheduler)监听消息队列获取到 API 发给它的消息,然后执行调度算法,从若干计算节点中选出合适的节点A;

④Scheduler 向 消息队列发送了一条消息:“在计算节点 A 上创建这个虚机”;

⑤计算节点 A 的 Compute(nova-compute)从消息队列中获取到 Scheduler 发给它的消息,然后在本节点的 Hypervisor 上启动虚机。

⑥在虚机创建的过程中,Compute 如果需要查询或更新数据库信息,会通过消息队列向 Conductor(nova-conductor)发送消息,Conductor 负责数据库访问。

6.openstack设计思路(转)


(1)API 前端服务
OpenStack是一个组件复杂的平台,每个组件都包含这若干的子服务,其中每个服务中必定会有一个API负责接收外部请求。

以 Nova 为例,nova-api 是作为 Nova 组件对外的唯一窗口,向User暴露 Nova 能够提供的功能。 
当User需要执行虚机相关的操作,能且只能向 nova-api 发送 REST 请求。 
这里的客户包括终端用户、命令行和 OpenStack 其他组件。

设计 API 前端服务的好处在于:

  1. 对外提供统一接口,隐藏实现细节
  2. API 提供 REST 标准调用服务,便于与第三方系统集成
  3. 可以通过运行多个 API 服务实例轻松实现 API 的高可用,比如运行多个 nova-api 进程

(2)Scheduler 调度服务
对于某项操作,如果有多个实体都能够完成任务,那么通常会有一个 scheduler 负责从这些实体中挑选出一个最合适的来执行操作。

在前面的例子中,Nova 有多个计算节点。 
当需要创建虚机时,nova-scheduler 会根据计算节点当时的资源使用情况选择一个最合适的计算节点来运行虚机。

调度服务就好比是一个开发团队中的项目经理,当接到新的开发任务时,项目经理会评估任务的难度,考察团队成员目前的工作负荷和技能水平,然后将任务分配给最合适的开发人员。

(3)Worker 工作服务
调度服务只管分配任务,真正执行任务的是 Worker 工作服务。

在 Nova 中,这个 Worker 就是 nova-compute 了。 
将 Scheduler 和 Worker 从职能上进行划分使得 OpenStack 非常容易扩展:

当计算资源不够了无法创建虚机时,可以增加计算节点(增加 Worker)
当客户的请求量太大调度不过来时,可以增加 Scheduler

(4)Driver 框架
OpenStack 作为开放的 Infrastracture as a Service 云操作系统,支持业界各种优秀的技术。 
这些技术可能是开源免费的,也可能是商业收费的。 
这种开放的架构使得 OpenStack 能够在技术上保持先进性,具有很强的竞争力,同时又不会造成厂商锁定(Lock-in)。

那 OpenStack 的这种开放性体现在哪里呢? 
一个重要的方面就是采用基于 Driver 的框架。

以 Nova 为例,OpenStack 的计算节点支持多种 Hypervisor。 
包括 KVM, Hyper-V, VMWare, Xen, Docker, LXC 等。

Nova-compute 为这些 Hypervisor 定义了统一的接口,hypervisor 只需要实现这些接口,就可以 driver 的形式即插即用到 OpenStack 中。 

下面是 nova driver 的架构示意图

OpenStack入门篇(九)之nova服务(控制节点)的部署与测试_mysql_02


在 nova-compute 的配置文件 /etc/nova/nova.conf 中由 compute_driver 配置项指定该计算节点使用哪种 Hypervisor 的 driver

OpenStack入门篇(九)之nova服务(控制节点)的部署与测试_linux_03

在我们的环境中因为是 KVM,所以配置的是 Libvirt 的 driver。

不知大家是否还记得我们在学习 Glance 时谈到: 
OpenStack 支持多种 backend 来存放 image。 
可以是本地文件系统,Cinder,Ceph,Swift 等。

其实这也是一个 driver 架构。 
只要符合 Glance 定义的规范,新的存储方式可以很方便的加入到 backend 支持列表中。

(5)消息队列服务
在前面创建虚机的流程示意图中,我们看到 nova- 子服务之间的调用严重依赖 消息队列服务。 
消息队列是 nova-
 子服务交互的中枢。

以前没接触过分布式系统的同学可能会不太理解为什么不让 API 直接调用Scheduler,或是让Scheuler 直接调用 Compute,而是非要通过 Messaging 进行中转。 
这里做一些解释。

程序之间的调用通常分两种:同步调用和异步调用。

同步调用 
API 直接调用 Scheduler 的接口就是同步调用。 
其特点是 API 发出请求后需要一直等待,直到 Scheduler 完成对 Compute 的调度,将结果返回给 API 后 API 才能够继续做后面的工作。

异步调用 
API 通过 Messaging 间接调用 Scheduler 就是异步调用。 
其特点是 API 发出请求后不需要等待,直接返回,继续做后面的工作。 
Scheduler 从 Messaging 接收到请求后执行调度操作,完成后将结果也通过 Messaging 发送给 API。

在 OpenStack 这类分布式系统中,通常采用异步调用的方式,其好处是:

解耦各子服务 
子服务不需要知道其他服务在哪里运行,只需要发送消息给 Messaging 就能完成调用。

提高性能 
异步调用使得调用者无需等待结果返回。这样可以继续执行更多的工作,提高系统总的吞吐量。

提高伸缩性 
子服务可以根据需要进行扩展,启动更多的实例处理更多的请求,在提高可用性的同时也提高了整个系统的伸缩性。而且这种变化不会影响到其他子服务,也就是说变化对别人是透明的。

(6)Database
OpenStack 各组件都需要维护自己的状态信息。 
比如 Nova 中有虚机的规格、状态,这些信息都是在数据库中维护的。 
每个 OpenStack 组件在 MySQL 中有自己的数据库。

Don't forget the beginner's mind