Scheduling

1 - スケジューラーの設定

FEATURE STATE: Kubernetes v1.19 [beta]

設定ファイルを作成し、そのパスをコマンドライン引数として渡すことでkube-schedulerの振る舞いをカスタマイズすることができます。

スケジューリングプロファイルは、kube-schedulerでスケジューリングの異なるステージを設定することができます。 各ステージは、拡張点に公開されています。プラグインをそれらの拡張点に1つ以上実装することで、スケジューリングの振る舞いを変更できます。

KubeSchedulerConfiguration(v1beta2v1beta3)構造体を使用して、kube-scheduler --config <filename>を実行することで、スケジューリングプロファイルを指定することができます。

最小限の設定は次の通りです。

apiVersion: kubescheduler.config.k8s.io/v1beta2
kind: KubeSchedulerConfiguration
clientConnection:
  kubeconfig: /etc/srv/kubernetes/kube-scheduler/kubeconfig

プロファイル

スケジューリングプロファイルは、kube-schedulerでスケジューリングの異なるステージを設定することができます。 各ステージは拡張点に公開されています。 プラグインをそれらの拡張点に1つ以上実装することで、スケジューリングの振る舞いを変更できます。

単一のkube-schedulerインスタンスで複数のプロファイルを実行するように設定することも可能です。

拡張点

スケジューリングは一連のステージで行われ、以下の拡張点に公開されています。

  1. queueSort: これらのプラグインは、スケジューリングキューにあるpending状態のPodをソートするための順序付け関数を提供します。同時に有効化できるプラグインは1つだけです。
  2. preFilter: これらのプラグインは、フィルタリングをする前にPodやクラスターの情報のチェックや前処理のために使用されます。これらのプラグインは、設定された順序で呼び出されます。
  3. filter: これらのプラグインは、スケジューリングポリシーにおけるPredicatesに相当するもので、Podの実行不可能なNodeをフィルターするために使用されます。もし全てのNodeがフィルターされてしまった場合、Podはunschedulableとしてマークされます。
  4. postFilter:これらのプラグインは、Podの実行可能なNodeが見つからなかった場合、設定された順序で呼び出されます。もしpostFilterプラグインのいずれかが、Podを スケジュール可能 とマークした場合、残りのpostFilterプラグインは呼び出されません。
  5. preScore: これは、スコアリング前の作業を行う際に使用できる情報提供のための拡張点です。
  6. score: これらのプラグインはフィルタリングフェーズを通過してきたそれぞれのNodeに対してスコア付けを行います。その後スケジューラーは、最も高い重み付きスコアの合計を持つノードを選択します。
  7. reserve: これは、指定されたPodのためにリソースが予約された際に、プラグインに通知する、情報提供のための拡張点です。また、プラグインはReserve中に失敗した際、またはReserveの後に呼び出されるUnreserveも実装しています。
  8. permit: これらのプラグインではPodのバインディングを拒む、または遅延させることができます。
  9. preBind: これらのプラグインは、Podがバインドされる前に必要な処理を実行できます。
  10. bind: これらのプラグインはPodをNodeにバインドします。bindプラグインは順番に呼び出され、1つのプラグインがバインドを完了すると、残りのプラグインはスキップされます。bindプラグインは少なくとも1つは必要です。
  11. postBind: これは、Podがバインドされた後に呼び出される情報提供のための拡張点です。
  12. multiPoint: このフィールドは設定のみ可能で、プラグインが適用されるすべての拡張点に対して同時に有効化または無効化することができます。

次の例のように、それぞれの拡張点に対して、特定のデフォルトプラグインを無効化、または自作のプラグインを有効化することができます。

apiVersion: kubescheduler.config.k8s.io/v1beta2
kind: KubeSchedulerConfiguration
profiles:
  - plugins:
      score:
        disabled:
        - name: PodTopologySpread
        enabled:
        - name: MyCustomPluginA
          weight: 2
        - name: MyCustomPluginB
          weight: 1

disabled配列のnameフィールドに*を使用することで、その拡張点の全てのデフォルトプラグインを無効化できます。また、必要に応じてプラグインの順序を入れ替える場合にも使用されます。

Scheduling plugins

以下のプラグインはデフォルトで有効化されており、1つ以上の拡張点に実装されています。

また、コンポーネント設定のAPIにより、以下のプラグインを有効にすることができます。 デフォルトでは有効になっていません。

複数のプロファイル

kube-schedulerは複数のプロファイルを実行するように設定することができます。 各プロファイルは関連するスケジューラー名を持ち、その拡張点に異なるプラグインを設定することが可能です。

以下のサンプル設定では、スケジューラーは2つのプロファイルで実行されます。1つはデフォルトプラグインで、もう1つはすべてのスコアリングプラグインを無効にしたものです。

apiVersion: kubescheduler.config.k8s.io/v1beta2
kind: KubeSchedulerConfiguration
profiles:
  - schedulerName: default-scheduler
  - schedulerName: no-scoring-scheduler
    plugins:
      preScore:
        disabled:
        - name: '*'
      score:
        disabled:
        - name: '*'

特定のプロファイルに従ってスケジュールさせたいPodは、その.spec.schedulerNameに、対応するスケジューラー名を含めることができます。

