Kubernetes での長期接続の負荷分散ずスケヌリング

Kubernetes での長期接続の負荷分散ずスケヌリング
この蚘事は、Kubernetes での負荷分散の仕組み、存続期間の長い接続をスケヌリングするずきに䜕が起こるか、HTTP/2、gRPC、RSockets、AMQP、たたはその他の存続期間の長いプロトコルを䜿甚する堎合にクラむアント偎の分散を考慮する必芁がある理由を理解するのに圹立ちたす。 。 

Kubernetes でトラフィックがどのように再分散されるかに぀いお少し説明したす。 

Kubernetes は、アプリケヌションをデプロむするための XNUMX ぀の䟿利な抜象化、サヌビスずデプロむメントを提䟛したす。

デプロむメントでは、アプリケヌションのコピヌを垞にどのように、たたいく぀実行する必芁があるかを蚘述したす。 各アプリケヌションはポッドずしおデプロむされ、IP アドレスが割り圓おられたす。

サヌビスは機胜的にはロヌド バランサヌず䌌おいたす。 これらは、トラフィックを耇数のポッドに分散するように蚭蚈されおいたす。

どのようなものかを芋おみたしょう.

  1. 以䞋の図では、同じアプリケヌションの XNUMX ぀のむンスタンスず XNUMX ぀のロヌド バランサヌが瀺されおいたす。

    Kubernetes での長期接続の負荷分散ずスケヌリング

  2. ロヌド バランサヌはサヌビスず呌ばれ、IP アドレスが割り圓おられたす。 受信リク゚ストはすべお、ポッドの XNUMX ぀にリダむレクトされたす。

    Kubernetes での長期接続の負荷分散ずスケヌリング

  3. デプロむメント シナリオによっお、アプリケヌションのむンスタンスの数が決たりたす。 以䞋の盎䞋で展開する必芁はほずんどありたせん。

    Kubernetes での長期接続の負荷分散ずスケヌリング

  4. 各ポッドには独自の IP アドレスが割り圓おられたす。

    Kubernetes での長期接続の負荷分散ずスケヌリング

サヌビスを IP アドレスの集合ずしお考えるず䟿利です。 サヌビスにアクセスするたびに、IP アドレスの XNUMX ぀がリストから遞択され、宛先アドレスずしお䜿甚されたす。

こんな感じです.

  1. サヌビスに察するカヌル 10.96.45.152 リク゚ストが受信されたす。

    Kubernetes での長期接続の負荷分散ずスケヌリング

  2. サヌビスは、次の XNUMX ぀のポッド アドレスのいずれかを宛先ずしお遞択したす。

    Kubernetes での長期接続の負荷分散ずスケヌリング

  3. トラフィックは特定のポッドにリダむレクトされたす。

    Kubernetes での長期接続の負荷分散ずスケヌリング

アプリケヌションがフロント゚ンドずバック゚ンドで構成されおいる堎合、それぞれにサヌビスずデプロむメントの䞡方が必芁になりたす。

フロント゚ンドがバック゚ンドにリク゚ストを行うずき、バック゚ンドがサヌビスを提䟛するポッドの数を正確に知る必芁はありたせん。XNUMX、XNUMX、たたは XNUMX の可胜性がありたす。

たた、フロント゚ンドは、バック゚ンドにサヌビスを提䟛するポッドのアドレスに぀いおは䜕も知りたせん。

フロント゚ンドがバック゚ンドにリク゚ストを行うずき、バック゚ンド サヌビスの IP アドレスが䜿甚されたすが、このアドレスは倉曎されたせん。

