Kubernetes 1.23: SIG Scheduling の変更内容

# はじめに

Kubernetes 1.23がリリースされましたね :tada:


今回もKubernetes v1.23の[CHANGELOG](https://github.com/kubernetes/kubernetes/blob/master/CHANGELOG/CHANGELOG-1.23.md#v1230)をベースにSIG Schedulingに関する機能について紹介していきます。

過去の変更内容:
- [Kubernetes 1.22: SIG Scheduling の変更内容](https://qiita.com/everpeace/items/c7ab1c366dd777dce14a)
- [Kubernetes 1.21: SIG Scheduling の変更内容](https://qiita.com/everpeace/items/084da032a83c81bb887a)
- [Kubernetes 1.20: SIG Scheduling の変更内容](https://qiita.com/everpeace/items/c2babe4f83ce31c41d06)

## 所感

v1.23では設定周りの変更が入った程度で、それ以外はバグ修正,メトリクス周りの修正程度で目立ったものはありませんでした。

- __`kubescheduler.config.k8s.io/v1beta3`が追加__されました。
    - `multiPoint` fieldの登場によってscheduler pluginが簡単・安全に有効化/無効化できるようになります。
    - `TaintTolerations, NodeAffinity, InterPodAffinity`Pluginのデフォルト重みの増えます。これによって`PreferNoSchedule`なEffectを持つTaintへのTolerationや、`preferredDuringSchedulingIgnoredDuringExecution`なaffinityがこれまでよりも効きやすくなります。
- __`kubescheduler.config.k8s.io/v1beta1`が削除__されました。
-  __[legacyなscheduler policy config](https://v1-22.docs.kubernetes.io/docs/reference/scheduling/policies/)が削除__されました。


> 下記 :pencil: がついた文章は、CHANGELOGの公式内容ではなく筆者の補足です。

# What's New (新情報)

## Simplified Multi-point plugin configuration for scheduler

kube-schedulerは複数の拡張点(extension point)を持つPluginの設定を単純化できる`multiPoint`設定フィールドを追加しました。このフィールドは、管理者がschedulerをシンプルに設定できるようにすることを目的としています。

`multiPoint`フィールドで有効化されたpluginは、自動的に実装されているすべて拡張点をschedulerに登録します。たとえば、ScoreとFilterという拡張点を実装しているpluginは、双方同時にenabledできるようになります。これによって、拡張点を個別のenables/disabledを手動で編集せずに、全てのpluginをenabled/disbledすることができるようになります。これらの拡張点を個別に設定する方式は、ほとんどのユーザーにとって無関係であるため、抽象化されました。

:pencil: kube-schedulerは[Scheduling Framework](https://kubernetes.io/docs/concepts/scheduling-eviction/scheduling-framework/)に基づいて動作していて、各機能はPluginという形で実装されています。それらのPluginは[KubeSchedulerConfiguration](https://kubernetes.io/docs/reference/scheduling/config/) を通して、有効化/無効化できるようになっています。各PluginはScheduling Frameworkの拡張点(extension point)を実装するのですが、これまではユーザの意図とはあまり関係のない拡張点の単位で設定を有効化/無効化する必要があり設定が煩雑でした。また設定を誤って一部の拡張点でしか設定しないと、Pluginが意図しない動作をする可能性すらありました。`multiPoint`フィールドを使うと拡張点単位ではなくPluginごとに有効化/無効化の設定ができるため、単純かつ安全になりました。

<details><summary>:pencil:`multiPoint` を使わない場合 → ユーザはPluginをenabled/disabledしたいのであって拡張点にあまり興味はないはずなのに、拡張点ごとにenabled/disabledしなきゃいけなくて、すごく面倒くさい。間違うと誤動作する可能性すらある。</summary><div>

```yaml
# v1beta2(multiPoint使えない)場合
# 例えば、デフォルトで有効になっているPodTopologySpreadを外す場合
# 実装している拡張点すべてでenabled/disabledする必要がある
# (しかも間違うと意図しない動作する可能性すらある)
apiVersion: kubescheduler.config.k8s.io/v1beta2
kind: KubeSchedulerConfiguration
profiles:
  - plugins:
      prescore:
        disabled:
          - name: PodTopologySpread
      score:
        disabled:
          - name: PodTopologySpread
      prefilter:
        disabled:
          - name: PodTopologySpread
      filter:
        disabled:
          - name: PodTopologySpread
---
#自作のPluginを利用する際にも、
#　実装している拡張点毎にenabledする必要がある
apiVersion: kubescheduler.config.k8s.io/v1beta2
kind: KubeSchedulerConfiguration
profiles:
  - plugins:
      score:
        enabled:
          - name: MyPlugin
      filter:
        enabled:
          - name: MyPlugin
```
</div></details>

<details><summary>:pencil:`multiPoint`を使う場合 → Pluginごとに簡単かつ安全にenabled/disabledできて便利！</summary><div>

```yaml
# v1beta3のmultiPointを使う場合
# すべての拡張点を適切にenabled/disabledしてくれる
apiVersion: kubescheduler.config.k8s.io/v1beta3
kind: KubeSchedulerConfiguration
profiles:
  - plugins:
      multiPoint:
        enabled:
          - name: MyPlugin
```
</div></details>

:pencil:　"[KubeSchedulerConfigrationのv1beta3(Kubernetes v1.23)で追加されるMulti-point plugin configurationについて](https://sanposhiho.com/posts/kubeschedulerconfigrationv1beta3/)"でも詳細に解説されているので参照してください。

### Structured logging graduate to Beta

構造化ロギングがBetaマイルストーンに到達しました。kubeletとkube-schedulerの多くのログメッセージが構造化ロギングに変換されました。ユーザはJSON出力を試したり、構造化テキストフォーマットをパースしたりして、multi-line文字列の処理といったopen issueについてのフィードバックを行うことが推奨されています。

# Urgent Upgrade Notes（必ず一読してからアップグレードしなければならない事項）

:pencil: ありません。とはいえ、action requiredな変更がいくつかあるので注意です。

# Deprecation (非推奨)

- __[ACTION REQUIRED]__ Kube-scheduler: `--port`,`--address`フラグは何の効果もなくなり、v1.24で削除されます。insecure portフラグである`--port`は0しか指定できなくなります。また、 `kubescheduler.config.k8s.io/v1beta1`の`metricsBindAddress`, `healthzBindAddress` fieldsは指定しても効果がなく、空であることが期待されます。そして、`kubescheduler.config.k8s.io/v1beta2`では完全に削除されます。加えて、下記に注意してください:
  - kube-schedulerは`--authorization-kubeconfig` and `--authentication-kubeconfig`が正しく設定された状態でスタートしなければなりません。
  - kube-schedulerのliveness/readiness probesはHTTPSを使わなければなりません。デフォルトポートが10259に変更になります。
  - kube-schedulerのメトリクスにアクセスするApplicationは `/metrics` nonResourceURLsへのアクセスが許可されたservice accountを使う必要があります。([#96345](https://github.com/kubernetes/kubernetes/pull/96345), [@ingvagabund](https://github.com/ingvagabund)) [SIG Cloud Provider, Scheduling and Testing]
- deprecatedな`scheduler_volume_scheduling_duration_seconds`メトリクスが削除されました。([#104518](https://github.com/kubernetes/kubernetes/pull/104518), [@dntosas](https://github.com/dntosas)) [sig/scheduling,sig/storage,sig/instrumentation]

# API Change （API の変更）

- kube-apiserver: `rbac.authorization.k8s.io/v1alpha1`API が削除されます。v1.8以降利用可能な `rbac.authorization.k8s.io/v1`APIを使ってください。 `scheduling.k8s.io/v1alpha1`APIが削除されます。v1.14以降利用可能な`scheduling.k8s.io/v1`APIを使ってください。([#104248](https://github.com/kubernetes/kubernetes/pull/104248), [@liggitt](https://github.com/liggitt))　
- `v1beta3` APIが追加されました。このバージョンでは
    - ユーザが指定できるnode priorityのweightが増えます。`TaintTolerations`が3に、`NodeAffinity`が2に、`InterPodAffinity`が2になります。
    - `HealthzBindAddress`, `MetricsBindAddress` fieldsが削除されます。
    - :pencil: `v1beta2`まではすべてこれらのScore pluginのweightは1でした。`v1beta3`からこれらのNodeScoreがより強く影響するようになります。`PreferNoSchedule` effectなTaintや、`preferredDuringSchedulingIgnoredDuringExecution`なaffinityを使っている際に影響を受けます。
    - :pencil: `v1beta3`では設定項目の変更は殆どなく、上記の重み変更によるデフォルト設定でのbreaking changeに伴うversion bumpとなっています。
- __Action Required__: kube-scheduler: 設定ファイルバージョン`v1beta1`が削除されます。v1.23に更新する前にv1beta2(xref: https://github.com/kubernetes/enhancements/issues/2901) もしくはv1beta3に更新してください。([#104782](https://github.com/kubernetes/kubernetes/pull/104782), [@kerthcet](https://github.com/kerthcet))
- `KubeSchedulerConfiguration`は新しく`MultiPoint`フィールドを提供します。このフィールドによって各プラグインが対応しているextension pointを適切に登録することができるようになります。([#105611](https://github.com/kubernetes/kubernetes/pull/105611), [@damemi](https://github.com/damemi)) [SIG Scheduling and Testing]
    - :pencil: [What's New(新情報)](#simplified-multi-point-plugin-configuration-for-scheduler)の節参照
- __Action Required__: legacyなscheduler policy configはv1.23で削除されます。関連する`policy-config-file`, `policy-configmap`, `policy-configmap-namespace` and `use-legacy-policy-config`フラグも削除されます。Component Config に移行してください。詳細は https://kubernetes.io/docs/reference/scheduling/config/ を参照してください。([#105424](https://github.com/kubernetes/kubernetes/pull/105424), [@kerthcet](https://github.com/kerthcet))

# Feature （機能）

- `VolumeBinding` pluginで、ClaimLostフェーズのPVCを`UnschedulableAndUnresolvable`として処理するように改善しました。([#105245](https://github.com/kubernetes/kubernetes/pull/105245), [@yibozhuang](https://github.com/yibozhuang))
- `pending_pods`, `preemption_attempts_total`, `preemption_victims` and `schedule_attempts_total`メトリクスがstableにgraduateしました。　また、`e2e_scheduling_duration_seconds`が`scheduling_attempt_duration_seconds`にリネームされ、stableにgraduateしました。([#105941](https://github.com/kubernetes/kubernetes/pull/105941), [@rezakrimi](https://github.com/rezakrimi)) [SIG Instrumentation, Scheduling and Testing]
- Jobが未スタートかつsuspendな場合にのみ、Node affinity, Node selectors, and tolerationsがmutableになりました。([#105479](https://github.com/kubernetes/kubernetes/pull/105479), [@ahg-g](https://github.com/ahg-g))
    - :pencil: [KEP-2926: Allow updating scheduling directives of suspended jobs](https://github.com/kubernetes/enhancements/pull/2931)
- `RequestedToCapacityRatio` ScoringStrategyを利用する際、空のshapeはエラーになります。([#106169](https://github.com/kubernetes/kubernetes/pull/106169), [@kerthcet](https://github.com/kerthcet)) [SIG Scheduling]
    - :pencil: `RequestedToCapacityRatio`はNodeにおけるrequests量に応じてスコアを自分自身で指定できる(shapeと呼ばれます)Pluginです。
    - :pencil: 参考: [Resource Bin Packing for Extended Resources](https://kubernetes.io/docs/concepts/scheduling-eviction/resource-bin-packing/)
- `kube-scheduler`は--v<10でも　nodeのscoreをログ出力するようになります。--v=4,5ではtop　3　nodeのtop 3 pluginのスコアを、--v=6,7,8,9ではtop 6 nodeのすべてのpluginのスコアを出力します。([#103515](https://github.com/kubernetes/kubernetes/pull/103515), [@muma378](https://github.com/muma378))
    - :pencil: [v1.21で--v=4以上で全ノードのtop 3 pluginの情報が出力されるようになりました](https://qiita.com/everpeace/items/084da032a83c81bb887a#feature-%E6%A9%9F%E8%83%BD)が、全ノードでログ出力は大規模クラスターではschedulerのパフォーマンスが50%ほど劣化すると報告されており([#103515](https://github.com/kubernetes/kubernetes/pull/103515))、段階的に出力内容を調整できるように修正されました。


# Documentation

- `pod_scheduling_duration_seconds`, `pod_scheduling_attempts`, `framework_extension_point_duration_seconds`, `plugin_execution_duration_seconds` and `queue_incoming_pods_total`メトリクスがstableにGraduateしました。([#106266](https://github.com/kubernetes/kubernetes/pull/106266), [@ahg-g](https://github.com/ahg-g)) [SIG Instrumentation, Scheduling and Testing]


# Failing Test (失敗しているテスト)

:pencil: ありません。


# Bug or Regression （バグまたはリグレッション）

- 一時的な故障によってschedulerがPodの削除イベントを観測できなかった場合でもscheduelr cacheからPodが削除される様に修正しました。([#106102](https://github.com/kubernetes/kubernetes/pull/106102), [@alculquicondor](https://github.com/alculquicondor)) [SIG Scheduling]
- requestsを持たないようなpodが存在するnodeにおける`NodeResourcesBalancedAllocation`scoring pluginsの挙動を修正しました。 ([#105845](https://github.com/kubernetes/kubernetes/pull/105845), [@ahmad-diaa](https://github.com/ahmad-diaa))
    - :pencil: `NodeResourcesBalancedAllocation` scoring pluginでは、requestsが空のpodについては、scheduler defaultのepsilon量をrequestsとして計算していましたが、これだと、zero requestsのpodが大量にある場合にbalanceしないという問題を修正しています。([#105220](https://github.com/kubernetes/kubernetes/issues/105220))
- nodeがzoneラベルを持たない場合のtopology spreadingのシステムデフォルトの設定を修正しました。この修正によってデフォルトでPodが分散されるようになります。　([#105046](https://github.com/kubernetes/kubernetes/pull/105046), [@alculquicondor](https://github.com/alculquicondor))
    - :pencil: Kubernetes 1.19以降、PodTopologySpreadのシステムデフォルト設定ではnodeが`kubernetes.io/hostname`, `topology.kubernetes.io/zone`の両ラベルを持っていることを想定しており、オプレミスクラスタ等でzoneラベルがないnodeがあるとPodTopologySpreadが期待通り動作しなかった問題を修正しています。([#102136](https://github.com/kubernetes/kubernetes/pull/102136))
    - :pencil: v1.20, v1.21, v1.22にbackportされています。
- 改行やエスケープを含むようなkube-schedulerの設定ファイルをログ出力する際の可読性を改善しました。([#106228](https://github.com/kubernetes/kubernetes/pull/106228), [@sanchayanghosh](https://github.com/sanchayanghosh)) [SIG Scheduling]
- schedulerのnode limitsとkubeletのhostpath checkでgeneric ephemeral volumesが適切に処理されていなかったのを修正しました。([#100482](https://github.com/kubernetes/kubernetes/pull/100482), [@pohly](https://github.com/pohly))
- kube-schedulerで未定義のフラグを指定した場合にusageメッセージを出力しないようになります。([#104503](https://github.com/kubernetes/kubernetes/pull/104503), [@sanposhiho](https://github.com/sanposhiho)) [sig/scheduling]
- メトリクスの変更: `scheduler_volume_scheduling_duration_seconds_bucket`メトリクスで公開されているBucketを修正しました。([#100720](https://github.com/kubernetes/kubernetes/pull/100720), [@dntosas](https://github.com/dntosas)) 
    - :pencil: このhisotogramメトリクスのバケットの最小値が1000秒になってしまっており、1000秒未満の値も1000秒として報告されていたのが修正されました。
- Schedulerのリソースメトリクスにおいて２進接頭辞を使っている場合(2.5Gi, 1.1Ki)にリソース量が非常に小さな値として報告されていたのを修正しました。([#103751](https://github.com/kubernetes/kubernetes/pull/103751), [@y-tag](https://github.com/y-tag)) [sig/scheduling,sig/api-machinery]
    - 　:pencil: このバグの影響は、Kubernetes 1.20で導入された、scheduerの`/metrics/resources`endpointで公開されている`kube_pod_resource_{request|limits}`のみです。backport等もされていないようです。
    - 　:pencil: 参考: [Kubernetes 1.20: Metrics Changes と SIG Instrumentation の変更内容](https://qiita.com/watawuwu/items/ab5a0f11210d15cc6a86#pod-resource-metrics)
- schedulerで`--leader-elect*`CLI argsが有効になるように修正しました。 ([#105915](https://github.com/kubernetes/kubernetes/pull/105915), [#105712](https://github.com/kubernetes/kubernetes/pull/105712), [@Huang-Wei](https://github.com/Huang-Wei))
- `pods/binding`サブリソースがPodの`metadata.uid`と`metadata.resourceVersion`を参照する用になります。([#105913](https://github.com/kubernetes/kubernetes/pull/105913), [@aholic](https://github.com/aholic))


# Other (その他の修正)
:pencil: ほとんどがstructured loggingに対応するPRです

- Schedulerで、PersistentVolumeClaimをbindするPersistentVolumeが存在しないことが原因でnodeが選択されなかった場合のエラーメッセージを改善しました。([#105196](https://github.com/kubernetes/kubernetes/pull/105196), [@yibozhuang](https://github.com/yibozhuang))
- `pkg/scheduler/framework/plugins/interpodaffinity/filtering.go`,`pkg/scheduler/framework/plugins/podtopologyspread/filtering.go`, `pkg/scheduler/framework/plugins/volumezone/volume_zone.go`をstructured loggingに移行しました。([#105931](https://github.com/kubernetes/kubernetes/pull/105931), [@mengjiao-liu](https://github.com/mengjiao-liu))
- `pkg/scheduler`をstructured loggingに移行しました。 ([#99273](https://github.com/kubernetes/kubernetes/pull/99273), [@yangjunmyfm192085(https://github.com/yangjunmyfm192085))
- `cmd/kube-scheduler/app/server.go`, `pkg/scheduler/framework/plugins/nodelabel/node_label.go`, `pkg/scheduler/framework/plugins/nodevolumelimits/csi.go`, `pkg/scheduler/framework/plugins/nodevolumelimits/non_csi.go`をstructured loggingに移行しました。 ([#105855](https://github.com/kubernetes/kubernetes/pull/105855), [@shivanshu1333]
- `pkg/scheduler/framework/plugins/volumebinding/assume_cache.go`をstructured loggingに移行しました。 ([#105904](https://github.com/kubernetes/kubernetes/pull/105904), [@mengjiao-liu](https://github.com/mengjiao-liu)) [SIG Instrumentation, Scheduling and Storage]
- `pkg/scheduler/framework/preemption/preemption.go`, `pkg/scheduler/framework/plugins/examples/stateful/stateful.go`,`pkg/scheduler/framework/plugins/noderesources/resource_allocation.go`をstructured loggingに移行しました。 ([#105967](https://github.com/kubernetes/kubernetes/pull/105967), [@shivanshu1333](https://github.com/shivanshu1333)) [SIG Instrumentation, Node and Scheduling]
- schedulerのファイル `cache.go`をstructured loggingに移行しました。 ([#105969](https://github.com/kubernetes/kubernetes/pull/105969), [@shivanshu1333](https://github.com/shivanshu1333)) [SIG Instrumentation and Scheduling]
- schedulerのファイル`comparer.go`, `dumper.go`, `node_tree.go`をstructured loggingに移行しました。 ([#105968](https://github.com/kubernetes/kubernetes/pull/105968), [@shivanshu1333](https://github.com/shivanshu1333)) [SIG Instrumentation and Scheduling]