Nova Conductor服务

Nova Conductor服务的大部分方法都是数据库的查询操作(/nova/conductor/manager.py ConductorManager类)。主

作用是避免Nova Compute服务直接访问数据库,增加系统的安全性。


一、引入nova conductor服务

1、nova compute服务的数据库查询更新操作都需要通过向nova conductor服务发送RPC请求来实现。

2、在创建Nova Compute服务的Service对象时,会调用conductor_api的wait_until_ready方法等待nova conductor服

务完成初始化工作。以下是Service类的初始化代码片段(/nova/service.py)。

class Service(service.Service):
    def __init__(self, host, binary, topic, manager, report_interval=None,
                 periodic_enable=None, periodic_fuzzy_delay=None,
                 periodic_interval_max=None, db_allowed=True,
                 *args, **kwargs):
        ...
		#创建conductor_api对象
        self.conductor_api = conductor.API(use_local=db_allowed)
		#等待nova conductor服务开始工作
        self.conductor_api.wait_until_ready(context.get_admin_context())

初始化方法中,有一个与conductor_api相关的重要参数db_allowed,指定服务是否有访问数据库的权限。

db_allowed默认值是True。nova compute服务的启动脚本(/bin/nova-compute),显式设置参数为False。

注意:nova scheduler启动脚本中,没有显式设置db_allowed参数。因此,db_allowed的值为默认值True。所以,具

有访问数据库的权限。

二、conductor.API方法

conductor.API方法定义如下:

def API(*args, **kwargs):
	#获取外部传入的use_local参数
    use_local = kwargs.pop('use_local', False)
	#如果nova.conf配置文件中配置了use_local配置项为True
	#或者外部传入的use_local参数为True,则使用LocalAPI对象
    if oslo_config.cfg.CONF.conductor.use_local or use_local:
        api = conductor_api.LocalAPI
	#否则创建远程API对象
    else:
        api = conductor_api.API
    return api(*args, **kwargs)

API方法检查nova.conf配置文件中的use_local配置项和use_local参数。如果 use_local配置项和use_local参数为

True,则为Nova服务创建LocalAPI对象;否则创建远程API对象。

注意:nova.conf配置文件use_local配置项默认值False。conductor.API方法会为nova compute服务创建远程API对

象;由于nova scheduler服务传入的use_local值为True,为nova scheduler服务创建Local API对象。

三、conductor_api对象的定义

Nova服务的conductor_api对象的类型可能是LocalAPI对象或者API类。LocalAPI类和API类初始化方法和

wait_until_ready方法。

1、LocalAPI类

LocalAPI类的初始化方法定义如下:

class LocalAPI(object):
    def __init__(self):
        self._manager = utils.ExceptionHelper(manager.ConductorManager())
(1)创建了一个ConductorManager对象。  在ConductorManager类中,定义许多数据库访问的方法,这些方法都在本

机建立与数据库的连接。

(2)LocalAPI类定义了许多接口方法供Nova其他服务(Nova Scheduler)调用,底层都是直接调用ConductorManager

对象中定义的相应的方法,并没有向nova conductor服务发送RPC请求。

注意:Nova Scheduler服务使用的conductor_api是LocalAPI对象。当Nova Scheduler调用conductor_api访问数据库

时,直接在本地建立与数据库的连接。因此Nova Scheduler服务的运行并不依赖nova conductor服务。

(3)既然不依赖nova conductor服务,nova scheduler没有必要等待nova conductor服务开始运行。实现代码重用,

创建nova scheduler服务对象时,调用conductor_api的wait_until_ready方法。 LocalAPI类为空。

2、远程API方法

远程API类的初始化方法定义:

class API(LocalAPI):
    def __init__(self):
        self._manager = rpcapi.ConductorAPI()
(1)创建了一个Conductor RPC API对象。Conductor RPC API类中定义许多接口方法向nova conductor发送RPC请求。

而nova consuctor服务处理RPC请求的manager对象是一个ConductorManager对象。API类中定义的接口方法底层会调

