Kubernetes 1.35 の CHANGELOG から、SIG-Scheduling に関するところを抜粋して紹介します。
は筆者によるコメントです。
過去 3 リリースの変更内容:
- Kubernetes 1.34: SIG-Scheduling の変更内容
- Kubernetes 1.33: SIG-Scheduling の変更内容
- Kubernetes 1.32: SIG-Scheduling の変更内容
所感
Workload API と、それを使った gang scheduling のサポートが入った(アルファ段階)のが大きなトピックです。KEP-4671: Gang Scheduling using Workload Object で議論されている機能で、Pod のグループをまとめて kube-scheduler で gang scheduling (coscheduling) できるようにするものです。
Gang scheduling は分散学習ジョブなどで以前から需要があり、out-of-tree スケジューラプラグインで実装したり、Kueue でも単純化された形でサポートされていました。PFN からもプラグインを OSS で公開しています。KEP からもこのプラグインは参考として挙げられています。
- scheduler-plugins/plugins/gang at master · pfnet/scheduler-plugins
- Setup All-or-nothing with ready Pods | Kueue
このように kube-scheduler の外部でも実現はできていましたが、標準化された API が提供されることで、Job などの組み込みコントローラがワークロードを理解したり、Cluster Autoscaler などの外部コンポーネントが連携しやすくなることが期待できます。
Workload API は以下のような構造になっています。Workload リソースでスケジューリングポリシーなどを定義し、Pod に追加された workloadRef フィールドで、所属先の Workload と Pod グループを参照します。PFN のプラグインでは、Pod のアノテーションにスケジューリングポリシーやグループを指定していたのですが、同等の情報を Workload リソースに定義するようになったイメージです。
apiVersion: scheduling.k8s.io/v1alpha1
kind: Workload
metadata:
namespace: example
name: example-workload
spec:
# この Pod グループのライフサイクル管理を担当するコントローラ。
# スケジューラ自身はこのフィールドは使わない。外部のツールなどが参照する想定。
controllerRef:
apiGroup: batch
kind: Job
name: example-job
# この Workload に属する Pod グループのリスト。
podGroups:
- # Pod グループの名前(Pod から Workload を参照するときに使用)。
name: workers
# スケジューリングポリシー("gang" または "basic")。
policy:
gang:
# このグループは同時に4つの Pod が実行可能な場合にのみスケジュール可能。
minCount: 4
apiVersion: v1
kind: Pod
metadata:
namespace: example
name: worker-0
spec:
workloadRef:
# 属する Workload の名前。
name: example-workload
# Workload のうち属する Pod グループの名前。
podGroup: workers
kube-scheduler に入ったプラグインの実装 を見ても、アノテーションか Workload リソースかという違いはあれど、基本的なロジックは PFN のプラグインと同じように見えます。グループに属する Pod がキューに揃うまで PreEnqueue フェーズで待機させ、Pod ごとのスケジューリング時に Reserve フェーズでリソースを確保し、すべての Pod がノードに割り当てられたら Permit フェーズで一括で次に進めるという流れになっています。どちらもメモリ上で Pod グループの状態を管理しているので、移行は難しくなさそうに見えます。
API Change
- 優先順位付きリスト (prioritized list) 機能にスコアリングを追加し、最上位のサブリクエストを最もよく満たすノードが選択されるようになりました。(#134711, @mortent) [SIG Node, Scheduling and Testing]
-
KEP-4816: DRA: Prioritized Alternatives in Device Requests では、要求するデバイスの種類を優先順位付きリストで表現できます。この変更で、リストの上位のデバイスが利用可能なノードが優先されるようにスコアリングされます。
-
- kube-apiserver、kube-controller-manager、および kube-scheduler に
--min-compatibility-versionフラグを追加しました。(#133980, @siyuanfoundation) [SIG API Machinery, Architecture, Cluster Lifecycle, Etcd, Scheduling and Testing] - DRA デバイス taint:
DeviceTaintRuleステータスが、Pod を退避させる必要があるかどうか(EvictionInProgress条件)を含む、ルールに関する情報を提供するようになりました。新しく追加されたNoneエフェクトを使用することで、NoExecuteエフェクトを使用した場合の動作のプレビューや、スケジューリングや実行中の Pod に即座に影響を与えずにデバイスの taint(デバイスの健全性)を付与することが可能になります。(#134152, @pohly) [SIG API Machinery, Apps, Auth, Node, Release, Scheduling and Testing] - DRA: コア機能の
DynamicResourceAllocationフィーチャーゲート(v1.34 で GA)がデフォルトで有効に固定され、無効化できなくなりました。(#134452, @pohly) [SIG Auth, Node, Scheduling and Testing] - Pod spec で要求されたリソースを記録するために、Pod status に
AllocatedResourcesを追加しました。(#132919, @ndixita) [SIG API Machinery, Apps, Architecture, Auth, CLI, Instrumentation, Node, Scheduling and Testing] - kube-scheduler において、
NominatedNodeNameForExpectationフィーチャーゲートをデフォルトで有効にしました。また、kube-apiserver において、ClearingNominatedNodeNameAfterBindingフィーチャーゲートをデフォルトで有効にしました。(#135103, @ania-borowiec) [SIG API Machinery, Apps, Architecture, Auth, Autoscaling, CLI, Cloud Provider, Cluster Lifecycle, Etcd, Instrumentation, Network, Node, Scheduling, Storage and Testing]-
KEP-5278: Nominated node name for an expected pod placement のフィーチャーゲートです。Pod の配置先を記録・認識することで、kube-scheduler と Cluster Autoscaler など外部コンポーネントが連携できるようになります。
-
-
"core/v1".Tolerationを拡張し、数値比較演算子(Gt、Lt)をサポートしました。(#134665, @helayoty) [SIG API Machinery, Apps, Node, Scheduling, Testing and Windows] -
scheduling.k8s.io/v1alpha1Workload API を使用した all-or-nothing スケジューリングをサポートするために、GangScheduling kube-scheduler プラグインを導入しました。(#134722, @macsko) [SIG API Machinery, Apps, Auth, CLI, Etcd, Scheduling and Testing] - Node Declared Features 機能(アルファ段階)を導入しました。これには以下が含まれます。
-
Node.Status.DeclaredFeaturesフィールドを追加し、ノード固有の機能を公開できるようにしました。 -
component-helpersにライブラリを追加し、機能の登録と推論をサポートしました。 - NodeDeclaredFeatures スケジューラプラグインを追加し、Pod を必要な機能を提供するノードにマッチできるようにしました。
- ノードの宣言済み機能に照らして Pod の更新を検証するための
NodeDeclaredFeatureValidatorアドミッションプラグインを追加しました。(#133389, @pravk03) [SIG API Machinery, Apps, Node, Release, Scheduling and Testing]
-
- ワークロードレベルのスケジューリング要件を表現し、kube-scheduler がそれに基づいて動作できるようにするために、
scheduling.k8s.io/v1alpha1Workload API を導入しました。(#134564, @macsko) [SIG API Machinery, Apps, CLI, Etcd, Scheduling and Testing] - 必要な CSI ドライバが動作していないノードに Pod がスケジュールされるのを防ぐようにしました。(#135012, @gnufied) [SIG API Machinery, Scheduling, Storage and Testing]
- スケジューラ:DynamicResources プラグインの設定に
bindingTimeout引数を追加しました。これにより、device binding condition におけるPreBindでの待機時間をカスタマイズできるようになります。DRADeviceBindingConditionsとDRAResourceClaimDeviceStatusの両方が有効な場合、デフォルトは10分です。(#134905, @fj-naji) [SIG Node and Scheduling] - DRA デバイス taint と toleration 機能に個別のフィーチャーゲート
DRADeviceTaintRulesが用意され、DeviceTaintRulesのサポートを制御するようになりました。これにより、DRADeviceTaintsを有効にしたまま本機能を無効化できるため、ResourceSlicesを介した taint 付与を継続して利用できます。(#135068, @pohly) [SIG API Machinery, Apps, Auth, Node, Scheduling and Testing] - ResourceQuota を更新し、
DRAExtendedResource機能が有効な場合、ResourceClaim 内の DeviceClass 要求が2つの追加クォータにカウントされるようになりました。 - Partitionable Devices 機能を更新し、同一リソースプール内の ResourceSlices をまたいだカウンターセットの参照をサポートしました。不完全なプールからのデバイスは、割り当ての対象外となりました。この変更により、このアルファ機能には後方互換性のないアップデートが含まれるため、v1.34 と v1.35 の間でアップグレードまたはダウングレードをおこなう前に、本機能を使用している ResourceSlices を削除する必要があります。(#134189, @mortent) [SIG API Machinery, Node, Scheduling and Testing]
Feature
-
resourceclaim_controller_resource_claimsメトリクスにsourceラベルを追加しました。また、DRAExtendedResource用にscheduler_resourceclaim_creates_totalメトリクスを追加しました。(#134523, @bitoku) [SIG Apps, Instrumentation, Node and Scheduling] - スケジューラの
statuszエンドポイントに paths セクションを追加しました。(#132606, @Peac36) [SIG API Machinery, Architecture, Instrumentation, Network, Node, Scheduling and Testing] - v1.34 で検出されたリグレッションの修正後、
SchedulerAsyncAPICallsフィーチャーゲートが再びデフォルトで有効になりました。(#135059, @macsko)-
しかし、パフォーマンスの問題が再び発生したため、また無効化されました。1.35 系にもバックポートされています。
-
SchedulerAsyncAPICallsは、kube-scheduler が kube-apiserver に発行する API 呼び出しを非同期化する(完了を待たずに次の処理に進む)ことで、スケジューリングのスループットを向上させることを目的としています。が、これにより API 呼び出しのレートが増加しスロットルされてしまう場合があり、Pod のバインディングなど重要な処理が遅延する問題につながります。対策として、API 呼び出しが実行中の Pod は scheduling cycle に再度投入しないようにするなどの改善が考えられています。
-
- 同一のスケジューリング要件を持つ Pod のスケジューリングを最適化するため、opportunistic batching (KEP-5598) を実装しました。(#135231, @bwsalmon) [SIG Node, Scheduling, Storage and Testing]
-
KEP-5598: Opportunistic batching で提案されている機能です。Pod のスケジューリング時にノードのスコアリング結果をキャッシュし、この Pod と同一のスケジューリング要件 (scheduling signature) をもつ Pod で再利用する(nominated node name をセットする)ことで、大規模なクラスタにおけるスケジューリング処理の効率化を図ります。Gang scheduling と組み合わせることが念頭に置かれていますが、それに限らず有効な設計になっていることがおもしろいです。
-
- DRA-backed 拡張リソースに対するスコアリングを実装しました。(#134058, @bart0sh) [SIG Node, Scheduling and Testing]
-
NodeResources スケジューラプラグインが DRA-backed 拡張リソースにも対応するようになりました。
-
-
InPlacePodVerticalScalingを GA に昇格させました。(#134949, @natasha41575) [SIG API Machinery, Node and Scheduling] - 1つの拡張リソースに対して複数の DeviceClass が利用可能な場合、決定論的に単一の DeviceClass を選択するようにしました。(#135037, @yliaog) [SIG Node, Scheduling and Testing]
- スケジューリングまたはバインディングに失敗した際、スケジューラが Pod の
nominatedNodeNameフィールドをクリアするようになりました。Cluster Autoscaler や Karpenter などの外部コンポーネントは、このフィールドを上書きすべきではありません。(#135007, @ania-borowiec) [SIG Scheduling and Testing]
Bug or Regression
- DRA デバイス taint:
NoExecuteの Toleration を修正しました。以前は、スケジューラが eviction controller に toleration について通知していなかったため、NoExecuteを許容していても、スケジュールされた Pod がほぼ即座に退避させられてしまい、正常に動作していませんでした。(#134479, @pohly) [SIG Apps, Node, Scheduling and Testing] - 非同期プリエンプションとの相互作用により、とくに kube-apiserver の負荷が高い状況で kube-scheduler のパフォーマンスが低下するバグを緩和するため、
SchedulerAsyncAPICallsフィーチャーゲートを無効化しました。(#134400, @macsko) - 自動 ResourceClaim を使用して割り当てられる init containers が要求する拡張リソースが、レガシーなデバイスプラグインの挙動と一致するようになりました。可能な場合は後続のサイドカー init containers や通常のコンテナが要求するリソースと同じものを再利用し、Pod が要求するデバイスの総数を最小限に抑えます。(#134882, @yliaog) [SIG Apps, CLI, Node, Scheduling and Testing]
- 保留されている Pod プリエンプションにより、プリエンプター Pod が頻繁にリトライされてしまう kube-scheduler のバグを修正しました。(#134245, @macsko) [SIG Scheduling and Testing]
- Binding フェーズで削除された Pod が、kube-scheduler 上でノードの領域を占有し続けてしまうバグを修正しました。(#134157, @macsko) [SIG Scheduling and Testing]
- 高レイテンシな kube-apiserver がスケジューリングのスループットを低下させていたバグを修正しました。(#134154, @macsko)
-
Feature に挙がっている #135059 で有効に戻ったものですが、上述の通り再び無効化されています。
-
- 非同期プリエンプションの問題を修正しました。スケジューラは、新しいプリエンプション呼び出しを開始する前に、その Pod に対してプリエンプションが進行中かどうかを確認するようになりました。(#134730, @ania-borowiec) [SIG Scheduling and Testing]
- プリエンプション完了に時間がかかる際の、プリエンプター Pod の不適切な挙動を修正しました。プリエンプター Pod は、プリエンプションが終了するまで scheduling cycle を空回りすべきではありません。(#134294, @ania-borowiec) [SIG Scheduling and Testing]
- 静的な PersistentVolume が作成された際に、スケジューリングが遅延することがある問題を修正しました。(#133929, @huww98) [SIG Scheduling and Storage]
- DeviceClass から派生した暗黙的な拡張リソース名 (
deviceclass.resource.kubernetes.io/<device-class-name>) を使用して、そのクラスに一致する DRA デバイスを要求するためのサポートを導入しました。(#133363, @yliaog) [SIG Node, Scheduling and Testing] - ResourceClaimTemplate から作成された ResourceClaim、およびスケジューラによって作成された
extendedResourceClaimから BlockOwnerDeletion を削除しました。(#134956, @yliaog) [SIG Apps, Node and Scheduling] - kube-scheduler: 許容されない taint によりスケジューリングに失敗した際、Pod のステータスに具体的な taint のキーや値が含まれないようになりました。(#134740, @hoskeri)
-
これまで node(s) had untolerated taint {<key>: <value>}という形式でしたが、node(s) had untolerated taint(s)だけになり、具体的な taint の情報は kube-scheduler のログにのみ出力されます。Taint は機微な情報の場合があるためです。
-
Other (Cleanup or Flake)
-
k/k/pkg/scheduler/framework内の型(Handle,Plugin,PreEnqueuePlugin,QueueSortPlugin,EnqueueExtensions,PreFilterExtensions,PreFilterPlugin,FilterPlugin,PostFilterPlugin,PreScorePlugin,ScorePlugin,ReservePlugin,PreBindPlugin,PostBindPlugin,PermitPlugin,BindPlugin,PodActivator,PodNominator,PluginsRunner,LessFunc,ScoreExtensions,NodeToStatusReader,NodeScoreList,NodeScore,NodePluginScores,PluginScore,NominatingMode,NominatingInfo,WaitingPod,PreFilterResult,PostFilterResult,Extender,NodeInfoLister,StorageInfoLister,SharedLister,ResourceSliceLister,DeviceClassLister,ResourceClaimTracker,SharedDRAManager)をk8s.io/kube-scheduler/frameworkパッケージへ移動しました。ユーザはインポートパスを更新する必要があります。なお、インターフェースに変更はありません。また、k/k/pkg/scheduler/framework/parallelism内のParallelizer型は、インターフェースとしてのParallelizer(k8s.io/kube-scheduler/framework内)と、構造体としてのParallelizer(k/k 内の場所は変更なし)に分割されました。プラグイン開発者は、インポートパスを staging リポジトリのものに更新してください。(#133172, @ania-borowiec) [SIG Node, Release, Scheduling, Storage and Testing]