2016-09-22 30 views
9

kubernetesポッド内のクライアント/サーバとしてPythonでgRPCを使用しています... 同じタイプ(gRPCサーバ)の複数のポッドを起動してクライアントに接続させたいと思いますそれら(無作為に)。gRPCクライアント側の負荷分散

私は10ポッドのサーバを派遣し、それらをターゲットとするために「サービス」をセットアップしました。次に、クライアントでは、サービスのDNS名に接続しました。つまり、kubernetesはロードバランシングを行い、ランダムなサーバーポッドに移動する必要があります。 実際には、クライアントはgRPC関数を呼び出します(これはうまくいきます)が、ログを見ると、すべての呼び出しが同じサーバーポッドに送られています。

私は、クライアントが何らかの種類のDNSキャッシングを行っていると仮定し、すべての呼び出しが同じサーバーに送信されるようにします。これは本当ですか?とにかくそれを無効にし、同じスタブクライアントを設定して "新しい"呼び出しを行い、各呼び出しでDNSによって新しいIPをフェッチしますか?

毎回DNSサーバーにクエリを実行すると、負荷が分散することがわかります。

EDIT

は、おそらくキャッシュの問題は...ちょうどgRPCの動作方法かもしれません。 HTTP/2と永続的な再利用可能な接続。各通話後に「切断」する方法はありますか?

答えて

10

私は、物事がどのように働くことになっているかを説明することによって答えを出すことができます。

クライアントサイドLBはgRPC Cコア以下のように(すべてが、Javaや味やgRPCを行くための基礎)がある(権威ドキュメントがhereを見つけることができる)で動作する方法:

クライアント側LBは目的に応じて単純で「ダム」に保たれます。複雑なLBポリシーを実装する方法は、前述の文書で説明されているように、外部のLBサーバーを使用する方法です。このシナリオには関心がありません。代わりに、チャネルを作成するだけで、(デフォルトの)ピックファースト LBポリシーが使用されます。

LBポリシーへの入力は、解決されたアドレスのリストです。 DNSを使用する場合、foo.comが[10.0.0.1, 10.0.0.2, 10.0.0.3, 10.0.0.4]に解決されると、ポリシーはそれらのすべてへの接続を確立しようとします。最初に正常に接続すると、が切断されるまでが選択されます。したがって、「ピック・ファースト」という名前。より長い名前は「できるだけ長い間、最初に選択してください」でしたが、非常に長いファイル名のために作られました:)。ピックされたものが切断された場合、ピック・ファースト・ポリシーは、次に正常に接続されたアドレス(内部的には「接続されたサブチャネル」と呼ばれる)を返すように移動する。もう一度、接続されている限り、この接続されたサブチャンネルを選択し続けます。すべてが失敗した場合、コールは失敗します。

ここでの問題は、本質的にプルベースであるDNS解決が、1)チャンネル作成時と、2)選択された接続されたサブチャンネルの切断時にのみトリガされることです。

今のところ、ハックリの解決策はすべてのリクエストに対して新しいチャネルを作成することです(非常に非効率的ですが、設定を考えればそのトリックを行うことになります)。

Q1 2017(https://github.com/grpc/grpc/issues/7818参照)の変更があると、クライアントは別のLBポリシー、つまりラウンドロビンを選択できます。さらに、クライアント設定に「ランダム化」ビットを導入することで、ラウンドロビンを実行する前にアドレスをシャッフルし、意図したものを効果的に達成できます。

+0

詳細な回答ありがとうございます。実際には、私はあなたが提案したものを既に行い、それぞれの要求に対して新しいチャンネルを作成しました(効率的ではありません、私は知っています)。あなたの答えから、私は、DNS内の最初のIPだけが停止するまで(使用可能な接続/強制終了/クラッシュ)、クライアントが2番目のIPに到達するまで要求を取得することを理解しています。 – Idan

+0

はい。前述のように、LBポリシーとして最初に選択の代わりにラウンドロビンを選択できるようになるまでは、 –

+0

通常、複数のgRPCサーバーを拡張する方法はありますか?またはクライアント側のロードバランシング? –

1

バニラKubernetesサービスを作成した場合、サービスには独自の負荷分散された仮想IPが必要です(kubectl get svc your-serviceにサービスのCLUSTER-IPが表示されているかどうかを確認してください)。これが当てはまる場合、その単一の仮想IPが実際のバックエンド間でトラフィックを分割する必要があるため、DNSキャッシングは問題ではありません。

​​を試して、サービスが実際にすべてのバックエンドについて知っていることを確認してください。

headless serviceがある場合、DNSルックアップは10個のIP(各ポッドごとに1個)のAレコードを返します。クライアントが常にAレコードの最初のIPを選択している場合は、表示されている動作も説明されます。

+0

サーバー用のCLUSTER_IPがあり、「エンドポイントを取得する」ときにすべてのエンドポイントがあることがわかります。それでも同じサーバーに移動します。私はそれがgRPCの仕組みとHTTP/2の接続再利用の方法かもしれないと思います... – Idan

関連する問題