Kubernetes v1.25 [stable]設定ファイルを作成し、そのパスをコマンドライン引数として渡すことでkube-schedulerの振る舞いをカスタマイズすることができます。
スケジューリングプロファイルは、kube-schedulerでスケジューリングの異なるステージを設定することができます。 各ステージは、拡張点として公開されています。 プラグインをそれらの拡張点に1つ以上実装することで、スケジューリングの振る舞いを変更できます。
KubeSchedulerConfiguration v1構造体を使用して、kube-scheduler --config <filename>を実行することで、スケジューリングプロファイルを指定することができます。
最小限の設定は次の通りです。
apiVersion: kubescheduler.config.k8s.io/v1
kind: KubeSchedulerConfiguration
clientConnection:
kubeconfig: /etc/srv/kubernetes/kube-scheduler/kubeconfig
スケジューリングプロファイルは、kube-schedulerでスケジューリングの異なるステージを設定することができます。 各ステージは拡張点に公開されています。 プラグインをそれらの拡張点に1つ以上実装することで、スケジューリングの振る舞いを変更できます。
単一のkube-schedulerインスタンスで複数のプロファイルを実行するように設定することも可能です。
スケジューリングは一連のステージで行われ、以下の拡張点に公開されています。
queueSort: これらのプラグインは、スケジューリングキューにあるpending状態のPodをソートするための順序付け関数を提供します。
同時に有効化できるプラグインは1つだけです。preFilter: これらのプラグインは、フィルタリングをする前にPodやクラスターの情報のチェックや前処理のために使用されます。
これらのプラグインは、Podをunschedulableとしてマークすることができます。filter: これらのプラグインは、スケジューリングポリシーにおけるPredicatesに相当し、Podを実行不可能なノードを除外するために使用されます。
フィルターは設定された順序で呼び出されます。
すべてのフィルターを通過するノードがない場合、Podはunschedulableとしてマークされます。postFilter: これらのプラグインは、Podを実行可能なノードが見つからなかった場合、設定された順序で呼び出されます。
もしpostFilterプラグインのいずれかが、Podを スケジュール可能 とマークした場合、残りのpostFilterプラグインは呼び出されません。preScore: これは、スコアリング前の作業を行う際に使用できる情報提供のための拡張点です。score: これらのプラグインはフィルタリングフェーズを通過したそれぞれのノードに対してスコア付けを行います。
その後スケジューラーは、最も高い重み付きスコアの合計を持つノードを選択します。reserve: これは、特定のPodに対してリソースが予約された際に、プラグインに通知する、情報提供のための拡張点です。
また、プラグインはUnreserve呼び出しも実装しており、これはReserve中またはその後に失敗が発生した場合に呼び出されます。permit: これらのプラグインは、Podのバインディングを防止または遅延させることができます。preBind: これらのプラグインは、Podがバインドされる前に必要な処理を実行できます。bind: これらのプラグインはPodをノードにバインドします。
bindプラグインは順番に呼び出され、1つのプラグインがバインドを完了すると、残りのプラグインはスキップされます。
bindプラグインは少なくとも1つは必要です。postBind: これは、Podがバインドされた後に呼び出される情報提供のための拡張点です。multiPoint: このフィールドは設定のみ可能で、プラグインが適用されるすべての拡張点に対して同時に有効化または無効化することができます。次の例のように、それぞれの拡張点に対して、特定のデフォルトプラグインを無効化、または自作のプラグインを有効化することができます。
apiVersion: kubescheduler.config.k8s.io/v1
kind: KubeSchedulerConfiguration
profiles:
- plugins:
score:
disabled:
- name: PodTopologySpread
enabled:
- name: MyCustomPluginA
weight: 2
- name: MyCustomPluginB
weight: 1
disabled配列のnameフィールドに*を使用することで、その拡張点の全てのデフォルトプラグインを無効化できます。
また、必要に応じてプラグインの順序を入れ替える場合にも使用されます。
以下のプラグインはデフォルトで有効化されており、1つ以上の拡張点に実装されています。
ImageLocality: Podが実行するコンテナイメージを既に持っているノードを優先します。
拡張点: scoreTaintToleration: TaintとTolerationを実装します。
実装する拡張点: filter、preScore、scoreNodeName: PodのSpecのノード名が、現在のノードと一致するかをチェックします。
拡張点:filterNodePorts: 要求されたPodのポートに対して、ノードが空きポートを持っているかチェックします。
拡張点: preFilter、filterNodeAffinity: nodeSelectorとノードアフィニティを実装します。
拡張点: filter、scorePodTopologySpread: Podトポロジーの分散制約を実装します。
拡張点: preFilter、filter、preScore、scoreNodeUnschedulable: .spec.unschedulableがtrueに設定されているノードを除外します。
拡張点: filterNodeResourcesFit: Podが要求しているすべてのリソースがノードにあるかをチェックします。
スコアは3つのストラテジのうちの1つを使用します: LeastAllocated(デフォルト)、MostAllocated、RequestedToCapacityRatio。
拡張点: preFilter、filter、scoreNodeResourcesBalancedAllocation: Podがスケジュールされた場合に、よりバランスの取れたリソース使用量となるノードを優先します。
拡張点: scoreVolumeBinding: ノードが、要求されたボリュームを持っている、またはバインド可能かをチェックします。
拡張点: preFilter、filter、reserve、preBind、scorescore拡張点は、StorageCapacityScoring機能が有効になっている時に有効化されます。
要求されたボリュームに適合する最小のPVを優先的に使用します。VolumeRestrictions: ノードにマウントされたボリュームが、ボリュームプロバイダー固有の制限を満たしているかを確認します。
拡張点: filterVolumeZone: 要求されたボリュームがゾーン要件を満たしているかどうかを確認します。
拡張点: filterNodeVolumeLimits: ノードのCSIボリューム制限を満たすかどうかをチェックします。
このプラグインは、ノードにCSIドライバーがインストールされていない場合に、そのノードへのPod配置を防ぐこともできます(VolumeLimitScalingフィーチャーゲートの有効化が必要です)。
また、アタッチ可能なCSIボリュームを持つスケジュール待ちPodのために必要なノード数を、cluster-autoscalerが正確に算出できるようにします。
拡張点: filterEBSLimits: AWSのEBSボリューム制限がノードに対して満たされるかをチェックします。
拡張点: filterGCEPDLimits: GCP-PDボリューム制限がノードに対して満たされるかをチェックします。
拡張点: filterAzureDiskLimits: Azure Diskボリューム制限がノードに対して満たされるかをチェックします
拡張点: filterInterPodAffinity: Pod間のアフィニティとアンチアフィニティを実装します。
拡張点: preFilter、filter、preScore、scorePrioritySort: デフォルトの優先順位に基づくソートを提供します。
拡張点: queueSort.DefaultBinder: デフォルトのバインディングメカニズムを提供します。
拡張点: bindDefaultPreemption: デフォルトのプリエンプションメカニズムを提供します。
拡張点: postFilterまた、コンポーネント設定のAPIにより、以下のプラグインを有効にすることができます。 デフォルトでは有効になっていません。
CinderLimits: ノードがOpenStack Cinderボリューム制限を満たせるかチェックします。
拡張点: filterkube-schedulerは複数のプロファイルを実行するように設定することができます。
各プロファイルは関連するスケジューラー名を持ち、その拡張点に異なるプラグインを設定することが可能です。
以下のサンプル設定では、スケジューラーは2つのプロファイルで実行されます。 1つはデフォルトプラグインで、もう1つはすべてのスコアリングプラグインを無効にしたものです。
apiVersion: kubescheduler.config.k8s.io/v1
kind: KubeSchedulerConfiguration
profiles:
- schedulerName: default-scheduler
- schedulerName: no-scoring-scheduler
plugins:
preScore:
disabled:
- name: '*'
score:
disabled:
- name: '*'
特定のプロファイルに従ってスケジュールさせたいPodは、Podの.spec.schedulerNameに、対応するスケジューラー名を含めることができます。
デフォルトでは、スケジューラー名default-schedulerを持つ1つのプロファイルが生成されます。
このプロファイルは、上記のデフォルトプラグインを含みます。
複数のプロファイルを宣言する場合は、それぞれユニークなスケジューラー名にする必要があります。
もしPodがスケジューラー名を指定しない場合、kube-apiserverはdefault-schedulerを設定します。
従って、これらのPodをスケジュールするために、このスケジューラー名を持つプロファイルが存在する必要があります。
Podのスケジューリングイベントには、ReportingControllerとして.spec.schedulerNameが設定されています。
リーダー選出のイベントには、リスト先頭のプロファイルのスケジューラー名が使用されます。
さらなる情報は、Event APIリファレンスのreportingController項目をご参照ください。
queueSort拡張点で同じプラグインを使用し、同じ設定パラメーターを持つ必要があります(該当する場合)。
これは、pending状態のPodキューがスケジューラーに1つしかないためです。kubescheduler.config.k8s.io/v1beta3からは、プロファイル設定にmultiPointというフィールドが追加され、複数の拡張点でプラグインを簡単に有効・無効化できるようになりました。
multiPoint設定の目的は、カスタムプロファイルを使用する際に、ユーザーや管理者が必要とする設定を簡素化することです。
MyPluginというプラグインがあり、preScore、score、preFilter、filter拡張点を実装しているとします。
すべての利用可能な拡張点でMyPluginを有効化するためには、プロファイル設定は次のようにします。
apiVersion: kubescheduler.config.k8s.io/v1
kind: KubeSchedulerConfiguration
profiles:
- schedulerName: multipoint-scheduler
plugins:
multiPoint:
enabled:
- name: MyPlugin
これは以下のように、MyPluginを手動ですべての拡張点に対して有効にすることと同じです。
apiVersion: kubescheduler.config.k8s.io/v1
kind: KubeSchedulerConfiguration
profiles:
- schedulerName: non-multipoint-scheduler
plugins:
preScore:
enabled:
- name: MyPlugin
score:
enabled:
- name: MyPlugin
preFilter:
enabled:
- name: MyPlugin
filter:
enabled:
- name: MyPlugin
multiPointを使用する利点の一つは、将来的にMyPluginが別の拡張点を実装した場合に、multiPoint設定が自動的に新しい拡張点に対しても有効化されることです。
特定の拡張点は、その拡張点のdisabledフィールドを使用して、MultiPointの展開から除外することができます。
これは、デフォルトのプラグインを無効にしたり、デフォルト以外のプラグインを無効にしたり、ワイルドカード('*')を使ってすべてのプラグインを無効にしたりする場合に有効です。
ScoreとPreScoreを無効にするためには、次の例のようにします。
apiVersion: kubescheduler.config.k8s.io/v1
kind: KubeSchedulerConfiguration
profiles:
- schedulerName: non-multipoint-scheduler
plugins:
multiPoint:
enabled:
- name: 'MyPlugin'
preScore:
disabled:
- name: '*'
score:
disabled:
- name: '*'
v1beta3からは、MultiPointを通じて、内部的に全てのデフォルトプラグインが有効化されています。
しかしながら、デフォルト値(並び順やスコアの重みなど)を柔軟に設定し直せるように、個別の拡張点は用意されています。
例えば、2つのスコアプラグインDefaultScore1とDefaultScore2に、重み1が設定されているとします。
その場合、次のように重さを変更し、並べ替えることができます。
apiVersion: kubescheduler.config.k8s.io/v1
kind: KubeSchedulerConfiguration
profiles:
- schedulerName: multipoint-scheduler
plugins:
score:
enabled:
- name: 'DefaultScore2'
weight: 5
この例では、MultiPointはデフォルトプラグインであるため、明示的にプラグイン名を指定する必要はありません。
そして、Scoreに指定されているプラグインはDefaultScore2のみです。
これは、特定の拡張点を通じて設定されたプラグインは、常にMultiPointプラグインよりも優先されるためです。
つまり、この設定例では、結果的に2つのプラグインを両方指定することなく、並び替えが行えます。
MultiPointプラグインを設定する際の一般的な優先順位は、以下の通りです。
MultiPointを使用して、手動で設定したプラグインとその設定内容上記の優先順位を示すために、次の例はこれらのプラグインをベースにします。
| プラグイン | 拡張点 |
|---|---|
DefaultQueueSort | QueueSort |
CustomQueueSort | QueueSort |
DefaultPlugin1 | Score, Filter |
DefaultPlugin2 | Score |
CustomPlugin1 | Score, Filter |
| プラグイン | 拡張点 |
| ------------------ | ----------------- |
DefaultQueueSort | QueueSort |
CustomQueueSort | QueueSort |
DefaultPlugin1 | Score、Filter |
DefaultPlugin2 | Score |
CustomPlugin1 | Score、Filter |
CustomPlugin2 | Score、Filter |
これらのプラグインの有効な設定例は次の通りです。
apiVersion: kubescheduler.config.k8s.io/v1
kind: KubeSchedulerConfiguration
profiles:
- schedulerName: multipoint-scheduler
plugins:
multiPoint:
enabled:
- name: 'CustomQueueSort'
- name: 'CustomPlugin1'
weight: 3
- name: 'CustomPlugin2'
disabled:
- name: 'DefaultQueueSort'
filter:
disabled:
- name: 'DefaultPlugin1'
score:
enabled:
- name: 'DefaultPlugin2'
なお、特定の拡張点にMultiPointプラグインを再宣言しても、エラーにはなりません。
特定の拡張点が優先されるため、再宣言は無視されます(ログは記録されます)。
このサンプルは、ほとんどの設定を一箇所にまとめるだけでなく、いくつかの工夫をしています。
queueSortプラグインを有効にし、デフォルトのプラグインを無効にする。CustomPlugin1とCustomPlugin2を有効にし、この拡張点のプラグイン内で、最初に実行されるようにする。filter拡張点でのみ、DefaultPlugin1を無効にする。score拡張点でDefaultPlugin2が最初に実行されるように並べ替える(カスタムプラグインより先に)。v1beta3以前のバージョンで、multiPointがない場合、上記の設定例は、次のものと同等になります。
apiVersion: kubescheduler.config.k8s.io/v1beta2
kind: KubeSchedulerConfiguration
profiles:
- schedulerName: multipoint-scheduler
plugins:
# デフォルトQueueSortプラグインを無効化
queueSort:
enabled:
- name: 'CustomQueueSort'
disabled:
- name: 'DefaultQueueSort'
# カスタムFilterプラグインを有効化
filter:
enabled:
- name: 'CustomPlugin1'
- name: 'CustomPlugin2'
- name: 'DefaultPlugin2'
disabled:
- name: 'DefaultPlugin1'
# カスタムScoreプラグインを有効化し、実行順を並べ替える
score:
enabled:
- name: 'DefaultPlugin2'
weight: 1
- name: 'DefaultPlugin1'
weight: 3
これは複雑な例ですが、MultiPoint設定の柔軟性と、拡張点を設定する既存の方法とのシームレスな統合を実証しています。
v1beta2のバージョンの設定では、新しいNodeResourcesFitプラグインをスコア拡張点で使用できます。
この新しい拡張機能は、NodeResourcesLeastAllocated、NodeResourcesMostAllocated、 RequestedToCapacityRatioプラグインの機能を組み合わせたものです。
例えば、以前までNodeResourcesMostAllocatedプラグインを使っていたなら、代わりにNodeResourcesFitプラグインを使用し(デフォルトで有効)、pluginConfigに次のようなscoreStrategyを追加することになるでしょう。
apiVersion: kubescheduler.config.k8s.io/v1beta2
kind: KubeSchedulerConfiguration
profiles:
- pluginConfig:
- args:
scoringStrategy:
resources:
- name: cpu
weight: 1
type: MostAllocated
name: NodeResourcesFit
スケジューラープラグインのNodeLabelは廃止されました。
代わりにNodeAffinityプラグイン(デフォルトで有効)を使用することで同様の振る舞いを実現できます。
スケジューラープラグインのServiceAffinityは廃止されました。
代わりにInterPodAffinityプラグイン(デフォルトで有効)を使用することで同様の振る舞いを実現できます。
スケジューラープラグインのNodePreferAvoidPodsは廃止されました。
代わりにノードのTaintを使用することで同様の振る舞いを実現できます。
v1beta2で有効化されたプラグインは、そのプラグインのデフォルトの設定より優先されます。
スケジューラーのヘルスとメトリクスのバインドアドレスに設定されているhostやportが無効な場合、バリデーションに失敗します。
InterPodAffinity:1から2NodeAffinity:1から2TaintToleration:1から3SelectorSpreadは廃止されました。
代わりにPodTopologySpreadプラグイン(デフォルトで有効)を使用することで同様の振る舞いを実現できます。