1. 程式人生 > >看 nova-scheduler 如何選擇計算節點

看 nova-scheduler 如何選擇計算節點

本節重點介紹 nova-scheduler 的排程機制和實現方法:即解決如何選擇在哪個計算節點上啟動 instance 的問題。

建立 Instance 時,使用者會提出資源需求,例如 CPU、記憶體、磁碟各需要多少。
OpenStack 將這些需求定義在 flavor 中,使用者只需要指定用哪個 flavor 就可以了。

可用的 flavor 在 System->Flavors 中管理。

Flavor 主要定義了 VCPU,RAM,DISK 和 Metadata 這四類。
nova-scheduler 會按照 flavor 去選擇合適的計算節點。
VCPU,RAM,DISK 比較好理解,而 Metatdata 比較有意思,我們後面會具體討論。

下面介紹 nova-scheduler 是如何實現排程的。

在 /etc/nova/nova.conf 中,nova 通過 scheduler_driver,scheduler_available_filters 和 scheduler_default_filters 這三個引數來配置 nova-scheduler。

Filter scheduler

Filter scheduler 是 nova-scheduler 預設的排程器,排程過程分為兩步:

  1. 通過過濾器(filter)選擇滿足條件的計算節點(執行 nova-compute)
  2. 通過權重計算(weighting)選擇在最優(權重值最大)的計算節點上建立 Instance。

scheduler_driver=nova.scheduler.filter_scheduler.FilterScheduler

Nova 允許使用第三方 scheduler,配置 scheduler_driver 即可。
這又一次體現了OpenStack的開放性。

Scheduler 可以使用多個 filter 依次進行過濾,過濾之後的節點再通過計算權重選出最適合的節點。

上圖是排程過程的一個示例:

  1. 最開始有 6 個計算節點 Host1-Host6
  2. 通過多個 filter 層層過濾,Host2 和 Host4 沒有通過,被刷掉了
  3. Host1,Host3,Host5,Host6 計算權重,結果 Host5 得分最高,最終入選

Filter

當 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

RetryFilter 的作用是刷掉之前已經排程過的節點。

舉個例子方便大家理解:
假設 A,B,C 三個節點都通過了過濾,最終 A 因為權重值最大被選中執行操作。
但由於某個原因,操作在 A 上失敗了。
預設情況下,nova-scheduler 會重新執行過濾操作(重複次數由 scheduler_max_attempts 選項指定,預設是 3)。
那麼這時候 RetryFilter 就會將 A 直接刷掉,避免操作再次失敗。
RetryFilter 通常作為第一個 filter。

AvailabilityZoneFilter

為提高容災性和提供隔離服務,可以將計算節點劃分到不同的Availability Zone中。

例如把一個機架上的機器劃分在一個 Availability Zone 中。
OpenStack 預設有一個命名為 “Nova” 的 Availability Zone,所有的計算節點初始都是放在 “Nova” 中。
使用者可以根據需要建立自己的 Availability Zone。

建立 Instance 時,需要指定將 Instance 部署到在哪個 Availability Zone中。

nova-scheduler 在做 filtering 時,會使用 AvailabilityZoneFilter 將不屬於指定 Availability Zone 的計算節點過濾掉。

RamFilter

RamFilter 將不能滿足 flavor 記憶體需求的計算節點過濾掉。

對於記憶體有一點需要注意:
為了提高系統的資源使用率,OpenStack 在計算節點可用記憶體時允許 overcommit,也就是可以超過實際記憶體大小。
超過的程度是通過 nova.conf 中 ram_allocation_ratio 這個引數來控制的,預設值為 1.5

ram_allocation_ratio = 1.5

其含義是:如果計算節點的記憶體有 10GB,OpenStack 則會認為它有 15GB(10*1.5)的記憶體。

DiskFilter

DiskFilter 將不能滿足 flavor 磁碟需求的計算節點過濾掉。

Disk 同樣允許 overcommit,通過 nova.conf 中 disk_allocation_ratio 控制,預設值為 1

disk_allocation_ratio = 1.0

CoreFilter

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

ComputeFilter 保證只有 nova-compute 服務正常工作的計算節點才能夠被 nova-scheduler排程。
ComputeFilter 顯然是必選的 filter。

ComputeCapabilitiesFilter

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

ImagePropertiesFilter 根據所選 image 的屬性來篩選匹配的計算節點。
跟 flavor 類似,image 也有 metadata,用於指定其屬性。

例如希望某個 image 只能執行在 kvm 的 hypervisor 上,可以通過 “Hypervisor Type” 屬性來指定。

點選 “+”,然後在右邊的列表中選擇 “kvm”。

配置好後,ImagePropertiesFilter 在排程時只會篩選出 kvm 的節點。
如果沒有設定 Image 的Metadata,ImagePropertiesFilter 不會起作用,所有節點都會通過篩選。

ServerGroupAntiAffinityFilter

ServerGroupAntiAffinityFilter 可以儘量將 Instance 分散部署到不同的節點上。

例如有 inst1,inst2 和 inst3 三個 instance,計算節點有 A,B 和 C。
為保證分散部署,進行如下操作:

  1. 建立一個 anti-affinity 策略的 server group “group-1”

nova server-group-create –policy anti-affinity group-1

請注意,這裡的 server group 其實是 instance group,並不是計算節點的 group

  1. 依次建立 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 會直接通過,不做任何過濾。

ServerGroupAffinityFilter

與 ServerGroupAntiAffinityFilter 的作用相反,ServerGroupAffinityFilter 會盡量將 instance 部署到同一個計算節點上。
方法類似

  1. 建立一個 affinity 策略的 server group “group-2”

nova server-group-create –policy affinity group-2

  1. 依次建立 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 會直接通過,不做任何過濾。

Weight

經過前面一堆 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。