概要
スケジューリングが失敗した後に同じ名前・namespaceでPodを作り直すと、スケジューラーの内部キューに古いUID(識別子)が残り続けるバグが修正されました。放置すると inFlightEvents という追跡データが際限なく増加し、メモリリークやスケジューラーの性能劣化につながる可能性がありました。
- PR: #138324
- 作者: Samarth Verma (@MaybeSam05)
- 変更ファイル:
pkg/scheduler/schedule_one.go、pkg/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 はその処理中に発生したクラスターイベントを追跡するもので、スケジューリングヒントの最適化に使われます。
詳細:バグの原因と修正
バグの発生シナリオ
- Pod
my-pod(UID:aaa-111)がスケジューリングキューからポップされる - スケジューリングが失敗(例: リソース不足)
handleSchedulingFailureがInformer(クラスター状態のキャッシュ)から最新のPod情報を再取得- このタイミングで
my-podが削除されて同じ名前・namespaceで再作成されていた - Informer が返すのは新しいPod(UID:
bbb-222) AddUnschedulableIfNotPresentが新しいUIDでDoneを呼ぶ- 古いUID
aaa-111はinFlightPodsに残り続ける → リーク
修正内容
// 修正前: 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が正しくクリアされ、メモリリークが発生しなくなります