課題とスコープ
マルチテナントの機械学習プラットフォームでは、GPU、FPGA、高速NICを使用しています。現在の設計では、ノードラベル、拡張リソース、device pluginsを通じてデバイス全体を割り当てているため、デバイス属性、共有、テナント分離の表現が困難です。チームは、Kubernetes 1.34でコアのresource.k8s.io/v1 APIが安定版となったDynamic Resource Allocation(DRA)を採用したいと考えています。
移行を設計し、ResourceClaim、DeviceClass、ResourceClaimTemplate、ResourceSlice、ドライバ、およびスケジューラの責務を説明してください。クラスタは、すべてのワークロードを一度に再起動することなく、段階的に移行する必要があります。
面接官が評価するポイント
面接官は、デバイス要件の宣言と具体的なデバイスの割り当てが分離されているかを確認したいと考えています。コントロールプレーンAPI、スケジューラ、ノードドライバ、kubelet間のデータフローを説明し、安定版のDRA APIと、実験的またはドライバ固有の機能との違いを区別してください。
優れた回答では、単にリソースの種類を列挙するだけでなく、容量共有、クロスネームスペース参照、ドライバ障害、Podの置き換え、既存ワークロードとの共存、最小権限、ロールバックのシグナルについて網羅します。
回答前の明確化のための質問
- 要求はデバイス全体、スライス可能な容量、または属性に一致する任意のデバイスのどれですか?
- ドライバはDRAをサポートしていますか?また、移行中に従来のdevice pluginを実行できますか?
- ワークロードがClaimを直接作成すべきですか、それともプラットフォームテンプレートが作成すべきですか?
- テナントはネームスペースを越えてClaimを再利用できますか?また、プラットフォームコントローラが書き込み可能なオブジェクトは何ですか?
- 移行中、優先事項はジョブの継続性、スケジューリングスループット、または使用率のどれですか?
30秒の回答フレームワーク
「デバイスの要件をClaimとしてモデル化し、ドライバにデバイスの検出、割り当て、設定を行わせ、スケジューラにはClaimとResourceSliceに基づいて実現可能性の判断を行わせます。分離されたネームスペースで小規模なデバイスクラスをカナリア展開します。従来のプラグインとDRAはプール単位で共存できますが、同じデバイスを所有してはなりません。各フェーズで、Claimの状態、Podのバインディング、ノードの可視性、ドライバエラー、割り当てレイテンシ、テナント境界を測定します。割り当てが失敗した場合は、新規Claimを停止し、実行中のジョブを保持し、新しいワークロードを従来のパスに戻します。」
ステップごとの詳細な回答
まずDRAのデータフローを描く
ワークロードは、PodのresourceClaimsフィールドを通じてClaimを参照します。Claimは直接作成することも、ResourceClaimTemplateによってJob用に生成することもできます。DeviceClassは選択可能なデバイスクラスを記述し、ドライバはResourceSliceを通じてノードのデバイスと属性を公開します。スケジューラはPod、Claim、DeviceClass、ResourceSliceを組み合わせてノードを選択し、ノードドライバが具体的な割り当てと設定を実行します。
これにより、デバイスの選択がアプリケーションYAMLから分離され、ハードウェアトポロジがラベル規約にエンコードされるのを防ぎます。
Claimテンプレートとテナント境界を設計する
メモリ層、インターコネクトタイプ、ネットワーク帯域幅など、テナント向けパラメータのみを公開します。ドライバ内部の識別子は公開しないでください。プラットフォームコントローラは、ネームスペースのアドミッションポリシー、クォータ、ライフサイクルのクリーンアップを適用します。クロスネームスペースでのClaimの使用には、明示的な参照権限と監査イベントが必要です。テナント削除中は、新規Claimを停止し、Podがデバイスを解放するのを待ってから、デバイスの状態を回収します。
全体デバイスと共有可能な容量を処理する
全体デバイスの割り当てでは、1つのDeviceRequestを1つのデバイスにマッピングできます。メモリ、帯域幅、タイムスライスの共有には、ドライバが容量を公開し、関連するDRAの消費可能容量の動作をサポートする必要があります。スケジューララベルで共有をシミュレートしないでください。ノードが実際の容量を超過販売している場合でも、スケジューリングが成功してしまう可能性があります。単位、同時実行制限、解放タイミング、断片化ポリシーを定義します。
device pluginsとの共存
従来のプラグインとDRAが同じハードウェアの所有権を競合してアドバタイズしないよう、移行をデバイスクラスまたはノードプールごとに分割します。既存のワークロードは拡張リソースを維持し、新しいワークロードはDRA Claimを参照します。プールラベルは移行の境界であり、デバイス属性の最終的なソースではありません。各プールには、重複したドライバの初期化を防ぐため、明示的な所有権と無効化スイッチが必要です。
スケジューリング、プリエンプション、障害の処理
Claimが待機または失敗した場合、Podは説明可能なPending理由を提示する必要があります。ノードを選択したからといって、デバイスが設定されたわけではありません。ノードのセットアップ中にドライバが失敗する可能性があります。コントローラは、障害を再試行可能、再試行不可、またはクリーンアップが必要に分類し、各クラスを適切なアラートに送信する必要があります。プリエンプションでは、CPUやメモリだけでなく、Podの優先度、占有されているClaimの容量、解放レイテンシを考慮する必要があります。
容量の可観測性と計画
Claimの作成からバインディング、バインディングからノード割り当て、割り当てからPod Readyまでを別々のステージとして測定します。アイドル、割り当て済み、利用不可、断片化した容量、およびドライバエラーを追跡します。ResourceSliceによってアドバタイズされた容量と、ノードが実際に公開している容量を調整(リコンサイル)します。乖離が生じた場合はカナリア拡張を停止します。トレーニングプラットフォームでは、再試行、チェックポイント復旧、デバイスヘルスイベントも記録する必要があります。
カナリア、ロールバック、および整合性
再試行可能なジョブを使用して、1つのドライバと1つのノードプールから開始します。次に複数のテナントとテンプレートに拡張し、長時間実行される中断不可能なジョブは最後に移行します。ロールバックは、バインドされたClaimを削除することを意味しません。新規Claimの作成を停止し、実行中のPodを終了または移行させ、ドライバの変更を凍結し、新しいジョブを従来のプラグインにルーティングします。インシデントの診断が可能な状態を保つため、Claim、Pod、ドライバのイベントを保持します。
APIとセキュリティ境界の検証
デプロイ前に、Claim、Template、DeviceClass、ResourceSliceのバージョン、状態遷移、削除順序について、resource.k8s.io/v1 APIに対するコントラクトテストを実行します。ドライバの再起動、ノードの喪失、重複割り当て、リークしたClaim、クロスネームスペースアクセスを注入してテストします。アドミッション、RBAC、監査、ノードエージェントの権限を確認します。機能、分離、および復旧のメトリクスが合格した後にのみ、デバイスプールを拡張します。
質の高い模範解答
「移行をリソースモデル、ドライバ、スケジューリング、ランタイム層に分割します。ワークロードはClaimを宣言し、Templateがそれらを生成し、DeviceClassが選択を表現し、ドライバがResourceSliceを公開してノード上で割り当てを行い、スケジューラが実現可能性とノードの選択を処理します。従来のプラグインとDRAはプールまたはデバイスクラス単位で共存し、二重に所有権を持つことはありません。共有については、ラベルベースの超過販売ではなく、ドライバの容量モデルと解放セマンティクスを要求します。再試行可能なジョブから開始し、ClaimからReadyまでのレイテンシ、割り当て失敗、断片化、ドライバのヘルス状態、テナント違反を測定し、ロールバック時には新規Claimを停止して状態を保持した上で新しいジョブを旧環境にルーティングします。」
よくある間違い
- DRAを新しいデバイスラベルとして扱う → ノードレベルでの履行がないままスケジューリングが成功してしまう → ドライバに構造化されたデバイスと容量を公開させる。
- プラグインとDRAに同一デバイスを所有させる → 重複初期化または二重割り当てが発生する → プールまたはデバイスクラス単位で所有権を分割する。
- 回収処理を考慮せずにClaimを設計する → デバイスやクォータのリークが蓄積する → 解放、タイムアウト、削除、調整(リコンシリエーション)を定義する。
- ラベルで共有をシミュレートする → スケジューラが実際の残容量を把握できない → ドライバに容量と同時実行数を公開させる。
- ノード選択を割り当て成功と同等とみなす → ドライバエラーによりPodが無期限にPendingのままになる → スケジューリング、ノード割り当て、Readyのメトリクスを分離する。
- ロールバック時にすべてのClaimを削除する → 実行中のジョブや調査用の証拠が失われる → 新規割り当てを凍結し、状態を保持する。
フォローアップの質問と回答
フォローアップ1:なぜGPUを拡張リソースとして登録し続けないのですか?
拡張リソースは単純な数量要求には適していますが、デバイス属性、代替候補、共有容量、または複雑な構成を適切に表現できません。要件がデバイス全体のカウントのみであり、ドライバが成熟している場合は、従来のパスを維持できます。デバイスの選択とライフサイクルの複雑さが見合う場合にDRAを導入すべきです。
フォローアップ2:複数のPodが1つのClaimを参照する場合、どのように超過販売を防ぎますか?
再利用セマンティクスはYAMLから推測するのではなく、ドライバとプラットフォームポリシーで明示する必要があります。共有容量について、ドライバは割り当て済み容量、同時実行制限、解放状態を記録し、アドミッションによってテナントポリシーに違反する参照を制限します。
フォローアップ3:ノードのセットアップ中のドライバ障害をスケジューラは再試行すべきですか?
まず、一時的なノード障害、デバイスヘルスの障害、および無効なClaimパラメータを分類します。一時的な障害はバックオフを伴って再試行し、無効なパラメータは再試行不可とマークします。スケジューラが同じ障害ドメインに繰り返し作業を送信しないよう、異常なノードを隔離します。
フォローアップ4:移行によって使用率が低下しなかったことをどのように証明しますか?
同一デバイスプール内の類似ワークロードについて、割り当て成功率、待機時間、断片化、有効な計算時間、ジョブの再試行率を比較します。DRAと従来のプラグインをデバイスクラスごとに分割して比較します。クラスタ全体の平均GPU使用率だけでは不十分です。