概要

LWKD(Week Ending December 7, 2025)で取り上げられたとおり、kube-apiserver 内の Service ClusterIP 割り当てに使われる IP アロケータ(ipallocator)が「すべてのエラーを自動で再試行する」挙動をやめ、再試行条件を限定する修正が入りました。 この変更は PR #135499 として 2025-12-04 にマージされています。

変更内容(何が変わったか)

  • これまで:割り当て処理で発生したエラー種別に関係なく「次の候補 IP を試す」ループを続け、結果として利用可能な IP 数に比例した内部 API 呼び出しを発生させうる実装でした(PR 本文で問題として説明されています)。
  • これから:MetaAllocator.AllocateNextService は、ErrFull(枯渇)または ErrNotReady(未準備)の場合にのみ「次を試す」挙動を継続し、それ以外のエラーはその時点で返して停止します(diff で errors.Is(err, ErrFull) / errors.Is(err, ErrNotReady) 以外は即 return)。
  • 併せて、無効な Service 生成がタイムアウトではなく Invalid として返ることを確認する統合テストが追加されています(apierrors.IsInvalid(err) を期待)。

背景(なぜこの変更が必要か)

根本は「再試行すべきでないエラーまで再試行していた」点です。具体例として、metadata.name が空の Service を作ろうとすると、Service の ClusterIP 割り当て過程で IPAddress オブジェクト作成が不正な参照(ParentReference)になって失敗し続けるケースが報告されています(Issue #135333)。 この失敗を「再試行可能」と誤判定すると、割り当て可能な IP を尽くすまで内部で API 呼び出しが連打され、kube-apiserver(および etcd)に高負荷・タイムアウト(例:504)を誘発しうる、というのが問題意識です(Issue と PR 本文に記載)。

また、この経路は MultiCIDRServiceAllocator(GA / 1.33 以降デフォルト有効)と関連し、旧来の bitmap ベースの ClusterIP アロケータから IPAddress を使う新アロケータへの移行・デュアルライトが説明されています(Feature Gates ドキュメント)。加えて、Service の IP レンジ拡張(ServiceCIDR 追加)手順でも MultiCIDRServiceAllocatornetworking.k8s.io/v1ServiceCIDR / IPAddress を前提に説明されています。

影響(運用者/利用者/開発者への影響、注意点、移行)

  • 運用者: 不正な入力(例:名前なし Service)に起因する kube-apiserver の過剰な内部リトライが抑制され、高 CPU・タイムアウトのリスク低減が期待できます。
  • 利用者: 不正な Service 作成が長時間ぶら下がってタイムアウトするのではなく、より早く失敗(Invalid)として返る方向になります(統合テストで担保)。
  • 開発者: 「どんなエラーでも内部で総当り再試行される」前提にはできなくなり、(必要なら)呼び出し側で適切にリトライ戦略を設計することになります。なお、ErrFull / ErrNotReady は引き続き再試行対象です。

用語メモ(用語の軽い説明)

  • IPallocator / ClusterIP アロケータ: Service の ClusterIP(クラスタ内部向け仮想 IP)を割り当てる kube-apiserver 内部コンポーネント。
  • MultiCIDRServiceAllocator: Service の IP レンジ拡張(複数 CIDR)と、新しい ClusterIP アロケータ(IPAddress ベース)への移行に関係する feature gate(1.33 以降 GA・デフォルト有効)。
  • ServiceCIDR: Service 用の IP アドレス範囲を表す networking.k8s.io/v1 リソース(ドキュメントでは kube-apiserver がデフォルトの ServiceCIDR を作る挙動も説明)。
  • IPAddress: 割り当て済み IP を表す networking.k8s.io/v1 リソース(例として services/default/kubernetes を参照する ParentRef が載っています)。
  • ErrFull / ErrNotReady: アロケータが枯渇している/準備できていないことを表すエラー(今回「再試行を続ける」対象として明示)。

参考リンク