Kubernetes 1.29 の CHANGELOG から、SIG-Scheduling に関するところを抜粋して紹介します。
は筆者によるコメントです。
過去 3 リリースの変更内容:
- Kubernetes 1.28: SIG-Scheduling の変更内容
- Kubernetes 1.27: SIG-Scheduling の変更内容
- Kubernetes 1.26: SIG-Scheduling の変更内容
所感
前回に引き続き、今回のリリースも Kubernetes スケジューラの内部に関する変更が主となっています。
Queueing hint 機能 に関して、Go のインタフェースにいくつかの変更が入り、プラグインの開発がしやすくなっています。
まず、プラグインで何か想定外のことが起こった場合に備えて QueueingHintFn
がエラーを返せるようになり、エラー時に pod を unschedulable pool に残し続けてしまうバグを埋め込みにくくなりました。
また、プラグインが返す pod のスケジュール状況に Pending
が追加され、QueueingHintFn
が返すヒントの値は Queue
と QueueSkip
のみに絞られました。
クラスタイベントが起こった際に unschedulable pool にある pod をいつ(バックオフの後なのか、すぐなのか)エンキューするかは、これまでプラグイン側で決定していましたが、明確な指標がなくプラグインの開発者によって意見が別れていました。
これを解決するために、ヒントが Queue
と評価されたとき、プラグイン側ではなくスケジューラ本体側で、pod をいつエンキューするかを pod が Pending
だったかどうかをもとに判断されるようになりました。
プラグイン側で判断するより自然であり、かつ明確な判断指標ができたので、プラグインの開発がしやすくなると思われます。
個人的に注目したいのは、feat: Support score extension function in preemption. by lianghao208 · Pull Request #121867 · kubernetes/kubernetes です。
プリエンプション処理は全体の流れが別々のプラグインでも同じになることが多いため、プラグインごとにカスタムしたい評価関数などが "k8s.io/kubernetes/pkg/scheduler/framework/preemption".Interface
インタフェースに切り出されています。
プラグインを自作する場合はこのインタフェースを実装することで簡単にプリエンプション処理が書けるようになっています。
これまで、あるノード上のプリエンプションされる pod を選ぶ処理はカスタム可能でした。
今回、スコアが同じノードが複数あった場合にその中から一つのノードを選ぶ処理もカスタムできるようになりました。
自作プラグインでこの処理をカスタムしていた場合、よりシンプルに実装できるようになる可能性があります。
なお、In-place Update of Pod Resources はもともと Kubernetes 1.29 でのベータへの昇格を目指していましたが、1.30 以降に持ち越しになりました。
Urgent Upgrade Notes(必ず一読してからアップグレードしなければならない事項)
SIG-Scheduling に関するものはありません。
Changes by Kind(種類別の変更)
Deprecation(非推奨)
SIG-Scheduling に関するものはありません。
API Change(API 変更)
-
kube-scheduler
の設定ファイル (KubeSchedulerConfiguration
) について、kubescheduler.config.k8s.io/v1beta3
バージョンが Kubernetes 1.29 で削除されました。kube-scheduler
の設定ファイルはkubescheduler.config.k8s.io/v1
に移行されました。(#119994, @SataQiu) [sig/scheduling, sig/testing]- 移行方法はこちらを参照してください:Scheduler Configuration | Kubernetes
- In-Place Pod Vertical Scaling 機能について Windows サポートが追加されました。(#112599, @fabi200123) [SIG Autoscaling, Node, Scalability, Scheduling and Windows] [sig/scalability, sig/scheduling, sig/node, sig/autoscaling, sig/windows]
- Go API: ボリュームでの使用について、
ResourceRequirements
構造体がVolumeResourceRequirements
に置き換えられました。(#118653, @pohly) [sig/scheduling, sig/storage, sig/node, sig/api-machinery, sig/auth, sig/apps, sig/testing]-
コンテナの計算リソース要求を
ResourceRequirements
で表し、ボリュームのストレージ要求をVolumeResourceRequirements
で表すようになりました。これまで両者ともResourceRequirements
で表していましたが、Dynamic Resource Allocation で使うClaims
フィールドはコンテナにしか関係ないものなので、混同を避けるためClaims
フィールドを持たないVolumeResourceRequirements
を導入しました。
-
コンテナの計算リソース要求を
-
kube-scheduler
のselectorSpread
プラグインが削除されました。代わりにpodTopologySpread
プラグインを使用してください。(#117720, @kerthcet) [sig/scheduling]-
Service, ReplicaSet, または StatefulSet で管理されている pod にデフォルトの topology spread constraint をもたせるプラグインでした。同じことが、
podTopologySpread
プラグインのdefaultConstraints
引数で設定できます。
-
Service, ReplicaSet, または StatefulSet で管理されている pod にデフォルトの topology spread constraint をもたせるプラグインでした。同じことが、
-
matchLabelKeys
/mismatchLabelKeys
がハード・ソフト要件ともにPodAffinity
/PodAntiAffinity
に導入されました。(#116065, @sanposhiho) [sig/scheduling, sig/api-machinery, sig/apps, sig/testing, sig/cloud-provider]- KEP-3633: Introduce MatchLabelKeys and MismatchLabelKeys to PodAffinity and PodAntiAffinity
-
Kubernetes 1.27 で Pod Topology Spread Constraint の
matchLabelKeys
フィールドがベータになりましたが、本 PR は Pod Affinity / AntiAffinity に関する同様の変更です。例えば、ReplicaSet で管理されている pod 群にmatchLabelKeys: [pod-template-hash]
という条件を追加することで、ローリングアップデートの際に同じリビジョンの pod 群だけをアフィニティの計算に入れることができます。
Feature(機能追加)
- スケジューラプラグインが返しうるステータスに新しく
Pending
が導入され、これを利用して効率的なエンキューが実現されます。QueueingHintFn
インタフェースは、Pending
を導入することで簡素化され、返り値はQueue
とQueueSkip
のみを持つように変更されました。スケジューラは、pod がスケジュールできなかった理由によって、Queue
をQueueAfterBackoff
として扱うかQueueImmediately
として扱うかどうかを決定します。(#119517, @sanposhiho) [SIG Node, Scheduling and Testing] [sig/scheduling, sig/node, sig/testing]-
Pod をいつ(バックオフの後なのか、すぐなのか)エンキューするかを、プラグインが実装する
QueueingHintFn
が 直接決定するのではなく、pod がスケジュールできなかった理由(アフィニティを満たせなかったのか、DRA がリソースを用意するまで待たなければならないのか、など)によって決定するということです。
-
Pod をいつ(バックオフの後なのか、すぐなのか)エンキューするかを、プラグインが実装する
- カスタマイズ可能な
OrderedScoreFuncs()
関数が導入されました。プリエンプションのためのインタフェースを使用していた out-of-tree プラグインは、この関数を実装することで、プリエンプション時のノード選択をカスタムできます。また、現在の動作を維持するために nil を返すことができます。(#121867, @lianghao208) [sig/scheduling]- プリエンプション時、最大のスコアをとったノードが複数あった場合に、どのノードにスケジュールするか決定する評価関数をカスタムできます。デフォルトでは、PDB 違反数が最小のノード(複数あればノード内の最小のプライオリティが最高のもの、まだ複数あれば別の指標で評価したノード)を選択します。
- スケジューラに新しいメトリック
pod_scheduling_sli_duration_seconds
が追加され、pod_scheduling_duration_seconds
の非推奨化が開始されました。(#119049, @helayoty) [sig/scheduling, sig/instrumentation, sig/testing]-
前者は pod が
PreEnqueue
プラグインによりリジェクトされていた(エンキューされていなかった)時間を含まず、後者は含みます。
-
前者は pod が
-
QueueingHint
にエラーを示す返り値が追加されました。もしQueueingHint
がエラーを返す場合、スケジューラはそれをログに記録し、イベントをQueueAfterBackoff
として扱って pod が unschedulable pool に取り残されないようにします。(#119290, @carlory) [sig/scheduling, sig/node, sig/testing] -
TaintManager
をNodeLifeCycleController
から切り離しました(KEP-3902)。(#119208, @atosatto) [sig/scheduling, sig/node, sig/api-machinery, sig/apps, sig/instrumentation, sig/testing]- KEP-3902: Decouple Taint-based Pod Eviction from Node Lifecycle Controller
-
NodeLifeCycleController が unhealthy なノードに
node.kubernetes.io/unreachable=:NoExecute
などの taint を付与し、TaintManager がそれに応じてノードから pod を退去させます。
-
ReadWriteOncePod
フィーチャゲートを GA に昇格しました。(#121077, @chrishenzie) [sig/scheduling, sig/storage, sig/node, sig/apps, sig/testing] -
kube-scheduler
のメモリ使用量を改善させるために、kube-scheduler
にとって不要な.metadata.managedFields
フィールドを削除するようにしました。(#119556, @linxiulei) [sig/scheduling]-
Informer の
SetTransform
を使い、メモリ上で informer が格納する pod からフィールドを削除したということです。
-
Informer の
-
Permit
プラグインについて、WaitOnPermit
中に pod がリジェクトされた場合、スケジューラはプラグインを記録します。スケジューラはクラスタイベントが起こった際、この記録にしたがって queueing hint を計算し、pod のスケジュールを再試行するか決定します。(#119785, @sanposhiho) [sig/scheduling, sig/testing] -
nodevolumelimits
スケジューラプラグインを contextual logging を使用するように移行しました。(#116884, @mengjiao-liu) [sig/scheduling, sig/storage, sig/node, sig/instrumentation, sig/testing] -
volumebinding
スケジューラプラグインを contextual logging を使用するように移行しました。(#116803, @mengjiao-liu) [sig/scheduling, sig/storage, sig/instrumentation] -
volume_zone
プラグインは、スケジューリング処理中にbeta
ラベルをGA
ラベルとして扱います。したがって、ラベルの値が同じであれば、beta
ラベルを持つ PV もGA
ラベルを持つノードにスケジュールできます。 (#118923, @AxeZhan) [sig/scheduling]-
Kubernetes 1.17 から
failure-domain.beta.kubernetes.io/{region,zone}
ラベルが非推奨になっておりtopology.kubernetes.io/{region,zone}
に置き換えられていることへの対応です。
-
Kubernetes 1.17 から
- DRA: スケジューラプラグインは、いくつかの場合において追加のスケジューリング試行を避けるために、競合後に SSA にフォールバックすることで対処します。(#120534, @pohly) [sig/scheduling, sig/node, sig/testing]
- PodSchedulingContext の更新操作が楽観的並行性制御のコンフリクトで失敗したときに SSA を試します。SSA は JSON のエンコーディングなどにより高コストとのことなので、失敗したときのみフォールバックします。
-
NodeUnschedulable
プラグインにスケジューリングヒントを実装しました。スケジューリングヒントにより、新しいノードが作成されたときと、ノードの.spec.unschedulable
が false に設定されたときにのみ、NodeSchedulable
プラグインによって以前にリジェクトされた pod のスケジューリングを再試行します。(#119396, @wackxu) [sig/scheduling] -
NodeAffinity
プラグインにスケジューリングヒントを実装しました。スケジューリングヒントにより、新しいノードが作成されたときと、ノードの更新が pod のノードアフィニティに一致する場合にのみ、NodeAffinity
プラグインによって以前にリジェクトされた pod のスケジューリングを再試行します。(#119155, @carlory) [sig/scheduling]
Documentation(ドキュメント改善)
SIG-Scheduling に関するものはありません。
Failing Test(失敗しているテスト)
- DRA (Dynamic Resource Allocation):スケジューラが pod に対してノードが不適合になった後にリソース要求を解放する必要があったとき、実際に必要なより多くのリソース割当てと解放が必要になることがありました。このバグは最初に割当てを無効にすることで修正されました。(#120428, @pohly) [sig/scheduling, sig/node]
Bug or Regression(バグ修正)
- 一時的な障害(例:
kube-apiserver
の一時的な障害)によって unschedulable になった pod について、より正確に再エンキューされるようになりました。(#119105, @sanposhiho) [sig/scheduling, sig/testing]- プラグイン起因でない理由で unschedulable になった pod が、unschedulable pool でイベントを待ち続けてしまうのではなく、backoff キューに戻されるようになりました。
- Kubernetes 1.27 でのリグレッションが修正されました。前の
PreFilter
プラグインがSkip
を返した場合、PostFilter
プラグインが機能しない可能性がありました。 (#119769, @Huang-Wei) [sig/scheduling, sig/testing] - Kubernetes 1.26 のリグレッションが修正されました。
PreFilter
プラグインがUnschedulableAndUnresolvable
を返した場合は、プリエンプション処理がスキップされるようになりました。(#119778, @sanposhiho) [sig/scheduling, sig/testing] - Kubernetes 1.28 でのリグレッションが修正されました。Pod にイベントが並列に起こった場合、pod が誤って unschedulable キューに移動され、イベントが起こらない場合、次の定期的なフラッシュまで 5 分間スケジュールされないことがありました。(#120413, @pohly) [sig/scheduling]
-
PodDisruptionConditions
フィーチャゲートが有効であるデフォルトの設定におけるリグレッションが修正されました。コントロールプレーンによる pod のガベージコレクタが、重複したキーをもつフィールド(環境変数やコンテナのポート)をもつ pod を削除できなくなっていました。(#121103, @mimowo) [sig/scheduling, sig/node, sig/auth, sig/apps, sig/testing]-
このフィーチャゲートは pod に
DisruptionTarget
コンディションを付与しますが、このような pod に対して SSA での更新操作が失敗し、削除もできなくなっていました。SSA の代わりに PATCH を使うようにして回避しました。
-
このフィーチャゲートは pod に
- Kubernetes 1.27 からスケジューラフレームワークにあったリグレッションが修正されました。
skippedScorePlugins
の数がenabledScorePlugins
よりも大きくなる可能性があり、スライスの初期時にcap(len(skippedScorePlugins) - len(enabledScorePlugins))
が負になってしまう問題がありました。(#121632, @kerthcet) [sig/scheduling] - 時折、スケジューラが pod を backoff キューではなく unschedulable pool に誤って配置してしまう状況が修正されました。これは、以前に何らかのプラグインが pod を unschedulable と判定し、後の試行で他のエラーが起こった場合に発生していました。その pod のスケジュールは、最大 5 分後の定期的なフラッシュにより active キューに戻さるまで遅れることになっていました。(#120334, @pohly) [sig/scheduling]
-
ImageLocality
プラグインでのスコアリングに影響する、あるコンテナイメージをもつノードの数の計算における不整合が修正されました。(#116938, @olderTaoist) [sig/scheduling] - Kubernetes 1.29 プレリリースにあった、contextual logging を有効にすると pod のスケジューリングが遅くなる問題が修正されました。(#121715, @pohly) [SIG Instrumentation and Scheduling] [sig/scheduling, sig/instrumentation]
- Taint manager が報告するイベントから
apiVersion
フィールドが抜けていた問題が修正されました。(#114095, @aimuz) [sig/scheduling, sig/node, sig/apps]
Other (Cleanup or Flake)(その他)
- スケジューラの残りの部分を contextual logging を使用するように移行しました。(#120933, @mengjiao-liu) [SIG Instrumentation, Scheduling and Testing] [sig/scheduling, sig/instrumentation, sig/testing]
-
NodeUnschedulable
プラグインのFilter
拡張点を最適化して不要な計算を回避しました。 (#119399, @wackxu) [sig/scheduling] - デバッグを容易にしつつ透明性を安全に確保するため、プリエンプションのイベントメッセージに、プリエンプションした pod の UID を追加しました。(#119971, @kwakubiney) [SIG Scheduling] [sig/scheduling]
- Kubernetes 1.27 で、他のネームスペースの存在や、その中の pod 名が漏洩することを防ぐために、これらの情報がイベントメッセージから除かれていました。
-
LegacyServiceAccountTokenNoAutoGeneration
フィーチャゲートが削除されました。(この機能は GA されており、常に有効です)。(#120192, @SataQiu) [SIG Apps, Auth and Scheduling] [sig/scheduling, sig/auth, sig/apps]- ServiceAccount の有効期限のないトークンを Secret として自動作成することをやめるフィーチャゲートです。
-
ComponentSLIs
フィーチャゲートによって制御され、/metrics/slis
で提供される メトリクスが GA に昇格し、無条件に有効化されるようになりました。このフィーチャゲートはv1.31
で削除されます。(#120574, @logicalhan) [sig/network, sig/scheduling, sig/node, sig/api-machinery, sig/instrumentation, sig/architecture, sig/cloud-provider] -
PreEnqueue
,PreFilter
,Filter
,Reserve
,Permit
以外のプラグインが実装するEnqueueExtensions
は無視されるようになりました。これにより、スケジューラがサブスクライブ、処理する必要があるクラスタイベントの種類が減少します。(#121571, @sanposhiho) [sig/scheduling]- これらのプラグイン以外は、プラグイン起因で pod を unschedulable と判定しないためです。
-
GetPodQOS(pod *core.Pod)
関数は、セットされている場合はPodStatus.QOSClass
の格納値を返すようになりました。QOSClass
の値をゼロから計算するには、ComputePodQOS(pod*core.Pod)
を使用する必要があります。(#119665, @vinaykul) [sig/scheduling, sig/node, sig/api-machinery, sig/apps, sig/cli, sig/testing]- QoS クラスとは Guaranteed / Burstable / BestEffort のことです。
-
ResourceClass
が存在しないために unschedulable となった pod の処理が少し効率的になり、周期的なリトライに依存しなくなりました。(#120213, @pohly) [sig/scheduling, sig/node, sig/testing]- ResourceClass の作成・更新イベントを契機に pod のスケジュールをリトライするようになりました。