プロンプトとユースケース
バッチプラットフォームが一度に数千のPodを作成しますが、イメージ、クォータ、トポロジー、または外部リソースの準備が整っていません。Podを即座にKubernetesスケジューラに送信することなく作成し、条件が満たされたときに解放するメカニズムを設計してください。無効なPending状態のPodに対してスケジューラやCluster Autoscalerの無駄な処理が発生するのを防ぐ方法、およびゲートのタイムアウト、コントローラの障害、テナントの分離をどのように処理するかを説明してください。
面接官がテストしていること
- 作成された状態とスケジュール可能な状態の分離。
spec.schedulingGatesの作成、削除、および追加不可という制約の理解。- 冪等な解放、タイムアウト、認可、およびリカバリフローの設計。
- SchedulingGated、Unschedulable、およびランタイム障害の区別。
- メトリクス、イベント、監査ログを用いて、システムがサイレントに停止しないことを証明する能力。
最初に明確にすべき質問
- 各ゲートを追加するのは誰で、その条件を確認するのは誰か?
- 条件はPod単位、バッチ単位、テナント単位のいずれのスコープか、またギャングスケジューリングは必要か?
- 解放レイテンシ、有効期限ポリシー、並行性制限、およびコスト目標は何か?
- コントローラの再起動、APIリトライ、ノードスケーリング、権限の取り消しはどのように動作すべきか?
30秒での回答
名前空間スコープのschedulingGatesを使用してPodを作成し、イメージの事前配置(ウォーミング)、クォータ、および外部リソースの準備状況を監視可能な条件とします。コントローラは自身が所有するゲートのみを削除し、作成後には決して新しいゲートを追加しません。また、解放前にテナントクォータとバッチポリシーを再確認します。メトリクスによってゲート付きPodと真にスケジューリング不可能なPodを区別し、有効期限が切れた場合はバージョニングされた条件と監査記録を伴う明示的な障害または人的レビュー状態に移行します。
詳細なステップバイステップ回答
1. 状態マシンの定義
Created、SchedulingGated、ReadyToSchedule、Unschedulable、Running、およびExpiredを分離します。APIは依然としてPodを読み取ることができますが、スケジューラはゲートリストが空でないPodのスケジューリングを試行しません。
2. ゲート名の選定
各ゲートは、batch.example.com/image-readyのような文字列の条件です。名前空間、バッチ、コントローラのバージョンはラベルやアノテーションに格納し、ゲート名は動的データのコンテナではなく、未充足条件のステートメントとして維持します。
3. 作成時のゲート設定
ゲートは、クライアントまたはアドミッションミューテータ(Admission Mutator)によってPod作成時に初期化できます。作成後、既存のゲートは任意の順序で削除できますが、新しいゲートを追加することはできないため、考えられるすべてのブロック条件を作成時に列挙する必要があります。
4. 解放コントローラの設計
コントローラは、Pod、クォータ、イメージウォーミング、および外部リソースイベントを監視し、条件セットを計算して、リソースバージョン付きのパッチを適用します。重複したイベントは同じ結果に収束する必要があります。コントローラ同士が互いに上書きしないように、各コントローラは自身が担当するゲートのみを削除します。
5. バッチと並行性の処理
バッチレベルのリソースは別のオブジェクトに記録し、Podのゲートはバッチコントローラの判断を待ちます。スケジューラやオートスケーラーに急激な負荷スパイクがかからないよう、テナント、優先度、および並行性を考慮したバッチ単位でゲートを削除します。
6. 有効期限と人的介入の設計
作成時刻、最後の条件進行状況、およびデッドラインを永続化します。有効期限が切れた場合は、サイレントにゲートを削除するのではなく、理由を記録し、イベントを発行して、キャンセル、リトライ、または人的レビューキューのいずれかを選択します。リトライにはバックオフと最大回数の設定が必要です。
7. 実際のキューの監視
Kubernetesはscheduler_pending_pods上でgatedラベルを公開しており、明示的に準備が整っていないPodと、試行された結果スケジューリング不可と判断されたPodを区別できます。これをPodのConditions、イベント、コントローラのキュー長、ゲート滞留時間のパーセンタイル、およびオートスケーラーのアクティビティと組み合わせてボトルネックを特定します。
8. 認可の制限とリカバリ
アドミッションポリシーによってゲートを作成できるユーザーを制限し、コントローラは許可された名前空間とプレフィックスを持つゲートのみを削除できるようにします。再起動後はAPIから状態を再構築し、パッチの競合が発生した場合はリソースバージョンを再読み込みして比較します。コントローラが利用不能な状態が続く場合に備え、オンコール担当者には監査証跡に裏付けられた安全なキャンセルまたは解放手順が必要です。
トレードオフと境界
スケジューリングゲートはPodがスケジューリングに入るかどうかを制御するものであり、ノードアフィニティ、リソース要求、トポロジー制約、ランタイムの準備状況を代替するものではありません。ゲートが多すぎると実際の容量問題がアプリケーション層に隠蔽され、少なすぎると準備ができていないPodがスケジューラに送信されてしまいます。未充足の条件と容量のないクラスタを明確に区別し、ゲートを一般的なクロスオブジェクトのトランザクションロックとして扱わないでください。
ロールアウト計画と検証
- 各ゲートの所有者、条件ソース、有効期限、および削除権限を記録する。
- アドミッション時にゲートプレフィックス、テナントクォータ、および作成時の完全な条件セットを検証する。
- まずは小さなバッチでスケジューラ、オートスケーラー、APIサーバー、およびコントローラのパッチ競合の負荷テストを実施する。
scheduler_pending_pods{queue="gated"}、ゲートの滞留時間、有効期限切れ率、解放スループット、およびテナントごとの並行性を監視する。- コントローラの再起動、ネットワーク分断、権限の取り消し、バッチのキャンセル、重複パッチをテストし、監査ログを検証する。
よくある間違いとフォローアップ
間違い1:作成後にゲートを追加する
APIは作成時のみゲートを許可し、その後は削除のみを許可します。動的な条件は作成前に集約するか、Podを作成する前に別オブジェクトを介して待機する必要があります。
間違い2:SchedulingGatedをスケジューリング失敗と呼ぶ
ゲートが空でないPodは、スケジューラによって試行されていません。ゲート付き(Gated)、Unschedulable、ImagePullBackOff、およびアプリケーションの準備完了を区別してください。
間違い3:ゲートの削除をクォータ制御として使用する
ゲートの削除はスケジューリングの試行を許可するだけであり、リソースを保証するものではありません。解放前にクォータ、優先度、およびバッチの並行性を再確認してください。
間違い4:ゲート滞留時間と有効期限のアラートを省略する
滞留時間のパーセンタイルがなければ、サイレントな停止を検知できません。条件、担当コントローラ、最新の進行状況、および明示的なキャンセルパスを記録してください。
間違い5:オートスケーラーのコストを無視する
準備ができていない大量のPodは、無意味なスケールアップ評価を引き起こす可能性があります。ゲート付きキューのメトリクスと解放のスロットリングを使用して、コストが実際に削減されていることを検証してください。