代表的な面接トピック

システムデザイン面接:Kubernetes Gateway API で gRPC をどのようにルーティングするか?

システム設計難しい
Offer.cc 編集チーム公開日 更新日

質問

マルチテナントの Kubernetes クラスターで、gRPC サービス、メソッド、リクエストメタデータに基づいてルーティングを行う必要があります。Gateway API リソース、認可、リリースのロールバックをどのように設計しますか?

プロンプトと適用範囲

プラットフォームチームが共有 Kubernetes クラスターを運用し、アプリケーションチームが gRPC サービスをデプロイします。プラットフォームには、単一のエントリポイント、TLS 終端、サービス/メソッド/ヘッダーによるルーティング、カナリアリリースが求められます。各アプリケーションチームは自身の Route のみを編集でき、インフラや他の namespace を制御することはできません。リソース、リクエストパス、認可境界、オブザーバビリティ、障害時のロールバックを設計してください。

Gateway API コントローラーがインストールされており、バックエンドは HTTP/2 gRPC を使用し、クライアントには明示的なタイムアウトおよびリトライポリシーが設定されているものとします。単一ベンダーの実装ではなく、チーム間のコントロールプレーンの境界に焦点を当ててください。

面接官が評価するポイント

  • GatewayClass、Gateway、GRPCRoute、Service の責務を分離できているか。
  • 汎用的な Ingress YAML を作成するのではなく、GRPCRoute のマッチング粒度を理解しているか。
  • クロス namespace の ReferenceGrant、RBAC、デフォルト拒否(default deny)、監査を適切に処理しているか。
  • 重み付け、長時間のストリーム、リトライの危険性について説明できるか。
  • ステータスシグナル、ロールバックゲート、コントローラー/データプレーンの障害を定義できるか。

回答前の明確化のための質問

  1. Gateway はプラットフォームが一元管理していますか、それともチーム所有ですか?これにより Route のアタッチと承認フローが変わります。
  2. ルーティングはサービス、メソッド、ヘッダー、ホスト名のどれで行いますか?マッチングの優先順位によって競合処理が変わります。
  3. 呼び出しは Unary ですか、それとも長時間のストリーミングですか?通常、ストリーミングはリクエストごとのリトライや切り替えを行うべきではありません。
  4. カナリアの選択はパーセンテージ、テナント、ヘッダー、クライアントバージョンのどれで行いますか?重み、スティッキネス、ロールバックシグナルを定義してください。
  5. バックエンド Service はクロス namespace またはクラスタを跨ぐことができますか?それにより ReferenceGrant やヘルスチェックの考慮事項が加わります。

30秒の回答フレームワーク

プラットフォームが所有する Gateway と、アプリケーションが所有する GRPCRoute を分離し、Service をバックエンド検出の境界とします。Route で gRPC メソッドとメタデータのマッチングを宣言し、クロス namespace の参照には明示的な認可を要求します。コントローラーは Accepted および参照解決のステータスを公開し、データプレーンは重み付けに基づいてルーティングを行い、ストリームに対する盲目的なリトライを回避します。カナリアリリースは1つのテナントまたは明示的なヘッダーから開始し、メソッドエラー、テールレイテンシ、ビジネスヘルスをロールバックゲートとして使用し、Route またはバックエンドが無効な場合は安定版バックエンドに戻します。

ステップごとの詳細解説

1. リソースの責務とデータフロー

プラットフォームはコントローラーを選択する GatewayClass を作成し、リスナー、アドレス、TLS ポリシーを設定します。アプリケーションはその namespace 内に GRPCRoute を作成し、parentRefs を使用して許可された Gateway にアタッチし、自身の Service をターゲットにします。コントローラーは承認されたルールをデータプレーンの設定に変換し、ホスト名、gRPC サービス、メソッド、ヘッダーをマッチングした上で backendRefs を選択します。

2. マッチングと競合処理

完全一致とフォールバックマッチの優先順位を定義します。完全なサービス/メソッド一致はサービス単独の一致より優先され、サービス単独はヘッダーフォールバックより優先されます。2つのチームが同じ親リソースやマッチ条件を暗黙的に上書きすることを許可してはいけません。Accepted や ResolvedRefs などの Conditions を通じて競合を表面化させ、CI でそれらをチェックさせます。未知のメソッドに対しては、明示的な UNIMPLEMENTED または安定したフォールバックを選択し、任意のサービスへサイレントにルーティングしてはいけません。

3. マルチテナント認可

アプリケーションは自身の Route と Service のみを記述できます。allowedRoutes は Gateway にアタッチ可能な namespace を制限します。クロス namespace のバックエンド参照には、送信先 namespace の所有者によって承認された ReferenceGrant が必要です。RBAC、アドミッションポリシー、Git レビューにより、アプリケーションチームがプラットフォームの TLS、リスナー、または他チームの許可を変更するのを防ぎます。親リソース、バックエンド参照、重みを誰が変更したかを監査します。

4. カナリア、ストリーム、リトライ