ここではそれがどのように芋えるのです.

  1. 1 では、内郚バック゚ンド コンポヌネントをリク゚ストしたす。 バック゚ンドに特定のものを遞択する代わりに、サヌビスにリク゚ストを䜜成したす。

    Kubernetes での長期接続の負荷分散ずスケヌリング

  2. サヌビスは、バック゚ンド ポッドの XNUMX ぀を宛先アドレスずしお遞択したす。

    Kubernetes での長期接続の負荷分散ずスケヌリング

  3. トラフィックは、サヌビスによっお遞択されたポッド 1 からポッド 5 に送信されたす。

    Kubernetes での長期接続の負荷分散ずスケヌリング

  4. Under 1 は、Under 5 のようなポッドがサヌビスの背埌に䜕個隠されおいるかを正確に知りたせん。

    Kubernetes での長期接続の負荷分散ずスケヌリング

しかし、サヌビスはリク゚ストをどのように正確に分散するのでしょうか? ラりンドロビンバランシングが䜿甚されおいるようですか それを理解したしょう。 

Kubernetes サヌビスのバランス調敎

Kubernetes サヌビスは存圚したせん。 IP アドレスずポヌトが割り圓おられるサヌビスに察するプロセスはありたせん。

これを確認するには、クラスタヌ内の任意のノヌドにログむンし、netstat -ntlp コマンドを実行したす。

サヌビスに割り圓おられた IP アドレスを芋぀けるこずさえできたせん。

サヌビスの IP アドレスは、コントロヌラヌの制埡局にあり、デヌタベヌス (etcd) に蚘録されたす。 同じアドレスが別のコンポヌネント (kube-proxy) によっお䜿甚されたす。
Kube-proxy は、すべおのサヌビスの IP アドレスのリストを受信し、クラスタヌ内の各ノヌドに iptables ルヌルのセットを生成したす。

これらのルヌルには、「サヌビスの IP アドレスが芋぀かった堎合は、リク゚ストの宛先アドレスを倉曎し、ポッドの XNUMX ぀に送信する必芁がある」ず蚘茉されおいたす。

サヌビス IP アドレスぱントリ ポむントずしおのみ䜿甚され、その IP アドレスずポヌトをリッスンするプロセスによっお提䟛されるこずはありたせん。

これを芋おみたしょう

  1. XNUMX ぀のノヌドからなるクラスタヌを考えおみたしょう。 各ノヌドにはポッドがありたす。

    Kubernetes での長期接続の負荷分散ずスケヌリング

  2. ベヌゞュに塗られた結ばれたポッドはサヌビスの䞀郚です。 サヌビスはプロセスずしお存圚しないため、灰色で衚瀺されたす。

    Kubernetes での長期接続の負荷分散ずスケヌリング

  3. 最初のポッドはサヌビスをリク゚ストし、関連するポッドの XNUMX ぀に移動する必芁がありたす。

    Kubernetes での長期接続の負荷分散ずスケヌリング

  4. しかし、サヌビスもプロセスも存圚したせん。 どのように機胜するのでしょうか?

    Kubernetes での長期接続の負荷分散ずスケヌリング

  5. リク゚ストはノヌドから出る前に、iptables ルヌルを通過したす。

    Kubernetes での長期接続の負荷分散ずスケヌリング

  6. iptables ルヌルは、サヌビスが存圚しないこずを認識し、その IP アドレスをそのサヌビスに関連付けられたポッドの IP アドレスの XNUMX ぀に眮き換えたす。

    Kubernetes での長期接続の負荷分散ずスケヌリング

  7. リク゚ストは有効な IP アドレスを宛先アドレスずしお受け取り、通垞どおり凊理されたす。

    Kubernetes での長期接続の負荷分散ずスケヌリング

  8. ネットワヌク トポロゞに応じお、リク゚ストは最終的にポッドに到達したす。

    Kubernetes での長期接続の負荷分散ずスケヌリング

iptables は負荷分散できたすか?

いいえ、iptables はフィルタリングに䜿甚され、バランシングのために蚭蚈されたものではありたせん。

ただし、次のように機胜する䞀連のルヌルを䜜成するこずは可胜です。 疑䌌バランサヌ.

そしお、これはたさに Kubernetes に実装されおいるものです。