デフォルトでは、スケジューラー名default-schedulerとしてプロファイルが生成されます。 このプロファイルは、上記のデフォルトプラグインを含みます。複数のプロファイルを宣言する場合は、それぞれユニークなスケジューラー名にする必要があります。

もしPodがスケジューラー名を指定しない場合、kube-apiserverはdefault-schedulerを設定します。 従って、これらのPodをスケジュールするために、このスケジューラー名を持つプロファイルが存在する必要があります。

備考:

Podのスケジューリングイベントには、ReportingControllerとして.spec.schedulerNameが設定されています。 リーダー選出のイベントには、リスト先頭のプロファイルのスケジューラー名が使用されます。

備考:

すべてのプロファイルは、queueSort拡張点で同じプラグインを使用し、同じ設定パラメーターを持つ必要があります (該当する場合)。これは、pending状態のPodキューがスケジューラーに1つしかないためです。

複数の拡張点に適用されるプラグイン

kubescheduler.config.k8s.io/v1beta3からは、プロファイル設定にmultiPointというフィールドが追加され、複数の拡張点でプラグインを簡単に有効・無効化できるようになりました。 multiPoint設定の目的は、カスタムプロファイルを使用する際に、ユーザーや管理者が必要とする設定を簡素化することです。

MyPluginというプラグインがあり、preScorescorepreFilterfilter拡張点を実装しているとします。 すべての利用可能な拡張点でMyPluginを有効化するためには、プロファイル設定は次のようにします。

apiVersion: kubescheduler.config.k8s.io/v1beta3
kind: KubeSchedulerConfiguration
profiles:
  - schedulerName: multipoint-scheduler
    plugins:
      multiPoint:
        enabled:
        - name: MyPlugin

これは以下のように、MyPluginを手動ですべての拡張ポイントに対して有効にすることと同じです。

apiVersion: kubescheduler.config.k8s.io/v1beta3
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の展開から除外することができます。 これは、デフォルトのプラグインを無効にしたり、デフォルト以外のプラグインを無効にしたり、ワイルドカード('*')を使ってすべてのプラグインを無効にしたりする場合に有効です。 ScorePreScoreを無効にするためには、次の例のようにします。

apiVersion: kubescheduler.config.k8s.io/v1beta3
kind: KubeSchedulerConfiguration
profiles:
  - schedulerName: non-multipoint-scheduler
    plugins:
      multiPoint:
        enabled:
        - name: 'MyPlugin'
      preScore:
        disabled:
        - name: '*'
      score:
        disabled:
        - name: '*'

v1beta3では、MultiPointを通じて、内部的に全てのデフォルトプラグインが有効化されています。 しかしながら、デフォルト値(並び順やスコアの重みなど)を柔軟に設定し直せるように、個別の拡張点は用意されています。 例えば、2つのスコアプラグインDefaultScore1DefaultScore2に、重み1が設定されているとします。 その場合、次のように重さを変更し、並べ替えることができます。

apiVersion: kubescheduler.config.k8s.io/v1beta3
kind: KubeSchedulerConfiguration
profiles:
  - schedulerName: multipoint-scheduler
    plugins:
      score:
        enabled:
        - name: 'DefaultScore2'
          weight: 5

この例では、MultiPointはデフォルトプラグインであるため、明示的にプラグイン名を指定する必要はありません。 そして、Scoreに指定されているプラグインはDefaultScore2のみです。 これは、特定の拡張点を通じて設定されたプラグインは、常にMultiPointプラグインよりも優先されるためです。つまり、この設定例では、結果的に2つのプラグインを両方指定することなく、並び替えが行えます。

MultiPointプラグインを設定する際の一般的な優先順位は、以下の通りです。

  1. 特定の拡張点が最初に実行され、その設定は他の場所で設定されたものよりも優先される
  2. MultiPointを使用して、手動で設定したプラグインとその設定内容
  3. デフォルトプラグインとそのデフォルト設定

上記の優先順位を示すために、次の例はこれらのプラグインをベースにします。

プラグイン 拡張点
DefaultQueueSort QueueSort
CustomQueueSort QueueSort
DefaultPlugin1 Score, Filter
DefaultPlugin2 Score
CustomPlugin1 Score, Filter
CustomPlugin2 Score, Filter

これらのプラグインの有効な設定例は次の通りです。

apiVersion: kubescheduler.config.k8s.io/v1beta3
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プラグインを再宣言しても、エラーにはなりません。 特定の拡張点が優先されるため、再宣言は無視されます(ログは記録されます)。

このサンプルは、ほとんどのコンフィグを一箇所にまとめるだけでなく、いくつかの工夫をしています。

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設定の柔軟性と、拡張点を設定する既存の方法とのシームレスな統合を実証しています。

スケジューラー設定の移行

次の項目

2 - スケジューリングポリシー

バージョンv1.23より前のKubernetesでは、スケジューリングポリシーを使用して、predicatesprioritiesの処理を指定することができました。例えば、kube-scheduler --policy-config-file <filename>またはkube-scheduler --policy-configmap <ConfigMap>を実行すると、スケジューリングポリシーを設定することが可能です。

このスケジューリングポリシーは、バージョンv1.23以降のKubernetesではサポートされていません。関連するフラグである、policy-config-filepolicy-configmappolicy-configmap-namespaceuse-legacy-policy-configも同様にサポートされていません。 代わりに、スケジューラー設定を使用してください。

次の項目