概要

スケジューリングが失敗した後に同じ名前・namespaceでPodを作り直すと、スケジューラーの内部キューに古いUID(識別子)が残り続けるバグが修正されました。放置すると inFlightEvents という追跡データが際限なく増加し、メモリリークやスケジューラーの性能劣化につながる可能性がありました。

  • PR: #138324
  • 作者: Samarth Verma (@MaybeSam05)
  • 変更ファイル: pkg/scheduler/schedule_one.gopkg/scheduler/schedule_one_test.go
  • 変更規模: +77行 / -0行(テストコードを含む)

背景・前提知識

スケジューラーとは? Kubernetes のスケジューラーは、新しく作成されたPodをどのNodeに配置するか決定するコンポーネントです。Pod→スケジューラーキュー→スケジューリング処理→Node割り当て、という流れで動作します。

UID(Unique Identifier)とは? Kubernetes の各リソース(Pod・Service等)には作成時に一意のUIDが付与されます。同じ名前のPodを削除して再作成すると、名前・namespaceは同じでもUIDは新しく別の値になります。

inFlightPods・inFlightEvents とは? スケジューラーが「現在処理中のPod」を追跡するための内部データ構造です。スケジューリングサイクルの開始時にPodのUIDを inFlightPods マップに登録し、完了時に削除(Done)します。inFlightEvents はその処理中に発生したクラスターイベントを追跡するもので、スケジューリングヒントの最適化に使われます。


詳細:バグの原因と修正

バグの発生シナリオ

  1. Pod my-pod(UID: aaa-111)がスケジューリングキューからポップされる
  2. スケジューリングが失敗(例: リソース不足)
  3. handleSchedulingFailure がInformer(クラスター状態のキャッシュ)から最新のPod情報を再取得
  4. このタイミングで my-pod が削除されて同じ名前・namespaceで再作成されていた
  5. Informer が返すのは新しいPod(UID: bbb-222
  6. AddUnschedulableIfNotPresent が新しいUIDで Done を呼ぶ
  7. 古いUID aaa-111inFlightPods に残り続ける → リーク

修正内容

// 修正前: handleSchedulingFailure がInformerから再取得した後のUIDでDoneを呼ぶ
func (sched *Scheduler) handleSchedulingFailure(ctx context.Context, fwk ..., podInfo *framework.QueuedPodInfo, ...) {
    pod := podInfo.Pod
    // ... informerから再取得してpodInfoを更新 ...
    sched.SchedulingQueue.AddUnschedulableIfNotPresent(podInfo, ...)
}
 
// 修正後: スケジューリングサイクル開始時のUID(元のUID)を保持してDoneに渡す
func (sched *Scheduler) handleSchedulingFailure(ctx context.Context, fwk ..., podInfo *framework.QueuedPodInfo, ...) {
    schedulingCycleInFlightUID := podInfo.Pod.UID  // ← 元のUIDを保存
    pod := podInfo.Pod
    // ... informerから再取得してpodInfoを更新 ...
    sched.SchedulingQueue.AddUnschedulableIfNotPresent(podInfo, schedulingCycleInFlightUID)
    //                                                          ↑ 元のUIDでDoneを呼ぶ
}

AddUnschedulableIfNotPresent のシグネチャに schedulingCycleInFlightUID string パラメータが追加されました。空文字列("")を渡すと従来の動作(pInfo.Pod.UID を使用)になり、後方互換性を保っています。


影響

影響を受ける操作パターン:

  • スケジューリングが失敗するPodを削除して同じ名前・namespaceで再作成する場合
  • 具体的には、リソース不足のためにPendingになったPodを強制的に削除・再作成するようなケース

症状:

  • inFlightEvents の追跡データが際限なく増加
  • 関連するメトリクスの値が増加し続ける
  • 長時間稼働するクラスターでスケジューラーのメモリ使用量が増加

修正後:

  • 古いUIDが正しくクリアされ、メモリリークが発生しなくなります

参考リンク