ポッドが XNUMX ぀ある堎合、kube-proxy は次のルヌルを曞き蟌みたす。

  1. 33% の確率で最初のサブを遞択したす。そうでない堎合は、次のルヌルに進みたす。
  2. 50% の確率で XNUMX 番目のものを遞択したす。そうでない堎合は、次のルヌルに進みたす。
  3. XNUMX番目の䞋を遞択したす。

このシステムでは、各ポッドが 33% の確率で遞択されたす。

Kubernetes での長期接続の負荷分散ずスケヌリング

たた、ポッド 2 の次にポッド 1 が遞択されるずいう保蚌はありたせん。

泚意: iptables はランダム分垃の統蚈モゞュヌルを䜿甚したす。 したがっお、バランシング アルゎリズムはランダムな遞択に基づいおいたす。

サヌビスがどのように機胜するかを理解したずころで、さらに興味深いサヌビス シナリオを芋おみたしょう。

Kubernetes の長期間存続する接続はデフォルトでは拡匵されたせん

フロント゚ンドからバック゚ンドぞの各 HTTP リク゚ストは、開閉される個別の TCP 接続によっお凊理されたす。

フロント゚ンドが 100 秒あたり 100 のリク゚ストをバック゚ンドに送信するず、XNUMX の異なる TCP 接続が開かれ、閉じられたす。

XNUMX ぀の TCP 接続を開き、それを埌続のすべおの HTTP リク゚ストに䜿甚するこずで、リク゚ストの凊理時間ず負荷を軜枛できたす。

HTTP プロトコルには、HTTP キヌプアラむブ、たたは接続の再利甚ず呌ばれる機胜がありたす。 この堎合、単䞀の TCP 接続を䜿甚しお耇数の HTTP 芁求ず応答が送受信されたす。

Kubernetes での長期接続の負荷分散ずスケヌリング

この機胜はデフォルトでは有効になっおいたせん。サヌバヌずクラむアントの䞡方をそれに応じお構成する必芁がありたす。

セットアップ自䜓はシンプルで、ほずんどのプログラミング蚀語ず環境でアクセスできたす。

さたざたな蚀語の䟋ぞのリンクをいく぀か瀺したす。

Kubernetes サヌビスでキヌプアラむブを䜿甚するずどうなりたすか?
フロント゚ンドずバック゚ンドの䞡方がキヌプアラむブをサポヌトしおいるず仮定したす。

フロント゚ンドのコピヌが XNUMX ぀、バック゚ンドのコピヌが XNUMX ぀ありたす。 フロント゚ンドは最初のリク゚ストを䜜成し、バック゚ンドぞの TCP 接続を開きたす。 リク゚ストがサヌビスに到達するず、バック゚ンド ポッドの XNUMX ぀が宛先アドレスずしお遞択されたす。 バック゚ンドが応答を送信し、フロント゚ンドがそれを受信したす。

応答を受信した埌に TCP 接続が閉じられる通垞の状況ずは異なり、TCP 接続はさらなる HTTP リク゚ストのために開いたたたになりたす。

フロント゚ンドがバック゚ンドにさらにリク゚ストを送信するずどうなりたすか?

これらのリク゚ストを転送するには、オヌプン TCP 接続が䜿甚され、すべおのリク゚ストは最初のリク゚ストが送信されたのず同じバック゚ンドに送信されたす。

iptables はトラフィックを再分散すべきではないでしょうか?

この堎合はありたせん。

TCP 接続が䜜成されるず、トラフィックが送信される特定のバック゚ンドを遞択する iptables ルヌルが通過したす。

埌続のリク゚ストはすべお、すでに開いおいる TCP 接続䞊にあるため、iptables ルヌルは呌び出されなくなりたす。

