Kubernetes 1.32: SIG-Scheduling の変更内容

Kubernetes 1.32 の [CHANGELOG](https://github.com/kubernetes/kubernetes/blob/master/CHANGELOG/CHANGELOG-1.32.md) から、SIG-Scheduling に関するところを抜粋して紹介します。 :pencil: は筆者によるコメントです。

過去 3 リリースの変更内容：

- [Kubernetes 1.31: SIG-Scheduling の変更内容](https://qiita.com/ordovicia/items/1a392826d7829f8a56bb)
- [Kubernetes 1.30: SIG-Scheduling の変更内容](https://qiita.com/ordovicia/items/fc0053e0d27d5b0bcca0)
- [Kubernetes 1.29: SIG-Scheduling の変更内容](https://qiita.com/ordovicia/items/e99d8ab6ca3b540b70e1)

## :pencil: 所感

久しぶりに大きい変更内容がいくつもあるリリースです。

ついに QueueingHint 機能と Dynamic Resource Allocation (DRA) がベータに昇格しました。
QueueingHint ([KEP-4247: Per-plugin callback functions for efficient requeueing in the scheduling queue](https://github.com/kubernetes/enhancements/blob/master/keps/sig-scheduling/4247-queueinghint/README.md)) は、スケジューラプラグインが Pod をスケジュール不可と判断した後、その Pod を再スケジュールするタイミングを、クラスタで起こったイベントをもとにより賢く判定する機能です。
無駄な再スケジュール処理を減らすことで、スケジューリング処理のスループットの向上が期待できます。
また、優先度が高い Pod によってスケジューリングキューを占有されてしまう head of line blocking 問題も緩和できます。

DRA については、[KEP-3063: Dynamic Resource Allocation with Control Plane Controller](https://github.com/kubernetes/enhancements/blob/master/keps/sig-node/3063-dynamic-resource-allocation/README.md) で提案されていた "classic" DRA のサポートが削除され、[KEP-4381: Dynamic Resource Allocation with Structured Parameters](https://github.com/kubernetes/enhancements/blob/master/keps/sig-node/4381-dra-structured-parameters/README.md) に一本化されました。
先日の KubeCon + CloudNativeCon NA 2024 でも DRA の話題がいくつもあり、プロダクションで使っている発表もあったので、開発や利用が進んでいることを感じます。
一方で、どんどん複雑になっているとも感じており、DRA の全機能がほんとうに Kubernetes 組み込みで必要だったのかは議論を追ったり KEP を読み込んだりしないとわかりません。

アルファで入った機能も、大きなものがいくつもあります。
その中でも注目しているのは、プリエンプション処理を非同期にする [KEP-4832: Asynchronous Preemption](https://github.com/kubernetes/enhancements/tree/master/keps/sig-scheduling/4832-async-preemption) です。
プリエンプションが多発する、計算リソースが有限の Kubernetes クラスタでスケジューリングスループットを向上できるということで、期待が大きいです。

## Urgent Upgrade Notes

すべての SIG について、項目はありません。

## Changes by Kind

### Deprecation

SIG-Scheduling に関する項目はありません。

### API Change

- **ACTION REQUIRED**: カスタムスケジューラプラグインの開発者向け: `preemption.Interface` インターフェイスの `PodEligibleToPreemptOthers` メソッドは、パラメータに `ctx` を含むようになりました。プラグインの実装をそれに応じて更新してください。([#126465](https://github.com/kubernetes/kubernetes/pull/126465), [@googs1025](https://github.com/googs1025)) [SIG Scheduling]
    - :pencil: `preemption.Interface` インターフェイスは、カスタムプラグインでプリエンプション処理を実装するときに便利なインターフェイスです。インターフェイスを実装した構造体を作ることで、プリエンプション処理の全体が実装できるようになっています。
- `NodeToStatusMap` をマップから構造体に変更し、そのエントリにアクセスするメソッドを公開しました。マップに存在しないノードのステータスを定める `absentNodesStatus` フィールドを追加しました。**ACTION REQUIRED**: Out-of-tree PostFilter プラグインの開発者は、`NodeToStatusMap` の使用方法を更新してください。また、`NodeToStatusMap` は最終的に `NodeToStatusReader` にリネームされる予定です。([#126022](https://github.com/kubernetes/kubernetes/pull/126022), [@macsko](https://github.com/macsko)) [SIG Node, Scheduling, and Testing]
    - :pencil: [kubernetes/kubernetes#125345](https://github.com/kubernetes/kubernetes/issues/125345) でトラックされていた、ノード数に対するスケーラビリティを改善する取り組みの一つです。Kubernetes 1.31 では、[kubernetes/kubernetes#125197](https://github.com/kubernetes/kubernetes/pull/125197) でマップの要素数を減らす変更が入りました。
- Pod のプリエンプションを非同期にする機能がアルファとして追加されました。`SchedulerAsyncPreemption` フィーチャゲートを有効にすると、スケジューラはプリエンプションに起因する kube-apiserver 呼び出しを非同期で実行し、パフォーマンスが向上します。([#128170](https://github.com/kubernetes/kubernetes/pull/128170), [@sanposhiho](https://github.com/sanposhiho)) [SIG Scheduling and Testing]
    - :pencil: [KEP-4832: Asynchronous Preemption](https://github.com/kubernetes/enhancements/tree/master/keps/sig-scheduling/4832-async-preemption) で提案された機能です。プリエンプションでは Pod を削除する API 呼び出しをおこない、その間スケジューリング処理を待たせてしまいます。これを非同期にし、並行して他の Pod のスケジューリングを進められるようにすることで、スケジューラのスループットを向上させます。
- Pod API に、Pod レベルのリソース量のための `spec` レベルの `resources` を追加しました。([#128407](https://github.com/kubernetes/kubernetes/pull/128407), [@ndixita](https://github.com/ndixita)) [SIG API Machinery, Apps, CLI, Cluster Lifecycle, Node, Release, Scheduling and Testing]
    - :pencil: [KEP-2837: Pod Level Resource Specifications](https://github.com/kubernetes/enhancements/blob/master/keps/sig-node/2837-pod-level-resource-spec/README.md) で提案されている機能です。コンテナごととは別に Pod 全体での resources limits/requests を定義できるようにすることで、リソース管理を簡単にし、リソース効率も上げることを目的としています。`PodLevelResources` フィーチャゲート（アルファ）で有効になります。
    - :pencil: ちなみに、Pod の resources limits/requests を計算するには、[`k8s.io/component-helpers/resource`](https://github.com/kubernetes/kubernetes/blob/master/staging/src/k8s.io/component-helpers/resource/helpers.go) を使うと便利です。Init container（サイドカーコンテナ含む）も考慮して計算してくれます。
- `ContainerStatus.AllocatedResources` は、別のフィーチャゲート `InPlacePodVerticalScalingAllocatedStatus` でガードされるようになりました。([#128377](https://github.com/kubernetes/kubernetes/pull/128377), [@tallclair](https://github.com/tallclair)) [SIG API Machinery, CLI, Node, Scheduling and Testing]
    - :pencil: In-place Update of Pod Resources 機能をベータに昇格する際に、このフィールドは使わなくなるようです。そのため、`InPlacePodVerticalScaling` に加えて `InPlacePodVerticalScalingAllocatedStatus` フィーチャゲートも有効にした場合にのみ、このフィールドが計算されるようになります。
- DRA: Opaque なデバイス構成パラメータの長さを制限しました。作成・更新時に Kubernetes は 10KiB のサイズ制限を適用します。([#128601](https://github.com/kubernetes/kubernetes/pull/128601), [@pohly](https://github.com/pohly)) [SIG API Machinery, Apps, Auth, Etcd, Node, Scheduling and Testing]
- DRA: シナリオによっては Pod のスケジューリングが最大16倍高速化されました。スケジューリングスループットはクラスタの利用状況に大きく依存し、リソースに余裕のあるクラスタでは高くなり、利用率が増加すると低下します。([#127277](https://github.com/kubernetes/kubernetes/pull/127277), [@pohly](https://github.com/pohly)) [SIG API Machinery, Apps, Architecture, Auth, Etcd, Instrumentation, Node, Scheduling and Testing]
    - :pencil: ベンチマークを作り、pprof で DRA のスケジューラプラグインのプロファイルを取りながら最適化をおこなったようです。
- DRA: `DeviceRequestAllocationResult` 構造体に `AdminAccess` フィールドを追加しました。デバイス割り当ての際に、`DeviceRequest` フィールド内の対応するフィールドの代わりにこちらを使うべきです。デバイスが管理者アクセスのためにのみ割り当てられている場合、通常の使用のために再度割り当てることは可能です。管理者アクセスを許可するには、1.32 から `DRAAdminAccess` フィーチャゲートを有効にする必要があります。([#127266](https://github.com/kubernetes/kubernetes/pull/127266), [@pohly](https://github.com/pohly)) [SIG API Machinery, Apps, Auth, Etcd, Network, Node, Scheduling and Testing]
    - :pencil: 未マージですが、[KEP-5018: DRA: AdminAccess for ResourceClaims and ResourceClaimTemplates](https://github.com/kubernetes/enhancements/blob/677a7edc4bb7c371ede3a98d7f79e0f48a19dc55/keps/sig-node/5018-dra-adminaccess/README.md) に DRA デバイスの管理者アクセスについてまとまっています。デバイスの正常性確認など、管理者アクセスを必要とするケースで使う機能のようです。
- kube-scheduler から `AzureDiskLimits`, `CinderLimits`, `EBSLimits`, `GCEPDLimits` プラグインを削除しました。対応する CSI ドライバが `NodeGetInfoResponse` でノードが処理できるボリューム数を報告し、kubelet がこの制限情報を `CSINode` オブジェクトに保存するため、スケジューラはそのノードでのドライバの制限を認識できます。**ACTION REQUIRED**: スケジューラの設定でこれらのプラグインを明示的に有効にしていた場合、削除してください。([#124003](https://github.com/kubernetes/kubernetes/pull/124003), [@carlory](https://github.com/carlory)) [SIG Scheduling, Storage and Testing]
    - :pencil: Kubernetes 1.31 で非推奨になっていたプラグインです。
- "Classic" DRA のすべてのサポートが削除されました。アルファだった `DRAControlPlaneController` フィーチャゲートは利用できなくなりました。Kubernetes は Pod への動的リソース割り当てに「構造化パラメータ」モデル (アルファ) のみを使用するようになりました。**ACTION REQUIRED**: Classic DRA が有効だったクラスタでは、アップグレード前に classic DRA に依存するすべてのワークロード（Pod, Deployment など）を削除し、`PodSchedulingContext` リソースがすべてなくなっていることを確認してください。`PodSchedulingContext` リソースはアップグレード後に API サーバ経由で削除できず、ワークロードが正しく動作しなくなります。([#128003](https://github.com/kubernetes/kubernetes/pull/128003), [@pohly](https://github.com/pohly)) [SIG API Machinery, Apps, Auth, Etcd, Node, Scheduling and Testing]
- DRA のコア機能がベータに昇格しました。アップグレード時の対応は不要です。以前の `v1alpha3` API は引き続きサポートされるため、`v1alpha3` を利用する既存のワークロードや DRA ドライバは引き続き動作します。ただし、DRA リソース (`ResourceClaim`, `ResourceClaimTemplate`, `DeviceClass`, `ResourceSlice`) がクラスタに存在する場合、1.32 から 1.31 へのダウングレードはサポートされません。これは、新しい `v1beta1` がストレージバージョンとして使用され、1.31 では読めないためです。([#127511](https://github.com/kubernetes/kubernetes/pull/127511), [@pohly](https://github.com/pohly)) [SIG API Machinery, Apps, Auth, Etcd, Node, Scheduling and Testing]

### Feature

- `SchedulerQueueingHints` 機能がベータに昇格しました。フィーチャゲートはデフォルトで有効になっています。([#128472](https://github.com/kubernetes/kubernetes/pull/128472), [@sanposhiho](https://github.com/sanposhiho)) [SIG Scheduling]
- `CSILimit` プラグインについて、`PersistentVolumeClaim/Add` イベントに対する QueueingHint を実装しました。([#124703](https://github.com/kubernetes/kubernetes/pull/124703), [@utam0k](https://github.com/utam0k)) [SIG Scheduling and Storage]
- QueueingHint 機能について、新しいクラスタイベント `UpdatePodSchedulingGatesEliminated` と `UpdatePodTolerations` を追加しました。([#127083](https://github.com/kubernetes/kubernetes/pull/127083), [@sanposhiho](https://github.com/sanposhiho))
    - :pencil: 前者は Pod のスケジューリングゲートが空になったとき、後者は Pod の toleration が変更（kube-apiserver により追加しか許可されない）されたときにプラグインに通知されます。
- `NodeAffinity` プラグインの `Node` イベントに対する QueueingHint を改善し、Pod をスケジュール不可から変えない無関係な変更を無視するようにしました。([#127444](https://github.com/kubernetes/kubernetes/pull/127444), [@dom4ha](https://github.com/dom4ha)) [SIG Scheduling and Testing]
- `NodeResourceFit` プラグインの `Node` イベントに対する QueueingHint を改善し、Pod をスケジュール不可から変えない無関係な変更を無視するようにしました。([#127473](https://github.com/kubernetes/kubernetes/pull/127473), [@dom4ha](https://github.com/dom4ha)) [SIG Scheduling and Testing]
- QueueingHint 機能について、inflight なイベントのメトリックを追加しました。([#127052](https://github.com/kubernetes/kubernetes/pull/127052), [@sanposhiho](https://github.com/sanposhiho)) [SIG Scheduling]
    - :pencil: 処理中のイベントの数を観測することで、メモリリークなどのデバッグに役立ちます。
- `VolumeBinding` プラグインの `CSIDriver` イベントに対する QueueingHint を実装し、スケジューリングのスループットを向上させました。([#125171](https://github.com/kubernetes/kubernetes/pull/125171), [@YamasouA](https://github.com/YamasouA)) [SIG Scheduling and Storage]
- スケジューラはゲートされた Pod を再スケジュールする前に、バックオフペナルティを与えるようになりました。([#126029](https://github.com/kubernetes/kubernetes/pull/126029), [@sanposhiho](https://github.com/sanposhiho)) [SIG Scheduling]
    - :pencil: スケジューラには、スケジュール不可となった（= スケジューリングサイクルを消費した）Pod にバックオフというペナルティを与えるという原則がありますが、スケジューリングゲートをもつ Pod はこの原則に沿っていませんでした。
- 許可されていないラベル値は、スケジューラのメトリクスで "unexpected" として表示されます。([#126762](https://github.com/kubernetes/kubernetes/pull/126762), [@richabanker](https://github.com/richabanker)) [SIG Instrumentation and Scheduling]
    - :pencil: [KEP-2305: Dynamic Cardinality Enforcement](https://github.com/kubernetes/enhancements/tree/master/keps/sig-instrumentation/2305-metrics-cardinality-enforcement) という機能があり、`--allow-metric-labels` フラグなど実行時の設定により、コンポーネントが公開するメトリクスのカーディナリティを制限することができます。このフラグが読まれる前にメトリクスの初期化をしてしまっていたため、フラグが効いていないという問題があり、今回修正されました。
- QueueingHint 機能での Node イベントの種類には、taints, labels, allocatable の更新が含まれます。In-tree のプラグインは、これらのフィールドを変更しない Node の更新を無視します。([#127220](https://github.com/kubernetes/kubernetes/pull/127220), [@sanposhiho](https://github.com/sanposhiho)) [SIG Node, Scheduling and Storage]
    - :pencil: QueueingHint 機能が置き換える `preCheck` と呼ばれるしくみでは、広い範囲の Node イベントを購読する必要がありました。QueueingHint 機能で、より細粒度なイベント購読が可能になりました。
- QueueingHint 機能が有効な場合、スケジューリングキューに保存されるイベントのキャッシュを可能な限り早くクリアし、スケジューラのメモリ消費を抑えるようになりました。([#120586](https://github.com/kubernetes/kubernetes/pull/120586), [@sanposhiho](https://github.com/sanposhiho)) [SIG Scheduling]

### Documentation

SIG-Scheduling に関する項目はありません。

### Failing Test

SIG-Scheduling に関する項目はありません。

### Bug or Regression

- DRA: DRA ドライバが、それが作成するリソースを要求する Pod の作成後に起動された場合、そのようなスケジュール不可だった Pod の再スケジュールがおこなわれていませんでした。構造化パラメータを使用する DRA のみが影響を受けました。([#126807](https://github.com/kubernetes/kubernetes/pull/126807), [@pohly](https://github.com/pohly)) [SIG Node, Scheduling and Testing]
- DRA: QueueingHint 機能を有効にした場合、生成された ResourceClaim の名前を記録してもスケジューリングがトリガーされず、Pod が不必要にしばらくスケジュール不可の状態にとどまっていました。([#127497](https://github.com/kubernetes/kubernetes/pull/127497), [@pohly](https://github.com/pohly)) [SIG Auth, Node, Scheduling and Testing]
- ノードの `kubernetes.io/hostname` ラベルがノード名と一致しない場合に、PersistentVolume にバインドされており `nodeAffinity` をもつ Pod が誤ったノードにスケジュールされたり、スケジューリングに失敗する可能性があるバグを修正しました。([#125398](https://github.com/kubernetes/kubernetes/pull/125398), [@AxeZhan](https://github.com/AxeZhan)) [SIG Scheduling and Storage]
- スケジューラがプラグインにノードの削除を正しく通知していなかったバグを修正しました。`Node/Delete` イベントを購読するすべてのプラグインに影響するバグで、プラグインによって拒否された Pod がノード削除後も誤ってキューに残されました。In-tree プラグインの中では、`PodTopologySpread` が唯一の影響を受けたプラグインです。([#127464](https://github.com/kubernetes/kubernetes/pull/127464), [@sanposhiho](https://github.com/sanposhiho)) [SIG Scheduling and Testing]
- QueueingHint 機能で発生する可能性のあるメモリリークを修正しました。([#126962](https://github.com/kubernetes/kubernetes/pull/126962), [@sanposhiho](https://github.com/sanposhiho))
- QueueingHint 機能で発生する可能性のあるメモリリークを修正しました。([#127016](https://github.com/kubernetes/kubernetes/pull/127016), [@sanposhiho](https://github.com/sanposhiho))
- Pod ステータスのパッチが正しくおこなわれず、プリエンプション対象の Pod が削除されないバグを修正しました。このバグは、プリエンプションする Pod とされる Pod が異なる QoS クラスをもつ場合に起こり、プリエンプション全体が失敗していました。([#126644](https://github.com/kubernetes/kubernetes/pull/126644), [@Huang-Wei](https://github.com/Huang-Wei))
    - :pencil: Typo により、プリエンプション対象 (victim) Pod のステータスをプリエンプションを引き起こす Pod のステータスで上書きするようなパッチをしてしまっており、不正なパッチなのでその後の victim の削除ができないというバグでした。大きなバグだったので v1.28 までバックポートされています。
- Pod Disruption Budget 違反が起こる場合の、最適でないプリエンプションの挙動を修正しました。([#128307](https://github.com/kubernetes/kubernetes/pull/128307), [@NoicFank](https://github.com/NoicFank)) [SIG Scheduling]
- QueueingHint が有効な場合にのみ発生する `NodeUnschedulable` のバグを修正しました。このバグにより、`NodeUnschedulable` プラグインによって拒否された Pod の一部の更新をスケジューラーが見落とし、必要以上に長くキューに Pod を残してしまう可能性がありました。([#127427](https://github.com/kubernetes/kubernetes/pull/127427), [@sanposhiho](https://github.com/sanposhiho))
- QueueingHint が有効な場合にのみ発生する `PodTopologySpread` のバグを修正しました。このバグにより、`PodTopologySpread` プラグインによって拒否された Pod の一部の更新をスケジューラーが見落とし、必要以上に長くキューに Pod を残してしまう可能性がありました。([#127447](https://github.com/kubernetes/kubernetes/pull/127447), [@sanposhiho](https://github.com/sanposhiho)) [SIG Scheduling]
- スケジューラはスコアリング処理中に既存のサイドカーコンテナのリソース要求を考慮するようになりました。([#127878](https://github.com/kubernetes/kubernetes/pull/127878), [@AxeZhan](https://github.com/AxeZhan)) [SIG Scheduling and Testing]

### Other (Cleanup or Flake)

- GA となっていたフィーチャゲート `MinDomainsInPodTopologySpread` が削除されました。([#126863](https://github.com/kubernetes/kubernetes/pull/126863), [@carlory](https://github.com/carlory)) [SIG Scheduling]
- `dynamicResources` は `DynamicResources` に改名されました。これにより、`dynamicresources` パッケージの外で `DynamicResources` 構造体を使えるようになりました。([#128399](https://github.com/kubernetes/kubernetes/pull/128399), [@JesseStutler](https://github.com/JesseStutler)) [SIG Node and Scheduling]
    - :pencil: `pkg/scheduler/framework/plugins/dynamicresources/dynamicresources.go` にある、DRA 用のスケジューラプラグインを表す構造体です。[Volcano](https://volcano.sh/en/) で使いたいという需要があったようです。