次の方法で共有


Application Gateway for Containers 上の gRPC

gRPC とは

gRPC は、古くからあるリモート プロシージャ コール (RPC) プロトコルを進化させた最新のハイパフォーマンス フレームワークです。 アプリケーション レベルでは、gRPC により、クライアントとバックエンド サービス間のメッセージングが合理化されます。 Google から提供されている gRPC は、オープンソースであり、クラウドネイティブ オファリングの Cloud Native Computing Foundation (CNCF) エコシステムの一部です。 CNCF は、gRPC を Incubating (発展中) プロジェクトと見なしています。 Incubating とは、エンドユーザーが運用アプリケーションでそのテクノロジを使用しており、プロジェクトには多数の貢献者がいることを意味します。

一般的な gRPC クライアント アプリは、事業運営を実装するローカルのインプロセス関数を公開しています。 内部的には、そのローカル関数により、リモート マシン上の別の関数が呼び出されます。 ローカルの呼び出しのように見えますが、本質的には、リモート サービスへの透過的なアウトプロセス呼び出しです。 RPC のプラミングにより、コンピューター間のポイントツーポイント ネットワーク通信、シリアル化、および実行が抽象化されます。

クラウドネイティブ アプリケーションの場合、開発者は複数のプログラミング言語、フレームワーク、テクノロジにまたがって作業することがよくあります。 この "相互運用性" により、クロスプラットフォームの通信に必要なメッセージ コントラクトとプラミングが複雑になります。 gRPC には、このような懸案事項を抽象化する "均一な水平レイヤー" が用意されています。 開発者は、ビジネス機能に集中して、ネイティブ プラットフォームでコードを書き、通信のプラミングは gRPC で処理します。

gRPC は、Java、JavaScript、C#、Go、Swift、NodeJS など、ほとんどの一般的な開発スタックを包括的にサポートしています。

gRPC の利点

gRPC では、トランスポート プロトコルに HTTP/2 が使用され、多くの高度な機能が提供されます。

  • データ転送のためのバイナリ フレーミング プロトコルです。テキストベースの HTTP 1.1 とは異なります。
  • 同じ接続を介して複数の並列要求を送信するための多重化のサポート。HTTP 1.1 の場合、処理が一度に 1 つの要求および応答メッセージに制限されています。
  • クライアント要求とサーバー応答の両方を同時に送信するための双方向全二重通信。
  • 大規模なデータセットを非同期にストリーミングするための要求と応答を可能にする組み込みのストリーミング。
  • ネットワークの使用量を減らすヘッダー圧縮。

gRPC は軽量でハイ パフォーマンスです。 メッセージが 60-80% 小さいので JSON シリアル化よりも最大 8 倍高速になる可能性があります。

プロトコル バッファー

gRPC はプロトコル バッファーというオープンソースのテクノロジを採用しています。 サービスが相互に送信する構造化メッセージをシリアル化するための、非常に効率的でプラットフォームに依存しないシリアル化形式が用意されています。 開発者は、クロスプラットフォームの インターフェイス定義言語 (IDL) を使用して、各マイクロサービスのサービスのサービス コントラクトを定義します。 コントラクトはテキストベースの .proto ファイルとして実装され、各サービスのメソッド、入力、出力が記述されます。 同じコントラクト ファイルを、異なる開発プラットフォームで構築された gRPC クライアントやサービスに使用することができます。

proto ファイルを使用すると、Protobuf コンパイラ protoc によってターゲット プラットフォーム用のクライアントとサービスの両方のコードが生成されます。 このコードには次のコンポーネントが含まれています。

  • クライアントとサービスによって共有される厳密に型指定されたオブジェクト。メッセージのサービス操作とデータ要素を表します。
  • リモート gRPC サービスによって継承および拡張できる、必要なネットワーク プラミングを備えた厳密に型指定された基底クラス。
  • リモート gRPC サービスを呼び出すための必要なプラミングを含むクライアント スタブ。