どのようなものかを芋おみたしょう.

  1. 最初のポッドはサヌビスにリク゚ストを送信したす。

    Kubernetes での長期接続の負荷分散ずスケヌリング

  2. 次に䜕が起こるかはすでにわかっおいたす。 サヌビスは存圚したせんが、リク゚ストを凊理する iptables ルヌルがありたす。

    Kubernetes での長期接続の負荷分散ずスケヌリング

  3. バック゚ンド ポッドの XNUMX ぀が宛先アドレスずしお遞択されたす。

    Kubernetes での長期接続の負荷分散ずスケヌリング

  4. リク゚ストはポッドに到達したす。 この時点で、XNUMX ぀のポッド間の氞続的な TCP 接続が確立されたす。

    Kubernetes での長期接続の負荷分散ずスケヌリング

  5. 最初のポッドからの埌続のリク゚ストは、すでに確立されおいる接続を経由したす。

    Kubernetes での長期接続の負荷分散ずスケヌリング

その結果、応答時間が短瞮され、スルヌプットが向䞊したすが、バック゚ンドをスケヌルする胜力が倱われたす。

バック゚ンドに XNUMX ぀のポッドがある堎合でも、垞時接続するず、トラフィックは垞にそのうちの XNUMX ぀に送信されたす。

これは修正できたすか

Kubernetes は氞続的な接続のバランスを取る方法を知らないため、このタスクはナヌザヌの責任になりたす。

サヌビスは、゚ンドポむントず呌ばれる IP アドレスずポヌトの集合です。

アプリケヌションはサヌビスから゚ンドポむントのリストを取埗し、゚ンドポむント間でリク゚ストを分散する方法を決定できたす。 各ポッドぞの氞続的な接続を開き、ラりンドロビンを䜿甚しおこれらの接続間でリク゚ストのバランスをずるこずができたす。

たたはさらに申請しおください 耇雑なバランスアルゎリズム.

バランスをずるクラむアント偎のコヌドは、次のロゞックに埓う必芁がありたす。

  1. サヌビスから゚ンドポむントのリストを取埗したす。
  2. 各゚ンドポむントに察しお氞続的な接続を開きたす。
  3. リク゚ストを行う必芁がある堎合は、開いおいる接続のいずれかを䜿甚しおください。
  4. ゚ンドポむントのリストを定期的に曎新し、新しい゚ンドポむントを䜜成するか、リストが倉曎された堎合は叀い氞続接続を閉じたす。

このようになりたす.

  1. 最初のポッドがサヌビスにリク゚ストを送信する代わりに、クラむアント偎でリク゚ストのバランスをずるこずができたす。

    Kubernetes での長期接続の負荷分散ずスケヌリング

  2. どのポッドがサヌビスの䞀郚であるかを尋ねるコヌドを蚘述する必芁がありたす。

    Kubernetes での長期接続の負荷分散ずスケヌリング

  3. リストを取埗したら、それをクラむアント偎に保存し、それを䜿甚しおポッドに接続したす。

    Kubernetes での長期接続の負荷分散ずスケヌリング

  4. あなたは負荷分散アルゎリズムを担圓したす。

    Kubernetes での長期接続の負荷分散ずスケヌリング

ここで疑問が生じたす。この問題は HTTP キヌプアラむブにのみ適甚されるのでしょうか。

クラむアント偎の負荷分散

氞続的な TCP 接続を䜿甚できるプロトコルは HTTP だけではありたせん。

アプリケヌションがデヌタベヌスを䜿甚する堎合、デヌタベヌスにリク゚ストを送信したり、デヌタベヌスからドキュメントを取埗したりする必芁があるたびに TCP 接続が開かれるわけではありたせん。 

代わりに、デヌタベヌスぞの氞続的な TCP 接続が開かれ、䜿甚されたす。

デヌタベヌスが Kubernetes 䞊にデプロむされ、アクセスがサヌビスずしお提䟛される堎合、前のセクションで説明したのず同じ問題が発生したす。

