2013年6月28日金曜日

nova-scheduler in OpenStack Grizzly

Novaにおいて資源配分を司る、APIと並んで最も重要なコンポーネントになります。
Havanaではスケジューラー周りにかなり手が入るようなので、あくまでGrizzlyまでの情報です。

全ての機能を試したわけではないので、間違いがある可能性もあります。


1 スケジューラーの概要

1) 仮想マシンを起動する際に、どの物理ホスト上で起動するか決める。
2) nova-scheduler がその機能を担当する。
3) nova-scheduler は起動すると、AMQPへ接続し、メッセージの受信を待つ。


2 スケジューラーの二重化

nova-scheduler がダウンすると、nova全体の重要操作が全て行えなくなります。そのため2重化が必須となるコンポーネントです。といっても方法は簡単で、物理的に異なる複数のホストで nova-scheduler を起動しておくだけです。外部から仮想IPをコントロールしたり、外部からプロセスの起動停止を制御する必要はありません。

起動した nova-scheduler は、AMQPブローカーの scheduler用のキューに接続し、配信されるメッセージを待ちます。この時、AMQP側でFIFOや、重複メッセージ配信は制御されるので、複数の nova-scheduler が起動していたとしても、特別な設定を行う必要がないように設計されています。もちろんAMQPブローカー側がダウンするとメッセージが受信できなくなるので、AMQP側の多重化は必須となります。


3 スケジューリングの方法

仮想マシンの起動要求メッセージを受け取った nova-scheduler は、2つのステップで起動先ホストを決定します。

1) 配置先の候補となるホストを抽出する
2) コスト計算によって配置先ホストを決定する


4 配置先の候補ホストの決定

配置先のホストの決定には以下の設定が関係してきます。

nova.conf
| parameters                        | default value                                        |
|-----------------------------------+------------------------------------------------------|
| scheduler_driver                  | nova.scheduler.multi.MultiScheduler                  |
| compute_scheduler_driver          | nova.scheduler.filter_scheduler.FilterScheduler      |
| scheduler_available_filters       | nova.scheduler.filters.all_filters                   |
| scheduler_default_filters         | AvailabilityZoneFilter,RamFilter,ComputeFilter       |

1) scheduler_driver
nova全体(compute & volume)のスケジューリングを行う。デフォルトのMultiSchedulerは、ComputeとVolumeに異なるスケジューラーを割り当てるためのもので、nova-volumeがなくなった今となっては殆ど意味ありません。

2) compute_scheduler_driver
nova-compute へのスケジューリングを行う。 scheduler_driver が MultiSchedulerの場合に、この設定が使われます。


scheduler_driver & compute_scheduler_driver に設定できるスケジューラー
|-------------------------------------------------+--------------------------------------------------------------------------|
| scheduler                                       | description                                                              |
|-------------------------------------------------+--------------------------------------------------------------------------|
| nova.scheduler.filter_scheduler.FilterScheduler | フィルターによって物理ホストを特定する。computeのみ利用可能。            |
|                                                 | デフォルト、というか実際にはこれしか実用上の選択肢がない。               |
|-------------------------------------------------+--------------------------------------------------------------------------|
| nova.scheduler.chance.ChanceScheduler           | ランダムに物理ホスト(or ストレージ)を選択する。                          |
|                                                 | nova-volumeにはこれしか使えないが、cinderがあるので実質出番なし。        |
|-------------------------------------------------+--------------------------------------------------------------------------|
| nova.scheduler.multi.MultiScheduler             | nova-compute と nova-volume に異なるスケジューラーを設定する場合に使う。 |
|                                                 | scheduler_driver にのみ設定可能。                                        |
|-------------------------------------------------+--------------------------------------------------------------------------|

3) scheduler_available_filters
FilterSchedulerがロードできるフィルターを指定する。デフォルトの nova.scheduler.filters.all_filters は nova が標準で備える、すべてのフィルターを利用可能にします。あくまで利用可能にするだけで、実際のフィルターは別に設定します。
このパラメータは、一つの設定ファイルで複数回設定することができます。利用するケースとして、独自のフィルターを定義して、そのフィルターを利用する場合です。
scheduler_available_filters = nova.scheduler.filters.all_filters
scheduler_available_filters = myfilter.Myfilter1
scheduler_available_filters = myfilter.Myfilter2

4) scheduler_default_filters
適応されるフィルターを定義します。デフォルトでは AvailabilityZoneFilter,RamFilter,ComputeFilter が指定されています。定義したフィルターがそれぞれ条件を持ち、全ての条件を満たしたホストが仮想マシンの起動先候補になります。あくまで候補となるだけで、この時点では起動先の物理ホストは決まりません。デフォルトでは、AvailabilityZone、メモリ残量、ハイパーバイザーやアーキテクチャの適合がチェックされます。詳細は後述します。


5 フィルタースケジューラ

配置先の候補ホストを選択するためのデフォルトスケジューラーです。


5.1 フィルタースケジューラーの概要

novaクラスタ内の compute-node 全てに対して、設定したフィルターが適応されます。設定したフィルターに応じて、フィルターは起動時に与えられたパラメーターや、Flavorの属性、物理ホストの状態等々を元に適合するホストを文字通りフィルターします。そして全ての条件をパスしたホストが仮想マシンの起動先候補となります。複数のフィルターが設定されている場合、そのAND条件になります。候補がゼロ台の場合はエラーとなります。フィルタの適合結果は「適合するか、しないか」の2つしかありません(中間の状態はありません)


5.2 フィルターの設定

scheduler_default_filters に適応したいフィルタ名をカンマで区切って指定していきます。


