本节重点介绍 nova-scheduler 的调度机制和实现方法:即解决如何选择在哪一个计算节点上启动 instance 的问题。架构
建立 Instance 时,用户会提出资源需求,例如 CPU、内存、磁盘各须要多少。spa
OpenStack 将这些需求定义在 flavor 中,用户只须要指定用哪一个 flavor 就能够了。翻译
可用的 flavor 在 System->Flavors 中管理。debug
Flavor 主要定义了 VCPU,RAM,DISK 和 Metadata 这四类。 nova-scheduler 会按照 flavor 去选择合适的计算节点。 VCPU,RAM,DISK 比较好理解,而 Metadata 比较有意思,咱们后面会具体讨论。日志
下面介绍 nova-scheduler 是如何实现调度的。server
在 /etc/nova/nova.conf 中,nova 经过 scheduler_driver,scheduler_available_filters 和 scheduler_default_filters 这三个参数来配置 nova-scheduler。内存
Filter scheduler 是 nova-scheduler 默认的调度器,调度过程分为两步:资源
经过过滤器(filter)选择知足条件的计算节点(运行 nova-compute)部署
经过权重计算(weighting)选择在最优(权重值最大)的计算节点上建立 Instance。it
scheduler_driver=nova.scheduler.filter_scheduler.FilterScheduler
Nova 容许使用第三方 scheduler,配置 scheduler_driver 便可。 这又一次体现了OpenStack的开放性。
Scheduler 可使用多个 filter 依次进行过滤,过滤以后的节点再经过计算权重选出最适合的节点。
上图是调度过程的一个示例:
最开始有 6 个计算节点 Host1-Host6
经过多个 filter 层层过滤,Host2 和 Host4 没有经过,被刷掉了
Host1,Host3,Host5,Host6 计算权重,结果 Host5 得分最高,最终入选
当 Filter scheduler 须要执行调度操做时,会让 filter 对计算节点进行判断,filter 返回 True 或 False。
Nova.conf 中的 scheduler_available_filters 选项用于配置 scheduler 可用的 filter,默认是全部 nova 自带的 filter 均可以用于滤操做。
scheduler_available_filters = nova.scheduler.filters.all_filters
另外还有一个选项 scheduler_default_filters,用于指定 scheduler 真正使用的 filter,默认值以下
scheduler_default_filters = RetryFilter, AvailabilityZoneFilter, RamFilter, DiskFilter, ComputeFilter, ComputeCapabilitiesFilter, ImagePropertiesFilter, ServerGroupAntiAffinityFilter, ServerGroupAffinityFilter
Filter scheduler 将按照列表中的顺序依次过滤。 下面依次介绍每一个 filter。
RetryFilter 的做用是刷掉以前已经调度过的节点。
举个例子方便你们理解: 假设 A,B,C 三个节点都经过了过滤,最终 A 由于权重值最大被选中执行操做。 但因为某个缘由,操做在 A 上失败了。 默认状况下,nova-scheduler 会从新执行过滤操做(重复次数由 scheduler_max_attempts 选项指定,默认是 3)。 那么这时候 RetryFilter 就会将 A 直接刷掉,避免操做再次失败。 RetryFilter 一般做为第一个 filter。
为提升容灾性和提供隔离服务,能够将计算节点划分到不一样的Availability Zone中。
例如把一个机架上的机器划分在一个 Availability Zone 中。 OpenStack 默认有一个命名为 “Nova” 的 Availability Zone,全部的计算节点初始都是放在 “Nova” 中。 用户能够根据须要建立本身的 Availability Zone。
建立 Instance 时,须要指定将 Instance 部署到在哪一个 Availability Zone中。
nova-scheduler 在作 filtering 时,会使用 AvailabilityZoneFilter 将不属于指定 Availability Zone 的计算节点过滤掉。
RamFilter 将不能知足 flavor 内存需求的计算节点过滤掉。
对于内存有一点须要注意: 为了提升系统的资源使用率,OpenStack 在计算节点可用内存时容许 overcommit,也就是能够超过实际内存大小。 超过的程度是经过 nova.conf 中 ram_allocation_ratio 这个参数来控制的,默认值为 1.5
ram_allocation_ratio = 1.5
其含义是:若是计算节点的内存有 10GB,OpenStack 则会认为它有 15GB(10*1.5)的内存。
DiskFilter 将不能知足 flavor 磁盘需求的计算节点过滤掉。
Disk 一样容许 overcommit,经过 nova.conf 中 disk_allocation_ratio 控制,默认值为 1
disk_allocation_ratio = 1.0
CoreFilter 将不能知足 flavor vCPU 需求的计算节点过滤掉。
vCPU 一样容许 overcommit,经过 nova.conf 中 cpu_allocation_ratio 控制,默认值为 16
cpu_allocation_ratio = 16.0
这意味着一个 8 vCPU 的计算节点,nova-scheduler 在调度时认为它有 128 个 vCPU。 须要提醒的是: nova-scheduler 默认使用的 filter 并无包含 CoreFilter。 若是要用,能够将 CoreFilter 添加到 nova.conf 的 scheduler_default_filters 配置选项中。
ComputeFilter 保证只有 nova-compute 服务正常工做的计算节点才可以被 nova-scheduler调度。
ComputeFilter 显然是必选的 filter。
ComputeCapabilitiesFilter 根据计算节点的特性来筛选。
这个比较高级,咱们举例说明。 例如咱们的节点有 x86_64 和 ARM 架构的,若是想将 Instance 指定部署到 x86_64 架构的节点上,就能够利用到 ComputeCapabilitiesFilter。
还记得 flavor 中有个 Metadata 吗,Compute 的 Capabilitie s就在 Metadata中 指定。
“Compute Host Capabilities” 列出了全部可设置 Capabilities。
点击 “Architecture” 后面的 “+”,就能够在右边的列表中指定具体的架构。
配置好后,ComputeCapabilitiesFilter 在调度时只会筛选出 x86_64 的节点。 若是没有设置 Metadata,ComputeCapabilitiesFilter 不会起做用,全部节点都会经过筛选。
ImagePropertiesFilter 根据所选 image 的属性来筛选匹配的计算节点。 跟 flavor 相似,image 也有 metadata,用于指定其属性。
例如但愿某个 image 只能运行在 kvm 的 hypervisor 上,能够经过 “Hypervisor Type” 属性来指定。
点击 “+”,而后在右边的列表中选择 “kvm”。
配置好后,ImagePropertiesFilter 在调度时只会筛选出 kvm 的节点。 若是没有设置 Image 的Metadata,ImagePropertiesFilter 不会起做用,全部节点都会经过筛选。
ServerGroupAntiAffinityFilter 能够尽可能将 Instance 分散部署到不一样的节点上。
例若有 inst1,inst2 和 inst3 三个 instance,计算节点有 A,B 和 C。 为保证分散部署,进行以下操做:
建立一个 anti-affinity 策略的 server group “group-1”
nova server-group-create --policy anti-affinity group-1
请注意,这里的 server group 实际上是 instance group,并非计算节点的 group。
依次建立 Instance,将inst1, inst2和inst3放到group-1中
nova boot --image IMAGE_ID --flavor 1 --hint group=group-1 inst1
nova boot --image IMAGE_ID --flavor 1 --hint group=group-1 inst2
nova boot --image IMAGE_ID --flavor 1 --hint group=group-1 inst3
由于 group-1 的策略是 AntiAffinity,调度时 ServerGroupAntiAffinityFilter 会将 inst1, inst2 和 inst3 部署到不一样计算节点 A, B 和 C。
目前只能在 CLI 中指定 server group 来建立 instance。
建立 instance 时若是没有指定 server group,ServerGroupAntiAffinityFilter 会直接经过,不作任何过滤。
与 ServerGroupAntiAffinityFilter 的做用相反,ServerGroupAffinityFilter 会尽可能将 instance 部署到同一个计算节点上。 方法相似
建立一个 affinity 策略的 server group “group-2”
nova server-group-create --policy affinity group-2
依次建立 instance,将 inst1, inst2 和 inst3 放到 group-2 中
nova boot --image IMAGE_ID --flavor 1 --hint group=group-2 inst1
nova boot --image IMAGE_ID --flavor 1 --hint group=group-2 inst2
nova boot --image IMAGE_ID --flavor 1 --hint group=group-2 inst3
由于 group-2 的策略是 Affinity,调度时 ServerGroupAffinityFilter 会将 inst1, inst2 和 inst3 部署到同一个计算节点。
建立 instance 时若是没有指定 server group,ServerGroupAffinityFilter 会直接经过,不作任何过滤。
通过前面一堆 filter 的过滤,nova-scheduler 选出了可以部署 instance 的计算节点。 若是有多个计算节点经过了过滤,那么最终选择哪一个节点呢?
Scheduler 会对每一个计算节点打分,得分最高的获胜。 打分的过程就是 weight,翻译过来就是计算权重值,那么 scheduler 是根据什么来计算权重值呢?
目前 nova-scheduler 的默认实现是根据计算节点空闲的内存量计算权重值: 空闲内存越多,权重越大,instance 将被部署到当前空闲内存最多的计算节点上。
是时候完整的回顾一下 nova-scheduler 的工做过程了。 整个过程都被记录到 nova-scheduler 的日志中。 好比当咱们部署一个 instance 时
打开 nova-scheduler 的日志 /opt/stack/logs/n-sch.log(非 devstack 安装其日志在 /var/log/nova/scheduler.log)
日志显示初始有两个 host(在咱们的实验环境中就是 devstack-controller 和 devstack-compute1),依次通过 9 个 filter 的过滤(RetryFilter, AvailabilityZoneFilter, RamFilter, DiskFilter, ComputeFilter, ComputeCapabilitiesFilter, ImagePropertiesFilter, ServerGroupAntiAffinityFilter, ServerGroupAffinityFilter),两个计算节点都经过了。
那么接下来就该 weight 了:
能够看到由于 devstack-controller 的空闲内存比 devstack-compute1 多(7466 > 3434),权重值更大(1.0 > 0.4599),最终选择 devstack-controller。
注:要显示 DEBUG 日志,须要在 /etc/nova/nova.conf 中打开 debug 选项
[DEFAULT]
debug = True
nova-scheduler 就是这些内容了,稍微有些复杂哈(由于灵活嘛),你们这两天能够好好消化一下。
下节咱们讨论 nova-compute。