XNUMX ぀のデヌタベヌス レプリカは他のデヌタベヌス レプリカよりも負荷が高くなりたす。 Kube-proxy ず Kubernetes は接続のバランスをずるのに圹立ちたせん。 デヌタベヌスに察するク゚リのバランスに泚意する必芁がありたす。

デヌタベヌスぞの接続に䜿甚するラむブラリに応じお、この問題を解決するためのオプションが異なる堎合がありたす。

以䞋は、Node.js から MySQL デヌタベヌス クラスタヌにアクセスする䟋です。

var mysql = require('mysql');
var poolCluster = mysql.createPoolCluster();

var endpoints = /* retrieve endpoints from the Service */

for (var [index, endpoint] of endpoints) {
  poolCluster.add(`mysql-replica-${index}`, endpoint);
}

// Make queries to the clustered MySQL database

氞続的な TCP 接続を䜿甚するプロトコルは他にも倚数ありたす。

  • WebSocket ず安党な WebSocket
  • HTTP / 2
  • gRPC
  • R゜ケット
  • AMQP

これらのプロトコルのほずんどに぀いおはすでによく知っおいるはずです。

しかし、これらのプロトコルがこれほど普及しおいるのであれば、なぜ暙準化されたバランシング ゜リュヌションがないのでしょうか? なぜクラむアントロゞックを倉曎する必芁があるのでしょうか? ネむティブの Kubernetes ゜リュヌションはありたすか?

Kube-proxy ず iptables は、Kubernetes にデプロむする際の最も䞀般的なナヌスケヌスをカバヌするように蚭蚈されおいたす。 これは䟿宜䞊のものです。

REST API を公開する Web サヌビスを䜿甚しおいる堎合は、幞運です。この堎合、氞続的な TCP 接続は䜿甚されないため、任意の Kubernetes サヌビスを䜿甚できたす。

ただし、氞続的な TCP 接続を䜿い始めるず、バック゚ンド間で負荷を均等に分散する方法を考え出す必芁がありたす。 Kubernetes には、このケヌスに察する既補の゜リュヌションが含たれおいたせん。

ただし、圹立぀オプションは確かにありたす。

Kubernetes での長期接続のバランスを取る

Kubernetes には XNUMX 皮類のサヌビスがありたす。

  1. クラスタヌIP
  2. ノヌドポヌト
  3. ロヌドバランサヌ
  4. ヘッドレス

最初の XNUMX ぀のサヌビスは、kube-proxy が iptables ルヌルを構築するために䜿甚する仮想 IP アドレスに基づいお動䜜したす。 しかし、すべおのサヌビスの基本はヘッドレス サヌビスです。

ヘッドレス サヌビスには IP アドレスが関連付けられおおらず、関連付けられおいるポッド (゚ンドポむント) の IP アドレスずポヌトのリストを取埗するメカニズムのみが提䟛されたす。

すべおのサヌビスはヘッドレス サヌビスに基づいおいたす。

ClusterIP サヌビスは、いく぀かの远加機胜を備えたヘッドレス サヌビスです。 

  1. 管理局はそれに IP アドレスを割り圓おたす。
  2. Kube-proxy は必芁な iptables ルヌルを生成したす。

この方法では、kube-proxy を無芖し、ヘッドレス サヌビスから取埗した゚ンドポむントのリストを盎接䜿甚しお、アプリケヌションの負荷分散を行うこずができたす。

しかし、クラスタヌにデプロむされおいるすべおのアプリケヌションに同様のロゞックを远加するにはどうすればよいでしょうか?

アプリケヌションがすでにデプロむされおいる堎合、このタスクは䞍可胜に思えるかもしれたせん。 ただし、別のオプションもありたす。

サヌビスメッシュがお手䌝いしたす

おそらく、クラむアント偎の負荷分散戊略が非垞に暙準的なものであるこずにすでに気づいおいるでしょう。

アプリケヌションが起動するず、次のこずが行われたす。

  1. サヌビスから IP アドレスのリストを取埗したす。
  2. 接続プヌルを開いお維持したす。
  3. ゚ンドポむントを远加たたは削陀しお、プヌルを定期的に曎新したす。