5.3 よく使いそうなフィルター

量が多いのでよく使いそうなフィルターを抜粋して紹介します。

5.3.1 AggregateInstanceExtraSpecsFilter

Host Aggregate の属性値と、インスタンスの Extra Spec で定義された属性値のマッチングを行い、マッチした属性値を持つ Aggregate のホストが選定されます。


5.3.2 AggregateMultiTenancyIsolation

特定の Host Aggregate にテナントを分離します。Host Aggregate の属性値に filter_tenant_id=tenant-id を設定することで、そのtenant-idに属するユーザが仮想マシンを起動した際に、対応する aggregate が選定されます。


5.3.3 AllHostsFilter

無条件に全てのホストを適合させる。


5.3.4 AvailabilityZoneFilter

指定されたAvailability Zoneに属するホストを選定する。このフィルターを使う場合、スケジューラーへのリクエストにAvailability Zoneの情報が含まれている必要がある。
関連:nova-api(default_scheduler_zone)


5.3.5 ComputeCapabilitiesFilter


5.3.6 ComputeFilter


5.3.7 CoreFilter

CPUのオーバーコミットをどこまで許容するかを設定します。cpu_allocation_ratio=1.0 の場合、オーバーコミットを許可しません。

物理ホストのCPUコア数と、そのホストで起動している仮想マシンのvCPUコア数合計の関係から判断します。物理コア数 x cpu_allocation_ratio までの vCPU を許可します。cpu_allocation_ratio のデフォルトは16.0です。1以下を設定することで、性能に余裕をもたせられます。


5.3.8 DifferentHostFilter
特定の仮想マシンと物理ホストを共有させないためのフィルターです。
nova boot時に、 --hint オプションでReSTの中にキーを埋め込みます。
nova boot --hint different_host=vm_uuid1 --hint different_host=vm_uuid2 --flavor xxx --image yyy testvm

このように指定することで、uuid1,2 のインスタンスが起動しているホストが除外されます。


5.3.9 DiskFilter

エフェメラルディスクの配置時にどこまでのオーバーコミットを許すかを設定します。デフォルトは disk_allocation_ratio=1.0 で、オーバーコミットを許可していません。1以下の数値を指定することでディスク容量に余裕を持たせることが可能です。


5.3.10 GroupAntiAffinityFilter


5.3.11 ImagePropertiesFilter


5.3.12 IsolatedHostsFilter


5.3.13 JsonFilter

Jsonで独自の条件文を埋め込みます。
--hint query='["=>",$free_ram_mb,1024]'
使える変数は以下が利用可能。意味は名前のままです。
$free_ram_mb
$free_disk_mb
$total_usable_ram_mb
$vcpus_total
$vcpus_used
条件判定には以下が利用可能。
=
<
>
in
<=
>=
not
or
and


5.3.14 RamFilter

メモリのオーバーコミットをどれだけ許可するか。デフォルトは1.5倍。ram_allocation_ratio=1.5。


5.3.15 RetryFilter

一度失敗したホストを除外する??


5.3.16 SameHostFilter

DifferentHostFilter の逆。--hint で指定したVMと同じホストが選択される。
-hint same_host=uuid

5.3.17 SimpleCIDRAffinityFilter


6 配置先ホストの決定

フィルターされた物理ホストのリストに対して、コストに基づく「重み」を設定し、その「重み」に昇順ソートを行い、先頭のホストが仮想マシンの起動先として決定されます。つまり最も「軽い」ホストが選ばれます。


6.1 コスト試算と「重み」の設定

ホストのコストを算出するには、ホストに対してコスト関数を適用します。コスト関数を適用すると、適用した関数に応じて数値が返ります。この返った値に対して、「重み定数(weighting constant)」を掛ける(乗算)します。

適用するコスト関数を指定するパラメータと、重み定数が以下になります。
least_cost_functions
指定可能な値は以下になります。どれか1つ、もしくは複数を設定することも可能です。その場合はカンマで区切ります。
|------------------------------------------------------+----------------------+-----------------------------------|
| values for least_cost_functions                      | description          | weighting constant                |
|------------------------------------------------------+----------------------+-----------------------------------|
| nova.scheduler.least_cost.compute_fill_first_cost_fn | 空きメモリ量を返す。 | compute_fill_first_cost_fn_weight |
| nova.scheduler.least_cost.noop_cost_fn               | 常に1を返す。        | noop_cost_fn_weight               |
|------------------------------------------------------+----------------------+-----------------------------------|
nova.scheduler.least_cost.retry_host_cost_fn がマニュアルには存在してますが、このコスト関数は存在しません。実装途中で一時的に作られた関数らしく、リリース版では消えています。この関数は仮想マシン作成の失敗をカウントして、失敗したホストに対する重みをどうつけるかを設定していた関数のようです。この機能はフィルターのRetyFilerで実装されています。

複数のコスト関数を指定した場合、重みの合計値になります。

実質的に利用するパラメータは以下だけです。
least_cost_functions = nova.scheduler.least_cost.compute_fill_first_cost_fn
compute_fill_first_cost_fn_weight = 1.0
compute_fill_first_cost_fn_weight に正の値を設定した場合、空きメモリ量が少ないホストが昇順ソートで先頭にくるため、フィルターされたホストの中で利用率の高いマシンから仮想マシンが配置されます。つまり、特定のホストから仮想マシンが充填されていくようになります。

負の値を設定した場合、空きメモリ量が多いマシンほどマイナス方向へ大きくなるので、昇順ソート時に先頭に配置されます。この場合、フィルターされたホストに対して平均的に仮想マシンが配置されるようになります。

0 件のコメント:

コメントを投稿