用Conductor RPC API对象中相应的方法。

注意:

(1)默认,nova compute服务使用的conductor_api是API对象。当nova compute调用conductor_api访问数据库时,会

通过Conductor RPC服务向Nova Conductor服务发送RPC请求。因此conpute服务依赖于conductor服务。

(2)既然nova compute服务访问数据库需要通过nova conductor服务中转,效率比nova scheduler服务低。


(2)创建Nova Compute服务对象时,调用API对象的wait_until_ready方法,定义如下:

class API(LocalAPI):
    def wait_until_ready(self, context, early_timeout=10, early_attempts=10):
        #尝试次数
        attempt = 0
	#请求等待时间
        timeout = early_timeout
        
        has_timedout = False
	#不断尝试ping Nova conductor服务
        while True:
            #如果尝试此时达到early_attempts,则不设置RPC请求等待时间
            if attempt == early_attempts:
                timeout = None
            attempt += 1

            try:
		#尝试向nova conductor服务发送RPC请求
                self.base_rpcapi.ping(context, '1.21 GigaWatts',
                                      timeout=timeout)
                if has_timedout:
                    LOG.info(_LI('nova-conductor connection '
                                 'established successfully'))
		#如果请求成功,说明nova conductor服务正常工作,结束循环
                break
	    #如果请求失败,进入下一个循环,继续发送RPC请求
            except messaging.MessagingTimeout:
                has_timedout = True
                LOG.warning(_LW('Timed out waiting for nova-conductor.  '
                                'Is it running? Or did this service start '
                                'before nova-conductor?  '
                                'Reattempting establishment of '
                                'nova-conductor connection...'))
不断向Nova Conductor服务发送ping RPC请求。当请求等待正常响应时,则认为nova conductor服务已经正常工作

了。nova conductor服务最终会把ping RPC请求交给ConductorManager对象的ping方法处理。


总结:

1、创建虚拟机请求的处理流程

通过虚拟机创建请求,分析Nova API、Nova Scheduler和Nova Compute服务的工作和协作机制。

虚拟机创建请求的处理流程:

Nova Conductor服务_第1张图片

servers资源底层(nova.api.openstack.compute.legacy_v2.servers.py) Controller类的create方法

2、调度算法

虚拟机调度算法是Nova Scheduler服务实现的最主要的功能,算法的框架定义在FilterScheduler类的_scheduler方

法中。_scheduler工作流程:

(1)调用HostManager对象的get_all_hosts方法获取所有的计算节点列表。

(2)调用HostManager对象的get_filtered_hosts方法获取可用的计算节点列表。

(3)调用HostManager对象的get_weighted_hosts方法计算可用计算节点的权值。

(4)从权值最高的scheduler_host_subset_size个计算节点中随机选择一个计算节点作为创建虚拟机的节点。

(5)调用被选中计算节点对应的 HostState对象的 consume_from_instance方法,更新选择的计算节点的硬件资源信

息,为虚拟机预留资源。

(6)HostManager对象的get_all_hosts方法首先调用HostManager对象的_choose_host_filters方法获取过滤器类列

表,然后调用HostFilterHandler对象的get_filtered_objects方法使用过滤器检查计算节点。

(7)HostFilterHandler对象的get_filtered_objects方法依次调用每个过滤器对象的filter_all方法。过滤器的

filter_all方法返回的是通过该过滤器的主机列表。只有通过所有的过滤器检查的节点才是可用的节点。

(8)HostManager对象的get_weighted_hosts方法调用了HostWeightHandler对象的get_weighted_objects方法。

(9)HostWeightHandler对象的get_weighted_objects方法首先为每个主机创建一个WeightedObject对象。然后,依

调用权值对象的weigh_objects方法不断修改主机WeightedObject对象的权值。

主机最终的权值是所有权值对象赋予给主机权值的加权和。最后将主机按照权值由高到低顺序排列


你可能感兴趣的:(openstack组件研究)