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つ以上の拡張点に実装されています。

  • ImageLocality:Podが実行するコンテナイメージを既に持っているNodeを優先します。 拡張点:score
  • TaintToleration:TaintsとTolerationsを実行します。 実装する拡張点:filterpreScorescore
  • NodeName: PodのSpecのNode名が、現在のNodeと一致するかをチェックします。 拡張点:filter
  • NodePorts:要求されたPodのポートに対して、Nodeが空きポートを持っているかチェックします。 拡張点:preFilterfilter
  • NodeAffinity:nodeselectorsNodeアフィニティを実行します。 拡張点:filterscore
  • PodTopologySpread:Podトポロジーの分散制約を実行します。 拡張点:preFilterfilterpreScorescore
  • NodeUnschedulable:.spec.unschedulableがtrueに設定されているNodeをフィルタリングします。 拡張点:filter.
  • NodeResourcesFit:Podが要求しているすべてのリソースがNodeにあるかをチェックします。スコアは3つのストラテジのうちの1つを使用します:LeastAllocated(デフォルト)、MostAllocated、 とRequestedToCapacityRatio 拡張点:preFilterfilterscore
  • NodeResourcesBalancedAllocation:Podがスケジュールされた場合に、よりバランスの取れたリソース使用量となるNodeを優先します。 拡張点:score
  • VolumeBinding:Nodeが、要求されたボリュームを持っている、もしくはバインドしているかチェックします。 拡張点:preFilterfilterreservepreBindscore
  • VolumeRestrictions:Nodeにマウントされたボリュームが、ボリュームプロバイダ固有の制限を満たしているかを確認します。 拡張点:filter
  • VolumeZone:要求されたボリュームがゾーン要件を満たしているかどうかを確認します。 拡張点:filter
  • NodeVolumeLimits:NodeのCSIボリューム制限を満たすかどうかをチェックします。 拡張点:filter
  • EBSLimits:NodeのAWSのEBSボリューム制限を満たすかどうかをチェックします。 拡張点:filter
  • GCEPDLimits:NodeのGCP-PDボリューム制限を満たすかどうかをチェックします。 拡張点:filter
  • AzureDiskLimits:NodeのAzureディスクボリューム制限を満たすかどうかをチェックします。 拡張点:filter
  • InterPodAffinity:Pod間のaffinityとanti-affinityを実行します。 拡張点:preFilterfilterpreScorescore
  • PrioritySort:デフォルトの優先順位に基づくソートを提供します。 拡張点:queueSort.
  • DefaultBinder:デフォルトのバインディングメカニズムを提供します。 拡張点:bind
  • DefaultPreemption:デフォルトのプリエンプションメカニズムを提供します。 拡張点:postFilter

また、コンポーネント設定の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をスケジュールするために、このスケジューラー名を持つプロファイルが存在する必要があります。

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

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

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

  • カスタムのqueueSortプラグインを有効にし、デフォルトのプラグインを無効にする。
  • CustomPlugin1CustomPlugin2を有効にし、この拡張点のプラグイン内で、最初に実行されるようにする。
  • 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プラグインをスコア拡張点で使用できます。 この新しい拡張機能は、NodeResourcesLeastAllocatedNodeResourcesMostAllocatedRequestedToCapacityRatioプラグインの機能を組み合わせたものです。 例えば、以前は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は廃止されました。代わりにNode taintsを使用することで同様の振る舞いを実現できます。

  • v1beta2で有効化されたプラグインは、そのプラグインのデフォルトの設定より優先されます。

  • スケジューラーのヘルスとメトリクスのバインドアドレスに設定されているhostportが無効な場合、バリデーションに失敗します。

  • デフォルトで3つのプラグインの重みが増加しました。
    • InterPodAffinity:1から2
    • NodeAffinity:1から2
    • TaintToleration:1から3

次の項目

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も同様にサポートされていません。 代わりに、スケジューラー設定を使用してください。

次の項目