実行時には、各メッセージは標準的な Protobuf 表現としてシリアル化され、クライアントとリモート サービスの間で交換されます。 JSON や XML とは異なり、Protobuf メッセージはコンパイルされたバイナリ バイトとしてシリアル化されます。

RPC ライフ サイクル

gRPC には、クライアントが gRPC サーバーと対話する方法として 4 つの rpc ライフ サイクルがあります。

単項 RPC

単項ライフ サイクルの場合、gRPC サーバーに対して要求が行われ、応答が返されます。

単項 gRPC ライフサイクルを示すダイアグラム。

クライアント ストリーミング RPC

クライアント ストリーミング ライフ サイクルの場合、gRPC サーバーに対して要求が行われ、その後、サーバーから追加の応答を受けることなく、一連の追加のメッセージがクライアントからサーバーにストリーミングされます。

クライアント ストリーミング gRPC ライフ サイクルを示すダイアグラム。

サーバー ストリーミング RPC

サーバー ストリーミング ライフ サイクルの場合、gRPC サーバーに対して要求が行われ、その後、クライアントから追加の応答を受けることなく、一連のメッセージがサーバーからクライアントにストリーミングされます。

サーバー ストリーミング gRPC ライフ サイクルを示すダイアグラム。

双方向ストリーミング RPC

双方向ストリーミング ライフ サイクルの場合、gRPC サーバーに対して要求が行われ、クライアントとサーバーの両方が相互に独立して動作しながら、一連のメッセージを送信します。

双方向ストリーミング gRPC ライフ サイクルを示すダイアグラム。

Application Gateway for Containers での gRPC の実装

Application Gateway for Containers には、単項、クライアント ストリーミング、サーバー ストリーミング、双方向ストリームという 4 つの各ライフ サイクルに従って要求をプロキシする機能があります。

gRPC 定義

構成は、Kubernetes Gateway API を使用して GRPCRoute リソースを定義することで実装されます (Application Gateway for Containers の Ingress API では gRPC はサポートされていません)。 各 GRPCRoute リソースは Gateway リソースを参照する必要があります。 要求を処理する規則が固有である場合、複数の GRPCRoute リソースが同じゲートウェイを参照することができます。

たとえば、次の GRPCRoute は Gateway-01 というゲートウェイにアタッチされます。

apiVersion: gateway.networking.k8s.io/v1
kind: GRPCRoute
metadata:
  name: grpc-route-example
  namespace: grpc-namespace
spec:
  parentRefs:
    - name: gateway-01
      namespace: gateway-namespace
  rules:
    - matches:
        - method:
            service: ChatBotService
            method: TalkBack
      backendRefs:
        - name: gRPC-TalkBack
          port: 8080

gRPC は、Application Gateway for Containers に Gateway API を使用する場合にのみサポートされます。

正常性プローブ

Application Gateway for Containers の既定では、gRPC サービスを実行しているバックエンド ポートへの TCP ハンドシェイクを開始しようと試みます。 ハンドシェイクが完了すると、バックエンドは正常であると見なされます。

HealthCheckPolicy をカスタム正常性プローブとして使用する場合、定義されたポリシーによってプローブの動作が決まります。

gRPC バックエンドの HealthCheckPolicy の例を次に示します。

apiVersion: alb.networking.azure.io/v1
kind: HealthCheckPolicy
metadata:
  name: gateway-health-check-policy
  namespace: test-infra
spec:
  targetRef:
    group: ""
    kind: Service
    name: test-service
    namespace: test-infra
  default:
    interval: 5s
    timeout: 3s
    healthyThreshold: 1
    unhealthyThreshold: 1
    port: 8123
    grpc: {} # defined if probing a gRPC endpoint
    UseTLS: true

この例では、protocol、port、UseTLS は省略可能ですが、サービスに複数のポッドが含まれており、gRPC ポッドが別のポートで公開されている場合は、そのポッドに対してプローブを明示的に開始する方法を参照できます。