OpenStack nova-scheduler 是如何運作的

OpenStack nova-scheduler 是如何運作的

最近在工作上因為某些緣由看了很多關於 OpenStack nova 的 code,因而打算來寫一些文章記錄一下 nova 是如何運作的。首先第一篇將由 nova-scheduler 的部分開始。會帶讀者從 code level 了解 conductor 如何 call scheduler 到 scheduler 怎麼做決定流程。

本篇文章以撰寫時最新 stable 版本 victoria 為基礎。

nova-scheduler 簡介

nova-scheduler 是設計成一個 plugin based 的 scheduler,使用者可以根據自己的需求撰寫自己的 scheduler driver。在 nova 中預設會啟用的是本身 nova code base 中提供的 filter scheduler

Filter scheduler 的運作原理非常的簡單,基本上會將所有的 host 經過一系列的 "filter",如果不符合 filter 的條件就會被剔除,符合的就會通過,並且進入最後的選擇的 pool。這些通過 filter 的 host 會在做 weighing 進行排序,並且從前幾名的 host 中隨機選擇一個 host 作為最後要生成 VM 的主機。簡單的流程可以參考官方文件中的圖:

OpenStack filter scheduler

OpenStack 本身有提供一些常用的 filter,適自身需求也可以撰寫並且在設定中啟用自己客制的 filter。Weigher 也相同有提供一些常用的,也可應自身需求自行撰寫。

nova-scheduler driver 有哪些 method?

我們可以從 nova-scheduler driver base class 中找到四個 method:

  • __init__
  • run_periodic_tasks
  • hosts_up
  • select_destinations

__init__

init 顧名思義就是要初始化這個 class,幫你拿到 host manager 跟 servcie group API 兩個 object。

run_periodic_tasks

這個 method 同樣的也很容易從中得知用途。一些週期性會需要跑的邏輯會被放在這個 method 下,在 base class 中是直接 pass 沒有 implement 任何邏輯的。

hosts_up

hosts_up 會 return 一個 list 包含有跑 service 或是 topic 的 host。

select_destinations

select_destinations 就是整個 scheduler 的精華了,選擇 host 的邏輯會被 implement 在這個 method 底下。 nova-conductor 在 scheduler instance 的時候就是 call 這個 method。

nova-scheduler 整體如何運作的

目前 nova 大部分內部事項都是由 conductor 處理,我們從 conductor manager 的 code 中可以找到一個負責 schedule instance 的 function

    def _schedule_instances(self, context, request_spec,
                            instance_uuids=None, return_alternates=False):
        scheduler_utils.setup_instance_group(context, request_spec)
        with timeutils.StopWatch() as timer:
            # where it call scheduler
            host_lists = self.query_client.select_destinations(
                context, request_spec, instance_uuids, return_objects=True,
                return_alternates=return_alternates)
        LOG.debug('Took %0.2f seconds to select destinations for %s '
                  'instance(s).', timer.elapsed(), len(instance_uuids))
        return host_lists

從 code 中可以看到 conductor manager 從 scheduler 的 query client 去 call select_destinations 這個 method,這個 call 最後會透過 rpc 送去 nova-scheduler driver 的 select destination 做處理。

在經過上述提到的 filter 跟 weigher 後,select destination 會 return 一個包含每個 instance destination 的 selection object

總結

nova-scheduler 整體的流程其實非常的簡單易懂,driver based 的設計也可以讓使用者能夠很彈性的根據自身需求替換 scheduler,就算是使用內建的 filter scheduler 也可以輕易的撰寫自己的 filter。這樣的設計個人認為來說是非常的不錯,不過目前在 host 跟同時要 schedule 的 instance 多的時候可能會遇上一些效能問題,可能會需要拆分 nova cell 來做解決。

Reference

https://docs.openstack.org/nova/latest/user/filter-scheduler.html
https://github.com/openstack/nova/tree/stable/victoria


Copyright Notice: All articles in this blog are licensed under CC BY-NC-SA 4.0 unless stating additionally.