Unary RPC は重み付けに従って新規リクエストを安定版とカナリア版に送信できます。ストリーミング RPC は接続確立後にそのルートを維持します。非冪等の呼び出しを自動的にリトライしてはならず、不明確なクライアントタイムアウトの上に Gateway のリトライを重ねてはいけません。デバッグ中に特定のテナントがランダムにドリフトしないよう、明示的なヘッダーまたはテナントリストをカナリアキーとして使用します。重みは小さなコミットで変更し、有効化の時刻を記録します。

5. ヘルス、ステータス、障害時のロールバック

データプレーンには gRPC ヘルスチェック、コネクションプール、およびルートごとの明示的なタイムアウトが必要です。コントローラーが利用できない場合は、最後に受け入れられた設定での提供を継続しますが、未検証の変更は拒否します。Gateway が受け入れられない場合、参照が解決できない場合、またはバックエンドにエンドポイントがない場合は、リリースをブロックするステータスを公開します。ロールバックでは、カナリアの重みをゼロに設定するか、以前の Route を復元するか、スタンバイの Gateway に切り替えます。これは冪等である必要があります。

6. オブザーバビリティとキャパシティの境界

リクエスト数、エラー、P50/P95/P99 レイテンシ、アクティブストリーム、リトライ、接続時間を、ルート、サービス、メソッド、ステータス、テナント、バージョンごとに記録します。カーディナリティの高い生のメタデータをメトリクスのラベルに含めてはなりません。ログ内でサンプリングおよびマスキングします。キャパシティテストでは、Unary およびストリーミングトラフィックの両方について、接続数、同時ストリーム数、TLS CPU、コントローラーの伝播遅延、バックエンドの接続制限をカバーする必要があります。

質の高い模範解答

プラットフォームチームに GatewayClass、Gateway、リスナーの所有権を与え、アプリケーションチームには namespace スコープの GRPCRoute と Service のみを所有させます。GRPCRoute はサービス/メソッドおよび制御されたヘッダーとマッチングします。クロス namespace バックエンドには送信先が所有する ReferenceGrant が必要であり、allowedRoutes と RBAC によってアタッチを制限します。

リリースの際、新規の Unary リクエストを安定版とカナリア版の間で重み付けします。ストリーミング接続は確立時に一度だけ選択されるため、ストリームの途中で切り替えることはしません。非冪等な呼び出しに対する自動リトライは避け、クライアントと Gateway の間でタイムアウトとリトライのバジェットを調整します。コントローラーは Accepted、ResolvedRefs、バックエンドのヘルスを公開し、CI は無効な参照や競合をブロックします。カナリアは1つのテナントまたは明示的なヘッダーから開始し、メソッドレベルのエラー、テールレイテンシ、アクティブストリーム、またはビジネス成功率に基づいてロールバックを行い、監査記録を残しながら以前の重みを復元します。

よくある間違い

GRPCRoute を通常の Ingress として扱う

サービス/メソッドおよび HTTP/2 のセマンティクスを無視すると、マッチングが広大になりすぎます。まず優先順位と未知のメソッドに対する動作を定義してください。

アプリケーションに Gateway の編集を許可する

共有リスナーや TLS がテナントによって変更可能になってしまいます。allowedRoutes、RBAC、ReferenceGrant、アドミッションポリシーを個別のゲートとして使用してください。

盲目的なリトライやストリームの強制切り替え

これにより副作用が重複したり、長時間の接続が切断されたりする可能性があります。冪等性と接続寿命に基づいて、Unary とストリーミングのポリシーを分離してください。

コントローラーのデプロイ成功のみを確認する

コントローラーが正常であっても、Route が受け入れられたことやバックエンドが使用可能であることは証明されません。Accepted、ResolvedRefs、ヘルス、およびデータプレーンのシグナルを確認してください。

フォローアップ質問と回答

フォローアップ 1: 2つの Route が同じメソッドにマッチした場合はどうなりますか?

実装ごとの偶発的な順序に依存してはなりません。namespace と親へのアタッチポリシーによって所有権を制約し、CI で競合をチェックし、未解決のステータスをリリースの失敗として扱います。

フォローアップ 2: カナリアで特定のテナントを安全に対象とするにはどうすればよいですか?

ランダムな重み付けではなく、明示的なテナントまたはヘッダーマッチングを使用し、バージョンおよびテナントごとのエラー率を記録します。ロールバック時はまずそのマッチングを削除します。

フォローアップ 3: Gateway コントローラーが停止するとトラフィックは中断されますか?

データプレーンが最後に受け入れられた設定を保持しているかどうかによります。変更を凍結した状態でトラフィックの処理を継続し、設定の経過時間を監視して、安全ウィンドウが期限切れになる前にスタンバイへフェイルオーバーします。

フォローアップ 4: クロス namespace の backendRef に認可が必要なのはなぜですか?

あるチームが別のチームの Service にトラフィックを送信できるようにするためです。送信先が所有する ReferenceGrant により同意が明示的になり、RBAC と監査により隠れた権限昇格を防ぐことができます。

公開情報ソース

関連する質問

関連面接ツール

システム設計の回答には「回答する」を使用

まず要件を明確にし、スケール、アーキテクチャ、コンポーネント選定、トレードオフの順に進めます。

ツールを見る