質問とコンテキスト
あるコントローラーはオブジェクト名、ラベル、ネームスペース、および resourceVersion のみを必要としていますが、サイズの大きい Pod の spec および status フィールドを読み取っています。リストリクエストに Kubernetes のメタデータ専用ネゴシエーションを使用し、未サポートのアグリゲート API、406 レスポンス、およびその後の watch について説明してください。
面接官がテストしていること
Acceptパラメータを正しく構築し、単一オブジェクト表現とリスト表現を区別できるかどうか。- 部分レスポンスを、任意のフィールドフィルタパッチではなく、表現(representation)として理解しているかどうか。
- 起動の失敗や無限リトライを引き起こすことなく、406、バージョンスキュー、完全オブジェクトへのフォールバックを設計できるかどうか。
- list/watch の
resourceVersionとキャッシュの整合性が正しく保たれているかどうか。
最初に確認すべき明確化のための質問
リソースとサーバーの境界
対象は in-tree API、CRD、それともアグリゲート API ですか?すべての apiserver とプロキシがメタデータ専用レスポンスをサポートしていますか?
使用パターン
クライアントは存在とラベルのインデックスを作成するだけですか、それとも後で spec が必要になりますか?リスト直後に watch を開始する必要がありますか?
障害ポリシー
部分レスポンスが利用できない場合、クライアントは完全なオブジェクトを読み取ってもよいですか、それとも帯域幅とメモリの予算を保護するために明示的に失敗する必要がありますか?
30秒の回答フレームワーク
リストには application/json;as=PartialObjectMetadataList;g=meta.k8s.io;v=v1 を優先し、メタデータとリストの resourceVersion のみを受け入れます。フォールバックとして優先度の低い application/json を追加し、レスポンスの kind を検査して実際に何が返されたかを把握します。フォールバックがない場合は、406 をリトライ可能なストームではなく未サポートの機能として扱います。返されたリソースバージョンから watch を開始し、その表現をキャッシュに記録します。
詳細な回答ステップ
1. 表現を区別する
1 つのオブジェクトには as=PartialObjectMetadata を使用し、コレクションには as=PartialObjectMetadataList を使用します。レスポンスでは spec と status が省略され、メタデータが保持されます。これにより、シリアライズ、ネットワーク、およびデコードのコストが削減されますが、ビジネスフィールドを必要とする呼び出し元には対応できません。
2. フォールバックリクエストを構築する
GET /api/v1/pods
Accept: application/json;as=PartialObjectMetadataList;g=meta.k8s.io;v=v1, application/json;q=0.9優先される表現が利用できない場合、サーバーは通常の JSON を選択することがあります。クライアントは kind、apiVersion、および Content-Type を検査する必要があります。HTTP 200 だけでは部分オブジェクトが返されたことを証明できません。
3. strict モードと 406 を処理する
対象 API がサポートしていない部分表現のみをリクエストが提示した場合、Kubernetes は 406 を返します。これを機能結果として記録し、ポリシーに従って完全なオブジェクトに切り替えるか、リソースをスキップするか、設定エラーを表面化させます。同じ Accept ヘッダーで無期限にリトライしたり、406 を一時的なネットワーク障害として分類したりしないでください。
4. アグリゲート API と CRD を処理する
組み込み API は通常メタデータ専用レスポンスをサポートしますが、アグリゲーションの背後にある API はサポートしていない場合があります。CRD やサードパーティの実装も完全なオブジェクトのみを公開する場合があります。リソースおよびサーバーごとに機能をプローブし、結果を有効期限付きでキャッシュし、1 つのリソースの成功をすべてのリソースに一般化しないでください。
5. list/watch の整合性を維持する
リストの resourceVersion は引き続き watch の開始点となります。これを保存し、有効期限切れ、切断、および再リストを処理し、メタデータ専用が変更するのはリソースバージョンのセマンティクスではなく表現であることを忘れないでください。完全オブジェクトへのフォールバックは、古く混在したデータを避けるために、同じバージョンを使用してキャッシュを設定する必要があります。
6. キャッシュとアップグレード動作を設計する
キャッシュエントリには、表現とフィールドの可用性を記録する必要があります。spec を必要とするパスは、メタデータ専用エントリにそれが存在すると想定してはなりません。名前を指定して制御された完全な GET を発行してください。サーバーまたはプロキシをアップグレードした後は Accept 機能を再プローブし、不要な完全オブジェクトパスが永久に残らないようにします。
7. コストとセキュリティを測定する
リクエストバイト数、デコード CPU、ヒープピーク、リストレイテンシ、watch 再接続率、および完全な GET の比率を比較します。ラベル、アノテーション、およびオーナーリファレンスには依然として機密データが含まれている可能性があります。メタデータのみが返されるからといって認証・認可が不要になるわけではありません。すべての注釈をログやメトリクスに出力することは避けてください。
質の高い回答例
私は PartialObjectMetadataList を優先し、優先度の低い通常の JSON をフォールバックとして含めます。クライアントは返された kind を検証し、406 で 1 回の機能切り替えを実行します。リストの resourceVersion から watch を開始し、フィールドの可用性をキャッシュに記録します。アグリゲート API、CRD、および spec を必要とするパスは個別にプローブと読み取りを行い、バイト数、CPU、メモリ、再接続のメトリクスによってメリットを証明します。
よくある間違い
- リストに対して単一オブジェクト用の
PartialObjectMetadataパラメータを使用すること。 - メタデータ専用を任意のサーバー側フィールドフィルタリングとして扱い、レスポンスの kind を無視すること。
- フォールバックが提供されていない場合に 406 をリトライ可能な 5xx として扱うこと。
- in-tree の機能がアグリゲート API やすべての CRD に適用されると想定すること。
- リストの
resourceVersionを破棄し、誤ったポイントから watch を再開すること。 - デコード CPU、ヒープピーク、または再接続コストを考慮せずにレスポンスサイズのみを測定すること。
フォローアップの質問と回答
なぜリストに PartialObjectMetadataList を使用するのですか?
コレクションリクエストはリスト表現を返し、PartialObjectMetadataList は各アイテムにメタデータのみが含まれていることを明示的に示します。単一オブジェクト形式は 1 つの GET 用です。クライアントはそれらを混同して推測すべきではありません。
サーバーが部分レスポンスをサポートしていない場合はどうなりますか?
通常の JSON を優先度の低いフォールバックとして使用し、レスポンスの kind を検査して完全なオブジェクトを使用します。strict モードでは、406 を機能の欠如として記録し、リソースポリシーに従ってスキップまたは失敗させます。無限にリトライしてはなりません。
メタデータ専用によって resourceVersion は変わりますか?
いいえ。変わるのは表現であり、resourceVersion のセマンティクスではありません。リストのバージョンは引き続き watch とキャッシュの整合性のアンカーとなります。
すべての CRD がこのリクエストをサポートしていますか?
そう想定してはなりません。アグリゲート API や CRD は部分表現を実装していない場合があります。リソースごとに機能をプローブしてキャッシュしてください。
完全なオブジェクトを読み取る必要があるのはいつですか?
決定を下すのに spec、status、またはその他のビジネスフィールドが必要な場合です。メタデータを使用してインデックスを構築し、名前またはイベントによって制御された完全な GET をトリガーします。