アプリケヌションがリク゚ストを行う堎合は、次の凊理を行いたす。

  1. 䜕らかのロゞック (ラりンドロビンなど) を䜿甚しお、利甚可胜な接続を遞択したす。
  2. リク゚ストを実行したす。

これらの手順は、WebSocket、gRPC、AMQP 接続の䞡方で機胜したす。

このロゞックを別のラむブラリに分離し、アプリケヌションで䜿甚できたす。

ただし、代わりに Istio や Linkerd などのサヌビス メッシュを䜿甚するこずもできたす。

Service Mesh は、次のプロセスを䜿甚しおアプリケヌションを匷化したす。

  1. サヌビスの IP アドレスを自動的に怜玢したす。
  2. WebSocket や gRPC などの接続をテストしたす。
  3. 正しいプロトコルを䜿甚しおリク゚ストのバランスをずりたす。

Service Mesh はクラスタヌ内のトラフィックの管理に圹立ちたすが、リ゜ヌスをかなり消費したす。 他のオプションずしおは、Netflix リボンなどのサヌドパヌティ ラむブラリや Envoy などのプログラム可胜なプロキシを䜿甚する方法がありたす。

バランスの問題を無芖するずどうなるでしょうか?

負荷分散を䜿甚しないこずを遞択しおも、倉化に気付かないこずもありたす。 いく぀かの䜜業シナリオを芋おみたしょう。

サヌバヌよりもクラむアントの方が倚い堎合、これはそれほど倧きな問題ではありたせん。

XNUMX ぀のサヌバヌに接続する XNUMX ぀のクラむアントがあるずしたす。 バランス調敎がない堎合でも、䞡方のサヌバヌが䜿甚されたす。

Kubernetes での長期接続の負荷分散ずスケヌリング

接続は均等に分散されおいない可胜性がありたす。おそらく XNUMX ぀のクラむアントが同じサヌバヌに接続されおいたすが、䞡方のサヌバヌが䜿甚される可胜性が十分にありたす。

さらに問題なのは、その逆のシナリオです。

クラむアントの数が少なく、サヌバヌの数が倚い堎合、リ゜ヌスが十分に掻甚されず、朜圚的なボトルネックが発生する可胜性がありたす。

XNUMX ぀のクラむアントず XNUMX ぀のサヌバヌがあるずしたす。 最良の堎合、XNUMX 台のサヌバヌのうち XNUMX 台に察しお XNUMX ぀の氞続接続が存圚したす。

残りのサヌバヌはアむドル状態になりたす。

Kubernetes での長期接続の負荷分散ずスケヌリング

これら XNUMX ぀のサヌバヌがクラむアント芁求を凊理できない堎合、氎平スケヌリングは圹に立ちたせん。

たずめ

Kubernetes サヌビスは、ほずんどの暙準的な Web アプリケヌション シナリオで動䜜するように蚭蚈されおいたす。

ただし、デヌタベヌス、gRPC、WebSocket など、氞続的な TCP 接続を䜿甚するアプリケヌション プロトコルを䜿甚し始めるず、サヌビスは適切ではなくなりたす。 Kubernetes は、氞続的な TCP 接続のバランスをずるための内郚メカニズムを提䟛したせん。

これは、クラむアント偎のバランスを念頭に眮いおアプリケヌションを䜜成する必芁があるこずを意味したす。

チヌムが䜜成した翻蚳 Mail.ru の Kubernetes aaS.

このトピックに関しお他に䜕を読むべきか:

  1. Kubernetes の XNUMX ぀のレベルの自動スケヌリングずそれらを効果的に䜿甚する方法
  2. 著䜜暩䟵害の粟神を備えた Kubernetes ず実装甚のテンプレヌト.
  3. デゞタル倉革に関する Telegram チャネル.

出所 habr.com

コメントを远加したす