注:过滤器可以为创建虚拟机设置条件,简单来讲提供了管理的功能,例如前两天在群里看见有人自己写的filter限制一台设备最多只能创建5台虚拟机等。
原文:http://docs.openstack.org/developer/nova/devref/filter_scheduler.html
过滤调度器支持filtering和weighting来决定,新创建的实例的位置。调度器的支持只工作在计算节点。
过滤调度器首先生成一个字典包含没有过滤的hosts,然后过滤它们使用过滤属性,最后选择hosts为请求的实例数(每次它选择开销最小的主机然后调节它到选择列表)。
如果它出现,它不能为下一个实例找到候选。它意味着这没有更多合适的实例。
如果我们谈起filtering和weighting ,在过滤调度器中它们的工作相当的灵活。调度器支持多种的过滤策略。同样你甚至可以实现你自己的过滤算法。
下面是一些标准的过滤类(nova.scheduler.filters):
* = (equal to or greater than as a number; same as vcpus case) * == (equal to as a number) * != (not equal to as a number) * >= (greater than or equal to as a number) * <= (less than or equal to as a number) * s== (equal to as a string) * s!= (not equal to as a string) * s>= (greater than or equal to as a string) * s> (greater than as a string) * s<= (less than or equal to as a string) * s< (less than as a string) * <in> (substring) * <or> (find one of these) Examples are: ">= 5", "s== 2.1.0", "<in> gcc", and "<or> fpu <or> gpu"
现在我们可以详细地关注这些标准的过滤类。我将pass简单的那些,例如AllHostsFilter,CoreFilter和RamFilter,因为他们的功能非常的简单和可以从代码上就能够理解。例如类RamFilter有下面的实现:
class RamFilter(filters.BaseHostFilter): """Ram Filter with over subscription flag""" def host_passes(self, host_state, filter_properties): """Only return hosts with sufficient available RAM.""" instance_type = filter_properties.get('instance_type') requested_ram = instance_type['memory_mb'] free_ram_mb = host_state.free_ram_mb total_usable_ram_mb = host_state.total_usable_ram_mb used_ram_mb = total_usable_ram_mb - free_ram_mb return total_usable_ram_mb * FLAGS.ram_allocation_ratio - used_ram_mb >= requested_ram
这里ram_allocation_ratio 意味着虚拟的RAM到物理的RAM分配比率(默认为1.5)。确实,很简单。
下一个要描述的标准的过滤器是AvailabilityZoneFilter ,它也不是很困难。这过滤器只是研究计算节点的可用性区域和从请求中的属性的可用性区域。每个计算服务有它自己的可用区域。所以部署工程师有一个选项来运行调度器支持可用区域和配置每个主机的可用区域。这个类方法host_passes返回true一旦可用区域请求中提及的和当前的计算主机一致。
ImagePropertiesFilter 过滤hosts基于架构,hypervisor类型,和虚拟机模式指定在实例中。例如,一个实例或许需要一个host支持arm建构在一个qemu计算host。ImagePropertiesFilter将只通过hosts那些可以满值这个请求的。这些实例属性来源于实例的镜像。例如 一个镜像可以被装饰属性通过使用glance image-update img-uuid-property architecture=arm-property hypervisor_type=qemu 只有hosts满足这些需求将会通过ImagePropertiesFilter。
ComputeCapabilitesFilter 检查是否host满足任何的'extra specs'指定的实例类型。'extra specs'可以包含键值对,ComputeCapabilitiesFilter将只通过hosts,能力满足请求的规定。所有的hosts被通过如果没有'extra specs'被指定。
ComputeFilter 是非常简单,通过任何的host,只要计算服务是可用的。
现在我们介绍IsolatedHostsFilter。这可以一些特殊的hosts保留给指定的images。这些hosts被称作isolated。所以运行在孤立hosts上的镜像也被称作isolated。这个调度器检查是否image_isolated标志命名在实例规定和在host中的一致。
DifferentHostFilter - 它的方法 host_passes 返回True 一旦host主机将实例在不同于使用的所有主机实例集。
SameHostFilter 和DifferetHostFilter相反。
SimpleCIDRAffinityFilter 研究子网掩码然后调查是否当球的主机的网路地址和子网一致作为它定义在请求中。
JsonFilter - 这个过滤提供这个机会来写复杂的查询对于hosts能力过滤。基于简单的类json语法。可以使用下面的操作对于host状态属性:'=','<','>','in','<=','>=',可以结合下面的逻辑操作:'not','or','and'。例如,你可以在测试中看点下面的查询:
['and',
['>=', '$free_ram_mb', 1024],
['>=', '$free_disk_mb', 200 * 1024]
]
这个查询将会过滤所有的hosts多余的剩余RAM空间或者至少1024MB,同事有剩余的磁盘空间或者至少200GB。
许多过滤使用的数据来自scheduler_hints,它被定义在用户创建一个服务器的时候。这个规定的唯一例外就是JsonFilter,它获得数据在一些奇怪困难与理解的方式。
RetryFilter过滤hosts那些已经尝试调度的。只通过hosts那些还没有在之前被尝试过的。
TrustedFilter 过滤hosts基于信任度。只通过hosts那些匹配信任请求在'extra_specs'z中的值的。这个值对于这个过滤是'trust:trusted_host','trust'是这个值的范围,'trusted_host'是实际的值。('trusted'/'untrusted')的值必须匹配完整的一个host(经过认证服务)在它通过TrustedFilter之前。
为了使用你指定的过滤器下面的两个设置:
默认值在nova.conf中:
--scheduler_available_filters=nova.scheduler.filters.standard_filters --scheduler_default_filters=RamFilter,ComputeFilter,AvailabilityZoneFilter,ComputeCapabilityFilter,ImagePropertiesFilter
有了这个配置。所有的过滤器在nova.scheduler.filters将会可用。默认下RamFilter,ComputeFilter,AvailabilityZoneFilter,ComputeCapabilityFilter,ImageProperTiesFilter将会被使用。
如果你想建立你自己的过滤器你只需要继承 BaseHostFilter然后实现一个方法:host_passes.这个方法应该返回True如果host通过过滤。它需要host_state和filter_properties字典作为参数。
例如,nova.conf可以包含下面的调度相关的设置:
--scheduler_driver=nova.scheduler.FilterScheduler --scheduler_available_filters=nova.scheduler.filters.standard_filters --scheduler_available_filters=myfilter.MyFilter --scheduler_default_filters=RamFilter,ComputeFilter,MyFilter有了这些设置,nova将会使用FilterScheduler作为调度驱动。标准的nova过滤器和我的过滤器可以被FilterScheduler调用。RamFilter,ComputeFilter,和我的过滤器默认下使用当没有过滤器被指定在请求中。
过滤调度器使用所谓的weights(权重)和costs(损耗)在它们工作的时候。
costs是计算的整数,表达hosts测量被选择合适的结果对于请求。当然。costs被计算由于hosts特点和请求中的特点匹配。所以尝试put实例在一个不适合的host(例如,尝试put一个非常简单的实例在一台高性能的主机上)将会有高的costs,put实例在一个适合的主机将会较少。
所以,让我们找出,这一切的计算工作是如何发生的。
在weighting之前,过滤调度器创建一个元祖列表包含weight和cost功能来用来weighing hosts。这些功能可以从缓存中获取,如果这些操作在之前已经做了(这个缓存依赖节点),过滤调度器值工作在计算节点,过滤调度器尝试获取这个cost功能通过nova.conf。Weight在元祖中表示cost功能的weight的匹配。它同样可以被获取通过nova.conf。在调度weights主机后,使用选定的cost功能。它做这些通过weighted_sum方法。参数是:
这个方法首先创建一个网格功能的结果(它只是计算每个功能使用host_state和weighing_properties的值)- 分数,每行一个host每列一个功能。下一步是计算这个值从每个单元从网格中。最后一个计算每行的总数-这将是host的weight,这个方法返回这host有最少的weight-最佳的一个。
如果我们集中于cost功能,它将会意味着我们使用compute_fill_first_cost_fn 功能默认下,只是简单的返回了有剩余RAM空间的hosts:
def compute_fill_first_cost_fn(host_state, weighing_properties): """More free ram = higher weight. So servers will less free ram will be preferred.""" return host_state.free_ram_mb你能实现你自己的cost功能变体对于主机的能力你想去涉及的。使用不同的cost功能(正如你所知的,同一时间可以有许多被使用的)可以灵活选择下一个用来创建新实例的主机。
这些cost功能应该安装在nova.conf中通过标识least_cost_functions(这可以有更多的更通过逗号隔开)。默认这行应该是:
--least_cost_functions=nova.scheduler.least_cost.compute_fill_first_cost_fn至于cost功能的weights,它们也要描述在nova.conf。这行描述看看起来下面的方式:function_name_weight.
至于默认的cost功能,:compute_fill_first_cost_fn_weight,默认是-1.0.
--compute_fill_first_cost_fn_weight=-1.0消极的功能的weight意味着计算节点有更多剩余RAM空间,更好的是,Nova尝试分离实例尽可能的覆盖计算节点。积极的weight意味着Nova 将首先添满一个单独的计算节点。
过滤调度器找到通过重复filtering和weighing找到了可以接受的列表。每次它选择一个host,它消耗了它上面的资源,所以随后的选择可以进行调节。一旦客户要求大数量的实例的时候非常的有用,因为weight被计算对于每一个实例的请求。
最后过滤调度器排序选择的hosts通过它们的weight和规定它们上面的实例。