在上一篇“
nova-scheduler调度过程分析”中,对过滤称重的过程一笔带过了,这篇着重介绍一下。
首先,我们声明一下host为主机,node为节点,在OpenStack中一个host可以运行多个node或者nova-compute服务。
首先,我们声明一下host为主机,node为节点,在OpenStack中一个host可以运行多个node或者nova-compute服务。
第一步,过滤filter,通过HostManager的get_filtered_hosts实现:
选取Icehouse版本支持的部分主机过滤器进行简要说明:
RetryFilter -> 如果主机已经尝试被调度了,那么过滤不通过
AvailabilityZoneFilter -> 我们可以根据物理位置对主机划分“可用域”, 如果创建虚拟机实例时指定了availability_zone,而主机又不在
该availability_zone中,那么过滤不通过
RamFilter -> 如果主机的可用内存不足以提供虚拟机实例需要的内存,那么过滤不通过
ComputeFilter -> 如果主机的计算服务被禁用掉或者down掉(一定时间内没有收到心跳包), 那么过滤不通过
ComputeCapabilitiesFilter -> 创建虚拟机实例时可以指定一些额外的要求,如果主机的能力不满足这些要求,那么过滤不通过
ImagePropertiesFilter -> 我们可以给镜像创建属性,譬如在镜像属性指定架构、hypervisor和虚拟机模式,如果主机不支持这些属性的虚拟机,那么过滤不通过
ServerGroupAntiAffinityFilter、ServerGroupAffinityFilter ->给定一个实例组,那么可以获取运行实例成员的主机集合,如果主机
在/不在这个主机集合里,那么过滤不通过
# nova-scheduler默认的过滤器列表
cfg.ListOpt('scheduler_default_filters',
default=[
'RetryFilter',
'AvailabilityZoneFilter',
'RamFilter',
'ComputeFilter',
'ComputeCapabilitiesFilter',
'ImagePropertiesFilter',
'ServerGroupAntiAffinityFilter',
'ServerGroupAffinityFilter',
],
help='Which filter class names to use for filtering hosts '
'when not specified in the request.'),
# 过滤器基类
class BaseFilter(object):
def _filter_one(self, obj, filter_properties):
return True
def filter_all(self, filter_obj_list, filter_properties):
for obj in filter_obj_list:
if self._filter_one(obj, filter_properties):
yield obj
run_filter_once_per_request = False
# 我们可以一次创建多个同类型的实例, 每个实例我们都需要对主机进行一次过滤称重操作,
# 有些过滤器类只需要在针对第一个实例的过滤过程中运行一次即可, 之后的实例就不再运行
def run_filter_for_index(self, index):
if self.run_filter_once_per_request and index > 0:
return False
else:
return True
# 主机过滤器基类
class BaseHostFilter(filters.BaseFilter):
def _filter_one(self, obj, filter_properties):
return self.host_passes(obj, filter_properties)
def host_passes(self, host_state, filter_properties):
raise NotImplementedError()
# 举例: 磁盘过滤器
class DiskFilter(filters.BaseHostFilter):
def host_passes(self, host_state, filter_properties):
# 求出创建虚拟机实例所需的磁盘大小
instance_type = filter_properties.get('instance_type')
requested_disk = (1024 * (instance_type['