プロンプトとコンテキスト
Kubernetes GPUプラットフォームを運用しています。学習ジョブやバッチ推論ジョブは、Podが作成される前に、クォータ、ノードリソース、メンテナンスウィンドウ、セキュリティポリシーを待つ必要があります。KueueのWorkload、ClusterQueue、ResourceFlavor、AdmissionCheckを使用してアドミッションを設計し、リソース枯渇(Starvation)や安全でないリリースを防止してください。
面接官がテストしていること
キューイングとアドミッションの分離:Workloadがキューに入ったからといって、Podを作成してよいわけではありません。ClusterQueueはリソースグループとノミナルクォータからフレーバーを選択し、AdmissionCheckは内部または外部のコントローラーがリリースに影響を与えることを可能にします。状態の一貫性、取り消し(Revocation)、部分アドミッション、テナントの公平性、バックオフ、監査可能性をカバーしてください。
最初に確認すべき明確化のための質問
リソースと優先度
GPUモデル、メモリ、CPU、トポロジー、プリエンプション、テナントの優先度、キューの公平性、最大待機時間を明確にします。GPUの数だけをカウントすると、メモリやトポロジーが合致しない場合に偽のキャパシティを生み出す可能性があります。
外部アドミッション依存関係
メンテナンスウィンドウ、イメージスキャン、予算承認、データアクセスのためのコントローラーを特定します。結果が再試行可能(replayable)であるか、タイムアウトが拒否を意味するのか待機を意味するのかを決定します。すべての外部チェックには所有者とTTLが必要です。
障害と取り消し(Revocation)ポリシー
ノードの変更、クォータの回収、アドミッション後のポリシー取り消しが発生した場合の挙動を定義します。重複リリースを防ぐために、アドミッション記録、Pod作成、外部チェックには冪等な相関関係が必要です。
30秒の回答フレームワーク
「WorkloadはLocalQueueに入り、そのClusterQueueがリソースグループ、フレーバー、コホートクォータを評価します。アドミッションの前に必要なすべてのAdmissionCheckStateがReadyである必要があります。Pendingはキューに残され、Rejectedまたはタイムアウトは制限付きリトライまたは終了ポリシーに従います。追跡可能なワークロード状態を永続化し、Podを作成する前にリソースとポリシーを再確認し、クォータ使用量、待機時間、チェック遅延、拒否、取り消しを測定して安全性と公平性を検証します。」
ステップバイステップの詳細な回答
ステップ 1: Workloadとキューの境界を定義する
ユーザーのJobを、PodSet、リソース要求、優先度、テナントキューを持つスケジューリング可能なWorkloadに変換します。LocalQueueは順序付けと待機を行い、Podを作成したりClusterQueueのリソース制約をバイパスしたりしてはなりません。
ステップ 2: ClusterQueueを通じてResourceFlavorを選択する
ResourceGroupを使用してCPU、メモリ、GPUリソースを記述し、利用可能なノミナルクォータを持つフレーバーの組み合わせを選択します。GPUモデル、リージョン、ノードラベル、トポロジーをフレーバー制約に含め、「GPUが十分にある」ことが誤ったアドミッションにならないようにします。
ステップ 3: AdmissionCheckステートマシンをオーケストレーションする
観測可能なPending、Ready、Rejected、および終端状態を公開します。セキュリティ、メンテナンス、予算コントローラーは、WorkloadのUIDを使用して冪等に状態を更新します。Kueueは必要なすべてのチェックがReadyの場合にのみアドミットします。Pendingを誤って失敗とラベル付けしてはならず、Rejectedを黙って無視することもできません。
ステップ 4: 部分アドミッションとリソース変更を処理する
部分アドミッションが許可されている場合は、削減可能なPodSetの並列性、最小サイズ、その後の拡張ルールを定義します。クォータ解放またはノード障害の後にフレーバーとチェックを再評価し、期限切れのアドミッションスナップショットを決して再利用しないでください。恒久的に不可能なリクエストには、無限リトライではなく理由を明示した拒否が必要です。
ステップ 5: 公平性を維持し、枯渇(Starvation)を防止する
テナント、キュー、優先度全体でのコホートの共有および借用(borrowing)の境界を定義します。優先度の高いジョブが希少なGPUを無期限に占有するのを防ぎ、優先度の低いジョブに対して待機またはエージング(aging)ルールを追加します。クォータ割り当て、チェック待機、実際のPod起動を個別に観測し、アドミッションは早いが起動が遅い状態を可視化できるようにします。
ステップ 6: 取り消し、リトライ、監査を設計する
コントローラーのタイムアウトまたは障害に対しては、ジッター付きバックオフとリトライ制限を使用します。取り消し(Revocation)は、単一のフィールドを切り替えるだけでなく、WorkloadとPodSetに安全に伝播する必要があります。決定が再現可能になるように、実行者、時間、理由、フレーバー、クォータバージョン、外部チェックバージョンを記録します。
ステップ 7: 可観測性と障害訓練を検証する
キュー待機時間、アドミッション遅延、各チェックのPending期間、拒否、取り消し、クォータ使用率、フレーバー選択、アイドルGPU、Pod起動を監視します。コントローラーの停止、重複コールバック、クォータ回収、ノード障害、ネットワーク分断の訓練を実施し、システムが安全でないリリースを行わず、永久にスタックしないことを証明します。
高品質な回答サンプル
私ならWorkloadをLocalQueueに配置し、ClusterQueueにフレーバーとコホートクォータから実行可能なリソースの組み合わせを選択させ、セキュリティ、メンテナンス、予算の条件にAdmissionCheckを使用します。必要なすべてのチェックがReadyであり、リソーススナップショットが依然として有効な場合にのみアドミットします。Pendingはキューに残され、Rejectedまたはタイムアウトは制限付きバックオフを使用します。GPUモデル、トポロジー、リージョンはフレーバーに属します。テナントクォータとエージングが公平性を保護し、冪等なコールバックと取り消しがWorkloadとPodSetに安全に伝播します。
よくある間違い
- 間違い: キューへの進入をPod作成の許可として扱う。 → なぜ失敗するか: キューイングとアドミッションは別個の状態です。 → 修正方法: ClusterQueueの割り当てとすべてのチェックがReadyであることを必須にします。
- 間違い: GPU数のみでリソースを選択する。 → なぜ失敗するか: モデル、メモリ、トポロジー、リージョンが合致しない可能性があります。 → 修正方法: ResourceFlavorを使用してハードウェア制約を表現します。
- 間違い: Pending状態のチェックを無限にリトライする。 → なぜ失敗するか: 恒久的な実現不可能性やコントローラーの障害が隠されたままになります。 → 修正方法: 制限とバックオフを用いてPending、Rejected、およびその理由を区別します。
- 間違い: Workloadフィールドのみを取り消す。 → なぜ失敗するか: 既存のPodがリソースを消費し続ける可能性があります。 → 修正方法: PodSetのアクション、監査、およびロールバック動作を定義します。
フォローアップの質問と回答
フォローアップ 1: AdmissionCheckはKubernetesのAdmission Webhookとどのように異なりますか?
AdmissionCheckは、Workloadが開始可能かどうかに関するKueueのビジネス状態です。WebhookはAPIリクエストパスを拡張します。これらは連携できますが、Webhookの通過はリソースが割り当てられたことを意味しません。
フォローアップ 2: なぜResourceFlavorが必要なのですか?
同じGPU数であっても、異なるモデル、リージョン、またはトポロジーを表す場合があります。フレーバーはそれらのスケジューリング可能な属性をリソースグループのクォータにバインドし、選択の説明可能性と安全性を確保します。
フォローアップ 3: 重複したコールバックによって状態が後退するのをどのように防ぎますか?
WorkloadのUID、チェック名、バージョンを冪等性キーとして使用します。古いバージョンを拒否し、繰り返されるReady更新によって2回目のPod作成がトリガーされないようにします。
フォローアップ 4: リクエストをPendingのままにするのではなく、いつ拒否すべきですか?
リソースフレーバー、ポリシー、または予算が決して満たされない場合に拒否し、その理由を提供します。一時的なノード不足、メンテナンスウィンドウ、コントローラーのリトライはPendingのままで構いませんが、最大待機時間とアラートが必要です。