クラウドネイティブ時代を1万語で解説、K8sコンテナプラットフォームのLB(Nginx)負荷分散システムを0から1に構築する方法

クラウドネイティブ時代を1万語で解説、K8sコンテナプラットフォームのLB(Nginx)負荷分散システムを0から1に構築する方法

クラウドネイティブ時代において、Kubernetes をベースとしたコンテナ オーケストレーション ソリューションが現在のところ最適な選択肢です。中規模および大規模のインターネット企業はすべて Kubernetes を採用しており、Kubernetes に匹敵するソリューションは他にありません。

すべてのサービス (特に高同時実行サービス) へのアクセスは、負荷分散 LB プロキシ レイヤーを通過する必要があります。サーバー側の高同時実行システムは、負荷分散なしでは実行できません。大規模および中規模の企業では、負荷分散プロキシ層は専任の担当者によって独自に開発および構築されます。クラウドネイティブ Kubernetes コンテナ プラットフォームの下にある LB プロキシ レイヤーでも、構築と保守を担当する専任の担当者が必要です。では、Kubernetes コンテナ プラットフォームに基づいて LB (Nginx) ロード バランシング プロキシ レイヤーを構築するにはどうすればよいでしょうか?非コンテナプラットフォームでの LB 構築との類似点と相違点は何ですか?構築の核心点と現時点での最善の解決策は何ですか?この記事を読めば、Kubernetes コンテナ プラットフォームの LB (Nginx) 負荷分散について明確に理解でき、Kubernetes LB (Nginx) 負荷分散システムを迅速かつ深く構築できるようになると思います。また、中規模から大規模の企業が、大規模な Kubernetes コンテナ プラットフォームの LB (Nginx) 負荷分散システムを 0 から 1 までどのように構築したかについて、非常に貴重な実践的な経験も学ぶことができます。

適している対象: Kubernetes 開発者、LB 開発者、Kubernetes の基本的な運用および保守担当者、LB (Nginx) 実践者、コンテナ プラットフォーム開発者、またはアーキテクチャ設計者。

1. コンテナLB建設の背景

PS: Kubernetes の基本的な概念に精通していない場合は、まず Kubernetes を理解する必要があります。この記事は、分析と設計のための Kubernetes の基本概念をある程度理解していることを前提としています。

1. 負荷分散(LB)の概要

ロード バランシング (LB) とは、クライアント アクセス トラフィックをロード バランサーに渡し、指定されたロード バランシング戦略に従って転送して、バックエンドのアップストリーム サーバーに均等に分散できるようにすることです。その後、アップストリーム サーバーが応答し、データをクライアントに返します。負荷分散の最も一般的な用途は、リバース プロキシとして機能することです。負荷分散により、サービスの応答速度が大幅に向上し、同時リクエストが増加し、安定性が向上します (単一点障害を防止)。

  • 業界の観点から見ると、負荷分散の基本的な実装は、一般的にソフトウェアとハ​​ードウェアの 2 つのカテゴリに分けられます。ソフトウェア負荷分散は、次のように 4 層負荷分散や 7 層負荷分散などの層に分けられます。
  • ハードウェア負荷分散
  • F5と同様に、パフォーマンスは優れていますが、高価です。ほとんどのインターネット企業はハードウェア負荷分散を収集していない
  • ソフトウェア負荷分散
  • 現在、どちらもレイヤー 4 を実装できますが、Nginx のレイヤー 7 機能を使用する人はまだ多くいます。
  • 4層: LVSなどの典型的なもの
  • レイヤー7: 代表的な例としてはNginxやHAProxyなどがある

2. コンテナ化におけるLBの類似点と相違点

コンテナ化以前の物理マシンの時代では、典型的な負荷分散構築計画は、7 層プロキシを提供する Nginx クラスターを構築することでした。 4 層プロキシ ソリューションを提供するために LVS クラスターを構築します。同時に、レイヤー 7 の上には通常レイヤー 4 プロキシがあり、トラフィックの基本的な流れは、クライアント -> LVS (レイヤー 4) -> Nginx (レイヤー 7) -> サーバーです。

物理マシンの時代では、運用および保守担当者は基本的に手動で各サーバーを追加および変更して Nginx のアップストリームを構成し、その構成をオンライン アプリケーションにプッシュしていました。物理マシン時代の従来のメンテナンス方法は、バックエンドサーバーの IP が基本的に固定されていることを前提としています。たとえば、WebServer サービスを起動すると、そのサービスが展開されるマシンが事前に決定され、IP は固定されたままになります。どのようにアップグレードしても、これらのマシンではサービスは固定されたままになります。したがって、この時代のメンテナンス方法にはそれほど多くの問題はなく、これまで誰もが非常に調和的にメンテナンスを行ってきました。

コンテナ化時代において、Kubernetes ベースのコンテナ化プラットフォーム上での LB 構築の違いは何でしょうか?主に 2 つの部分に分かれています。

• バックエンド サービスの IP は、クラスターのスケジュールにより変動します。デプロイ、アップグレードなどを行うたびに、IP は変更されます。現時点では、7 層プロキシを維持するために、元のハードコードされた IP 方式を引き続き使用することはできません。サービス IP が不確実なため、姿勢を変える必要があります。 Nginx のアップストリームのサーバー IP を手動で入力することはできません。動的に取得および変更することしかできません。これには、LB がバックエンド サービスを積極的に検出し、動的に更新することが必要です。

• Kubernetes コンテナ プラットフォームでは、クラスター内のネットワークは仮想化されており、仮想ネットワークの IP はクラスター外部からアクセスできません。したがって、コンテナ クラスターの内外のネットワーク接続の問題も解決する必要があります。

2. コンテナLB負荷分散の構築方法

1. Kubernetes 負荷分散

Kubernetes 自体には、kube-proxy と呼ばれるクラスター内に組み込まれた負荷分散ソリューションがありますが、これは内部からしかアクセスできず、その機能は若干不十分です。実際、ユーザー (クライアント) はすべてクラスターの外部にいるので、コンテナー プラットフォームはクラスターへの外部アクセスを提供する必要があります。

Kubernetes 負荷分散関連のソリューションには以下が含まれます。

  • クラスター内の内部負荷分散 [組み込み]

ポッド IP はクラスター内で相互接続されているため、クラスター内のネットワーク相互接続の問題を考慮する必要はありません。

各ノード上の kube-proxy は、クラスターに組み込まれた内部負荷分散ソリューションです。ただし、クラスターに限定されており、機能も制限されています。

  • クラスター外部負荷分散 [追加]

コミュニティが提供するnginx-ingress-controllerソリューションは、ニーズを満たすことができます。

クラウドプロバイダーもニーズを満たすことができます

nginx-ingress-controller モデルを参照して独自の LB ソリューションを構築します。

このことから、独自の IDC 内でコンテナ LB ソリューションを構築する場合は、独自に構築したソリューションか、nginx-ingress-controller ソリューションに基づくソリューションのみを使用できることがわかります。クラウドに移行する場合は、自分で構築することも、クラウド ベンダーのソリューションを直接使用することもできます。

以下の紹介はすべて、自作のソリューションに基づいて設計されています。 IDC では、K8s コンテナの LB システムを 0 から 1 までどのように構築するのでしょうか?

2. ビジネス要件

ビジネス機能要件とは、コンテナ LB システムを使用する際に、どのように使用するのか、どのような機能が必要なのか、どのようなポリシーが必要なのかなど、ビジネス (開発) 側で何が必要なのかということです。コンテナLB構築の開発者として、ビジネス側の視点で検討できることが必要です。次の図に示すように、次のようなビジネス要件があります。

詳細な手順は次のとおりです。

  • 経験要件

LBグループ化: このビジネスは非常にコアであり、独立したLBクラスタを必要とします。つまり、LBプロキシ層をグループ化する必要があります。

ドメイン名解決ライン: 複数のクラスターと複数の IDC がある場合、サービスによって公開されるドメイン名はどのように解決する必要がありますか?すべての IDC に解決する必要がありますか、それとも特定のクラスターにのみ解決する必要がありますか?

URI書き換えルールや特別な設定のカスタマイズなど、レイヤー7プロキシの高度な設定

ほとんどのユーザー: 企業がサービスを公開するには、簡単な構成と理解のみが必要です。サービス公開の詳細に注意を払う必要も、注意を払うつもりもありません。彼らが望んでいるのは結果だけです。つまり、サービスがデプロイされ、それをクライアントに公開して呼び出せるようにしたいのです。

ニッチユーザー:ビジネスは非常にコアであり、さまざまな不確実性があり、ビジネス開発者は細部に注意を払う必要がある

  • 負荷分散プロキシ層の一般的な機能要件

QPS、遅いリクエスト、エラーの数などを含む SLA をカウントできるようになります。

異常を警告できるようにする

ポーリング、最小接続、ハッシュなどの一般的な負荷分散アルゴリズムをサポートできる必要があります。

負荷分散プロキシ層は、タイムアウトや再試行などの基本的な機能をサポートできる必要があります。

負荷分散プロキシ層は、バックエンドサービスのヘルスチェックもサポートできる必要があります。

基本的なサービス公開: レイヤー 4 およびレイヤー 7 プロキシ ソリューション、レイヤー 7 HTTP および HTTPS、基本的な PATH ルーティングをサポート

ドメイン名: サービスが公開される場合、各サービスには独自のドメイン名が必要です。このドメイン名は、特定のルールに従ってデフォルトで生成される必要があり、カスタム ドメイン名もサポートする必要があります。具体的な選択はビジネスのニーズによって異なります。

内部および外部ネットワークの要件: 一部のサービスは APP によって直接呼び出されるため、外部ネットワークに公開する必要があります。一部のサービスはクラスター内でのみアクセスする必要があるため、内部ネットワークに公開できます。

アップストリーム(バックエンド)サービスの基本戦略

監視と統計

  • 負荷分散プロキシ層の高度なポリシー要件

電流制限戦略: 高可用性サービスに必要な機能。過剰なトラフィックによってバックエンドの過負荷や全体的な障害が発生するのを防ぐために、電流制限は LB プロキシ レイヤーを通じて実行されます。

ヒューズ保護メカニズム:サービスが異常を発見し、電流制限では解決できない場合、他のサービスに影響を与えないように、直接ヒューズ、つまり要求を直接切断できる必要があります。

グレースケールリリース: 新しい機能 (バージョン反復) がリリースされると、最初にグレースケールリリースが必要になり、次に期待どおりかどうかの観察が実行されます。そうなった場合、グレースケールのリリースは継続されます。例外が発生した場合は、直ちにロールバックが必要です

3. 運用および保守要件

私たちが構築したコンテナ LB ソリューションは、最終的には運用・保守担当者に配布され、使用されることになります。運用・保守担当者は、会社全体の交通入口を管理する必要があります。 LBは会社全体の交通の入り口です。また、一般の業務担当者には LB 関連の設定を操作する権限がありません。では、運用・保守の観点から、コンテナ LB にはどのような機能が必要なのでしょうか。次の図に示すように、次のような運用および保守の要件があります。

詳細な手順は次のとおりです。

  • ロードバランサー管理

ロードバランサーの自動スクリプト展開。運用と保守にはロードバランサーの導入が必要なので、分散したコマンドの代わりに、よりインテリジェントな自動スクリプト導入を実現するにはどうすればよいでしょうか。これは、私たちが提供するいくつかの操作手順とサブコマンドに依存し、実装をカプセル化するためにAnsibleを組み合わせています。

ロード バランサを導入した後、国慶節、春節、プロモーション期間など、その後の拡張や縮小が必要になる場合があります。事前に拡張が必要となります。では、どうすれば容量を素早く拡大・縮小できるのでしょうか?どうすればもっと自動化できるでしょうか?これもAnsibleと組み合わせてパッケージ化して実装する必要がある。

ロードバランサーのグループ化では、運用と保守において安定性が最も重要です。オンラインサービスには、重要なサービスと重要でないサービスがあります。一般的に、重要なコア サービスとトラフィックが非常に多いサービスは、物理的な分離と制御のために別々にグループ化する必要があります。

  • 権限制御と監査

権限。一般的に、企業がKubernetesコンテナプラットフォームを構築する場合、管理プラットフォームシステムが用意され、運用保守や開発など、全員が管理プラットフォームを通じて業務を行うことになります。ビジネス サービスの展開、オンラインとオフラインの切り替え、LB の操作と管理など。この場合、権限を制御する必要があります。異なるロールには異なる操作権限があり、誰もが負荷分散構成を操作できないようにします。管理者または運用保守担当者のみが操作できます。

監査: 問題の遡及を容易にするために、すべてのオンライン変更を監査する必要がある

  • ビジネスサービスの構成操作

Nginx ロード バランシングの基本構成テストは、基本テストと異常テストを含め、管理プラットフォームを通じて実装する必要があります。変更はテストに合格した後にのみ行うことができます。

Nginx 負荷分散構成のグレースケールとロールバック メカニズム。グレースケールとは、変更を行う前に、まず 1 つの Nginx ノードをグレースケール化して、完全な変更を行う前に変更に問題がないことを確認する必要があることを意味します。ロールバックとは、グレースケールに問題がある場合、すぐに以前のバージョンにロールバックできる必要があることを意味します。

Nginx 負荷分散構成の基本的な表示と検索。すべての構成のグローバル管理。キーワード検索で構成を素早く見つける

  • 安定性に関する操作(フロー制御)

ビジネスフロー制御: ビジネスフローが大きすぎる場合、バックエンドサービスの飽和を回避するために、実際の状況に応じてフロー制御が実行されます。

グレースケール拡張: ビジネスの更新前にグレースケールの段階的な拡張プロセスが必要です

  • LBシステムとドメイン名管理システムが接続されています

中規模企業や大規模企業では、社内にドメイン名管理システムが導入されます。各サービスには、アクセス用に外部に公開されたドメイン名が与えられます。したがって、ドメイン名管理システムは LB システムに接続およびリンクされ、完全な操作チェーンを形成する必要があります。これにより、ユーザーがサービスを公開する際に、事前にドメイン名を申請する必要はなく、LB システム内で直接申請できるようになります。

4. 基本計画と基本原則

Kubernetes では、バックエンド サービスはすべて Pod の形式になります。 Pod が外部負荷分散を実現できるようにするには、Pod が nginx のアップストリームになる必要があります。 Pod の IP アドレスはいつでも変更される可能性があります。したがって、Pod を動的に検出し、それを nginx のアップストリームとしてレンダリングするには、Nginx コントローラーが必要です。 Nginx-Controller は、Nginx とコントローラー (Pod を検出し、それをアップストリームとしてレンダリングする) を組み合わせたものです。

したがって、これを実現するには、Nginx-Controller コンポーネントを開発する必要があります。では、この Nginx コントローラーの要件は何でしょうか?

A. ク​​ラスターの内部と外部のネットワークは相互に通信できる必要があります。

基本的な要件は次のとおりです。

  • クラスターでは、Nginx-Controllerがトラフィックをポッドに分散できる必要があります。

Nginx-ControllerはKubernetesノードに含める必要があります。つまり、Nginx-ControllerがデプロイされているマシンはKubernetesノードである必要があります。

  • クラスター外では、外部ネットワークリクエストはNginx-Controllerに転送される必要がある。

これには、Nginx-Controller がデプロイされているマシンが外部と通信できる必要があります。最も簡単な方法は、Nginx-Controller をバイナリ形式でデプロイし、Node ホストのネットワークを使用することです。

ノードIPは相互運用可能であるため、ポッドIPのみが相互運用可能ではない。

B. ポッドを動的に検出し、nginx 構成としてレンダリングする

まず、ポッド、サービス、エンドポイント、その他のリソースの変更を監視できる必要があります。これには、K8s API サーバーとのやり取りが必要です。一般的に、Golang言語を使用して実装しているため、公式のクライアント-goに基づいて実装できます。

ここでは、ビジネス構成を容易にし、自動的にレンダリングするために、統一されたテンプレート構成を提供する必要があります。 Nginx-Controller が監視する必要があるビジネス サービス リソースは不明であり、いつでも追加または削除される可能性があるため、それを実装するためのテンプレート メカニズムを用意するのが最適です。 Golang の場合、テンプレートの実装は Golang のテンプレート パッケージを通じてカプセル化でき、テンプレートは現在のサービスおよびエンドポイントと結合されて、対応する nginx 構成をレンダリングします。例えば:

アップストリームテスト- API {
{ { k8sBuildUpstream "default.test-back" "port=8080" "max_fails=3" "fail_timeout=3s" } }

対応するサービスのノードとポートのリストとしてレンダリングされます。

アップストリームテスト- API {
サーバー10.1 .1 .7 : 8080 max_fails = 3 fail_timeout = 3;
サーバー10.1 .1 .9 : 8080 max_fails = 3 fail_timeout = 3;
}

C. グレースケール、フルボリューム、ロールバックメカニズムの実装

Nginx-Controller は nginx 構成を動的にレンダリングできますが、オンライン サービスとして、グレースケール、フル ボリューム、およびロールバック メカニズムを備えている必要があります。

コンテナ LB をグループ化する必要があるため、LB の各グループにも複数の nginx ノードが含まれます。グレースケールとは、構成をリリースするときに、まず 1 つのノードをグレースケールし、このノードが正常であることを確認してから、次の nginx ノードにグレースケールするか、すべての nginx ノードにグレースケールすることを意味します。ロールバックとは、ノードをグレー表示した後に問題が見つかった場合に、このノードの構成をロールバックすることを意味します。

どうやってそれを達成するのでしょうか?グレースケールと完全更新の問題は、2 つの configmap を使用することで解決できます。 configmap-canary はグレースケールの configmap として使用され、注釈はグレースケール化する nginx ノードの IP アドレスをマークするために使用されます。このように、nginx コントローラーは configmap-canary の変更を認識すると、アノテーション内の IP アドレスを通じてこのノードに属しているかどうかを判断します。そうであれば、設定をレンダリングし、それを有効にするために nginx をリロードします。このノードに属していない場合は破棄されます。全額が必要な場合は、次のようになります。

  • まず、configmap-canary のannotation["ip"] フィールドにすべてのフルノードを追加します。 nginx-controller はこのフィールドを読み取り、ip フィールドと一致させ、一致するノードの構成を更新します。
  • その後、完全リリースが成功した場合は、まず configmap-canary の内容を configmap-release に上書きし、次に configmap-canary 内の IP リストをクリアします。これにより、グレースケールと完全リリースのプロセス全体が完了します。

グレースケールのリリース中に例外が見つかり、ロールバックが必要な場合は、configmap-canary の IP リストをクリアするだけです。その後、以前のバージョンにロールバックし、リリース プロセスを再度実行してロールバック操作を完了します。

D. コンテナLBコンポーネント自体の管理と展開

前述のように、コンテナ LB コンポーネント自体 (Nginx-Controller) はバイナリ形式でノード ホストにデプロイする必要があります。常に実行する必要があるこのバイナリ展開プログラムを適切に管理するには、systemd を通じて管理するのが一般的でエレガントな方法です。構成例は次のとおりです。

 [ユニット]
Descriptinotallow = nginx -コントローラーデーモン
ドキュメントを許可しない=/ www / nginx - controller / bin / nginx - controller - h
= nginx.service
欲しいもの= nginx.service

[サービス]
タイプ=シンプル
ExecStart =/ www / nginx -コントローラー/ bin / nginx -コントローラー--slow-start=true --is_dynamic=true ${OPTIONS}
ExecStop =/ bin / kill -SIGTERM $MAINPID
ExecReload =/ bin / kill - HUP $MAINPID
キルシグナル= SIGQUIT
再起動=オン-失敗
再起動秒数= 3

[インストール]
WantedBy =マルチユーザー.target

この設定を /usr/lib/systemd/system/ に置くだけで、systemd が管理できるようになります。

E. 各種統計と監視

Nginx-Controller プロキシ レイヤーに必要な監視には、次のものが含まれます。

  • プロセス監視

プロセスが稼働中かどうか、パニックが発生しているかどうかなど。

  • ログ監視

最初にログを収集し、次にエラー ログを監視する必要があります。 ELKは使用可能

  • 基本的な指標の監視

Nginx-Controllerのいくつかの基本的な指標はPrometheusを使用して監視できます。

例えば、リロード回数、更新回数、更新が失敗したかどうかなど。 。 。

  • LBが配置されているホストのマシンパフォーマンス監視

CPU: アイドル、システム、ユーザー、その他のインジケーター

NIC ソフト割り込み

ネットワーク帯域幅: 受信および送信帯域幅インジケーター、ネットワーク カードのパケット損失インジケーター

メモリ使用量、スワップ使用量

ディスクIO: 読み取りと書き込み

残りのハンドル数

  • LBプロキシ層の基本ビジネス指標モニタリング

サービスレベル保証

エラー統計

レイテンシ統計

ドメイン名ディメンション、パスディメンションなど

3. コンテナ LB エクスペリエンスの最適化 (LB アーキテクチャ製品設計)

1. 初期アーキテクチャ図

K8s ロードバランシングシステムを 0 から 1 に構築するため、早い段階で物理マシンからコンテナに切り替える必要があります。一般的な選択は、プロジェクトが正常に実行できることを保証することです。コンテナ LB の選択は、運用および保守担当者の習慣、許容性、変更の少なさ、および安定性の高さと組み合わされて、アーキテクチャ上のトレードオフが行われます。

コンテナ化以前は、7 層プロキシのアーキテクチャは一般的に、クライアント -> CDN -> LVS -> 物理マシン Nginx -> サーバーでした。

上記の要件を満たすには、コンテナ化の開始時にコンテナ LB が安定していない可能性があり、徐々に転送する必要があります。したがって、全体的なアーキテクチャは、クライアント -> CDN -> LVS -> 物理 LB -> コンテナ LB (Nginx コントローラ) -> POD のようになります。

LVS と Nginx はどちらも高可用性である必要があるため、次のようになります。

  • LVS は高可用性を実現するためにキープアライブ自体を使用しますが、すべてのトラフィックが LVS を通過する必要があるため、LVS は 10G ネットワーク カードで構成する必要があります。
  • Nginx の高可用性と高同時実行性は、Nginx のグループ (複数の Nginx インスタンス) を構築し、それを LVS の下にハングさせてハートビート検出とトラフィック分散を行うことによって実現されます。

LVS 4層プロキシはNginxを検出して高可用性を確保できます

LVS 4層プロキシは4層に基づいてNginxにトラフィックを分散できます

  • コンテナ LB (Nginx-Controller) と Pod のネットワークは相互に通信できる必要があるため、コンテナ LB も Kubernetes クラスター内で同じネットワーク アーキテクチャの下に確立される必要があります。

CalicoはKubernetesコンテナプラットフォームのネットワークとして使用できます

2. 最適なアーキテクチャ図

プロジェクトの後期段階では、コンテナ LB が安定する傾向にあるため、パフォーマンス、コスト、エクスペリエンスの問題を考慮する必要があります。そのためには、アーキテクチャを徐々に進化させる必要があります。

  • まず、物理マシンにNginxが存在すると、追加のリンクが作成されます。

応答時間の増加

構成管理の複雑さの増大

トラブルシューティングのためのリンク分析を追加しました

機械コストの増加

  • 第二に、Nginx-Controllerソリューションのより良い代替手段はnginx-ingress-controllerです。

全体的な最適なアーキテクチャフローは、クライアント -> CDN -> LVS -> Nginx-Ingress-Controller -> Pod です。

Nginx-Ingress-Controller の詳細な紹介については、次の章で分析します。

3. エクスペリエンスの最適化

最適化1: 動的アップストリームを実装して、Nginx Reload によって発生する 502 エラーを削減する

動的アップストリームをサポートする必要があるのはなぜですか?これは、K8s ではサービスの Pod IP が頻繁に変更されるためです。たとえば、アップデートがリリースされるたびに Pod IP が変更され、nginx のアップストリームのサーバーリストが頻繁に変更されることになります。 IP が変更されるたびに nginx をリロードする必要がある場合、同時実行性が高く、オンラインでのトラフィックが多いシナリオでは、長時間接続されたサービスで nginx がリロードされたときに 502 エラーが発生することがよくあります。これは許容できないことであり、ビジネス SLA に大きな影響を与えます。

では、nginx がリロードされたときに、長時間接続されたサービスが 502 を表示することが多いのはなぜでしょうか?これには、nginx がリロード時に古い接続をどのように処理するかを分析することに重点を置く必要があります。明確なプロセスは次のとおりです。

  • 現在の接続がアイドル状態の場合は、直接閉じます
  • 現在の接続がまだアップストリーム応答を待機している場合は、要求処理が完了するか、タイムアウト (proxy_read_timeout) になるまで待機してから閉じます。

このプロセスは短い接続要求に対しては非常に合理的であり、パフォーマンスも非常に正常です。ただし、nginx では接続が長いシナリオでいくつかの問題が発生します。長い接続要求の場合、nginx は最後の要求を処理して応答を返すときに、Connection: keepalive の応答ヘッダーを返します。これにより、時間枠に差が生じます。 nginx が接続を閉じてから Linux カーネルが完全に接続を閉じてクライアントに FIN を送信するまでの期間中、クライアントが高同時実行シナリオにある場合、接続が長いため、この接続を再利用して Nginx への新しいリクエストを開始する可能性が非常に高くなります。このように、Nginx マシンが配置されている Linux カーネルは、閉じられた接続に対する新しい要求を検出すると、直接 RST パケットを返し、クライアントで 502 エラーが発生します。

最適化2: SlowStart機能を実装して、Pod起動の初期段階でのSLAパフォーマンスの低下を軽減する

SlowStart 戦略とは、Pod が初めて起動され、外部にサービスを提供できるようになった後、最初にバッファ時間が与えられることを意味します。このバッファ時間中は、最初に小さなトラフィック要求が提供され、重み付けされた RR アルゴリズムが実行され、トラフィックのごく一部だけが許可されます。このバッファ時間が経過すると、重み付けされていない RR アルゴリズムが開始されます。

一般的に、Pod の準備状況プローブが作業可能であれば、Pod は外部にサービスを提供できると考えられます。ただし、一部の Java サービスでは、Java が Java 仮想マシンを起動し、関連するシステムとコンポーネントを初期化する必要があるため、準備状況プローブが OK になった後でも、すぐには大量のサービスを提供できません。さまざまなメモリ プール、スレッド プール、その他の初期化作業も実行する必要があります。これらの初期化作業には場合によっては少し時間がかかることがあります。あるいは、リクエストが来てから初期化が行われる場合もありますが、初期化に時間がかかるため、準備状況の調査がOKになった後すぐに大量のサービスを提供できず、起動時にサービスが不安定になり、SLAが低下して業務に影響が出る可能性があります。これは、実際の Java プロジェクトから導き出された結論です。 JIT の影響により、低トラフィック時に JIT コンパイルが完了するとバッファ時間が確保され、最終的な効果として SLA を向上できます。現時点では、この機能は実際には回避策です。理論的には、ビジネス当事者によって状況が異なる可能性があるため、ビジネス当事者自身で解決する必要があります。

具体的にどうやって達成するのでしょうか?これには、Kubernetes 独自のメカニズムと組み合わせた包括的な実装が必要です。通常、Kubernetes のサービスは Deployment + Service を通じてデプロイされます。この場合、サービスはデプロイメントのローリング アップデート機能をサポートできます。 MaxSurge (25% など)、MaxUnavailable (25% など)、minReadySeconds (30 秒など)、progressDeadlineSeconds (600 秒など) を構成してローリング戦略を制御することで、各ローリング アップグレード プロセスにおける新旧の Pod の合計数を (1+MaxSurge) * desiredPods 以下とし、使用可能な Pod ノードの数を MaxUnavailable * desiredPods 以上とすることができます。新しく追加された Pod ノードの準備ができたら、使用可能になるまで少なくとも minReadySeconds 待機します。ローリング プロセス全体が progressDeadlineSeconds の 600 秒を超えて停止した場合、失敗と見なされ、古いバージョンがロールバックされます。

このため、SlowStart メカニズムはこの機能を活用できます。 SlowStart 機能がオンになっている場合、Pod ノードが今回のアップデートで新しく起動されたノードであるかどうかが判断されます。新しく起動された Pod ノードの場合、その Pod の重みは事前に設定された比率 (通常は小さい重み) に調整されます。ノードの準備時間が MinReadySeconds を超えると、重みは通常の重み (デフォルト: 100) に復元され、SlowStart スロー スタートが実現されます。このメカニズムの SlowStart 機能によって実装されるスロー スタートは、ビジネス全体のサービス レベルを対象とします。この機能は、ノードが新しいノードであるかどうかを判断するために使用されます。要約すると、満たす必要のある条件は次のとおりです。

 # 1.ノードはデプロイメントリリースサイクル内にある
LatestPod .ReadyStatus .LastTransitionTime + progressDeadlineSeconds > CurTime

# 2.ノードは準備ができているが、minReadySecondsウィンドウを超えていない
CurPod .ReadyStatus .LastTransitionTime + minReadySeconds > CurTime

# 3.現在のノード初期化時間と最新のノード初期化時間の差は、ステップ長の拡張と電流制限を防ぐために、minReadySecondsウィンドウを超えません。
CurPod .InitializedStatus .LastTransitionTime + minReadySeconds > LatestPod .InitializedStatus .LastTransitionTime

新しいノードが追加された場合は、その重みを 100 * slow-start-weight に設定し、LatestPod.ReadyStatus.LastTransitionTime + minReadySeconds + 10s - CurTime 後にデフォルトの重み (重み = 100) を復元するようにサービス レベル トリガーを設定します。

最適化3:LB構成リリースと運用保守ドメイン名管理システムを接続し、サービス公開のプロセスステップを削減

一般的に、インターネット企業の運営・保守には独自のドメイン名管理システムが用いられます。開発者は、船荷証券を通じて運用および保守部門にドメイン名 (イントラネットまたはエクストラネット) をサービスに割り当てるように依頼できます。開発者はドメイン名を取得した後、それを独自のサービスにバインドできます。バインディング プロセスは、サービス公開のプロセスです。サービス公開とは、LB 側で対応するルールを確立し、このドメイン名を通じて対応するサービスにアクセスできるようにすることを意味します。

サービスを公開するプロセスでは、まずドメイン名を取得した後、手動での課金と手動での設定が必要になります。このため、企業が適切なメカニズムと機会を持っている場合は、コンテナ LB サービス公開のプロセスをドメイン名管理システムに接続する必要があります。ビジネスでサービスを公開する必要がある場合、複数のプラットフォームでの操作を通じて完了する必要がなくなります。コンテナ LB の管理プラットフォーム上でサービスを公開するだけで、ドメイン名が内部で自動的に生成またはカスタマイズされ、ドメイン名管理システムに自動的に接続され、正式に有効になって外部にサービスを提供できるようになります。

このような最適化の主な目的は、ユーザーエクスペリエンスを向上させ、中間の手動操作環境を削減し、それによって人件費をさらに削減することです。

最適化4: 物理マシンからNginxを削除してリンクを最適化し、コストを削減する

先ほども述べたように、初期段階では、安定性と移行性を確保するために、物理的な Nginx の存在が依然として必要です。物理 Nginx の主な機能は 2 つあります。

  • まず、コンテナ LB のトラフィックを物理マシンの Nginx レイヤーを通じてグレーアウトし、時間内にロールバックすることができます。
  • 第二に、同社のビジネス サービスの多くは、依然として物理マシン上に展開されます。初期段階では、少数のサービスのみが徐々にコンテナに移行するため、物理マシンの Nginx は引き続き保持する必要があります。

ただし、プロジェクトの後期段階では、コンテナLBは徐々に安定します。現時点では、物理マシンnginxを徐々に除去し、LVSからコンテナLBに直接移動する必要があります。ただし、物理マシンNginxを削除するには、物理​​マシンnginxの構成が手動で構成されており、多くの分化と特性の構成がある可能性があるため、整理するために多くの作業が必要です。

最適化5:nginx-ingress-controllerソリューションを使用して、Nginx構成の介入を減らし、1つのステップで達成する

前述のように、Nginx-ingress-Controllerは、Nginx-Controllerを置き換えるための最良のソリューションとして使用できます。 Nginx-ingress-Controllerの主な目的は、クラスターの内側と外側のアクセス問題を解決できるように、Kubernetesクラスターの外側のKubernetesのサービスによってプロキシによってプロキシによって紹介されるポッドサービスを公開することです。イングレスにより、7層の負荷分散を直接実行し、複雑な構成を減らしながら外部アクセスを実現できます。

したがって、リクエストプロセスはクライアント - > lvs VIP-> ingress -controller-> business podです

特定のnginx-ingress-controllerソリューションについては、以下の最後の説明を参照してください。

4.コンテナLBの開発と設計における重要な考慮事項

コンテナLBの開発と設計に関する中心的な考慮事項は次のとおりです。

詳細な指示は次のとおりです。

1。動的上流の実装をサポート[非常に重要]

K8Sコンテナプラットフォームでは、ビジネスサービスのポッドが動的に変化します。たとえば、ポッドのIPアドレスは、再配置、ローリングアップグレード、または立ち退きと再構築のたびに変更されます。ポッドIPが変更されるたびに、Nginxの上流が変更されたことを意味します。動的上流が実装されていない場合、NginxはPOD IPが変更されるたびに異常なリロード操作を実行する必要があります。大規模なオンラインクラスターでは、ビジネスのQPSリクエストが非常に高い場合、頻繁にnginxリロードすることで、nginxがリロードするとクライアントの長い接続要求が502に表示されます。

したがって、LUAモジュールに基づくような動的上流を実装する限り、バックエンドポッドIPがどのように変化しても、nginxバックエンドのIPはLUA共有メモリとロードバランスを通過するため、Nginxはリロードされず、SLAサービス品質を大幅に改善します。

2。バックエンドポッドの健康チェックをサポートします

ポッド自体については、K8SのKubeletは健康チェックを実行します。では、コンテナLBレベルでPOD(ビジネスサービス)で健康チェックを実行する必要があるのはなぜですか?

  • kubelet自体が失敗し、時間内に異常なポッドを除去できない可能性があるため、kubeletを完全に信頼することはできません
  • ノードノードが異常な場合、kubeletはポッドを利用できないものとしてマークします。これには数秒かかります。

3。スロースタート戦略

NGINXの商用バージョンは、次のように使用できます。

上流のバックエンド{
Server BackEnd1 .example .com slow_start = 30;
サーバーBackEnd2 .example .com ;
}

SlowStart戦略とは、SlowStart戦略で構成されたサーバーの場合、一定量のトラフィック(たとえば、0%-1%)が最初にSlowStartタイム範囲内で与えられ、その後、SlowStartの時間が経過した後にトラフィックの100%が回復することを意味します。

このようにして、SlowStartの時間範囲内で、サーバーはJavaサービスなど、低いトラフィックの下でサービス内のいくつかの最初のものを処理できます。このようにして、スロースタートの時間が経過した後、トラフィックの100%を回復する前にすべてが準備されます。これにより、サービスが外の世界により良い品質を提供できるようになります。

現在、これは商用バージョンの実装であり、オープンソースバージョンを使用できないため、自分で実装する必要があります。 K8S下でのコンテナLBのスロースタート関数の特定の実装については、前の記事の説明を参照してください。

4。検査モジュール

検査モジュールは、コンテナLB専用であるだけでなく、すべてのコンテナ基本モジュールに対応できます。これの目的は、実際の状況を人為的にシミュレートし、検査を通じてコン​​テナLBの各リンクを定期的に確認することです。これは、打ち上げの初期段階で特に重要です。

検査モジュールの実装には、少なくとも以下が含まれます。

  • 検査サービスを切り離す(さまざまな検査モジュールを追加するのに役立つ)
  • 確認する頻度(間隔、再試行)
  • 検出された異常の定義(レイテンシ、エラーなど)
  • 例外処理メカニズム(アラーム、ログ出力など)

検査モジュールは、次の利点を提供します。

  • まず、コンテナLBの問題をタイムリーに発見できることを保証できます。これは、カスタムタスクがコンテナLBの各リンクを検出するために使用されるため、ビジネス自体の前に発見される可能性が高いためです。検査モジュールで問題が発生した場合、処理のために関連する担当者に迅速に警告する必要があります。
  • 次に、コンテナLBの各リンクが検査されるため、検査モジュールに問題がない場合、コンテナLB全体が基本的に正常であり、メンテナンス担当者の信頼性を大幅に高めることができます。

5。NGINXSLA統計モジュール

業界は主にTengineのNGX_HTTP_REQSTAT_MODULEを使用しています。さらに最適化したい場合は、この基準で拡張して、次の機能を追加できます。

  • 遅い要求統計
  • HTTPカスタムエラーコード(6xx 7xxなど)の統計をサポートしています。
  • HTTPステータス統計をカスタマイズします
  • 上流に基づく統計をサポートします

6.パフォーマンスストレステストと最適化

コンテナLBは、最高のパフォーマンスを達成し、最も安定したサービスを提供するために、多くのストレステストと最適化を受ける必要があります。

この記事は、「Allenwu」によって書かれたWeChatパブリックアカウント「バックエンドシステムとアーキテクチャ」から再現されており、次のQRコードを介して従うことができます。

「バックエンドシステムとアーキテクチャ」のパブリックアカウントに連絡して、この記事を再版してください。

<<:  2022 年の DevOps: 成功と課題

>>:  「クラウドネイティブ」Prometheus Pushgetwayの解説と実践的な操作

推薦する

K8sとDockerコンテナ管理プラットフォームをベースにしたMomoのアーキテクチャプラクティス

[51CTO.com からのオリジナル記事] コンテナ クラスター管理システムとコンテナ クラウド ...

SEOチームワークが企業サイトのコンバージョン率を最大化

エンタープライズ Web サイトに携わったり、運営したりしたことがある SEO 担当者や Web マ...

採用ウェブサイトは卒業生にサービスを提供するためにU-Mail電子メールマーケティングプラットフォームを使用しています

2018年最もホットなプロジェクト:テレマーケティングロボットがあなたの参加を待っています暑い7月は...

errantweb-2g メモリ VPS (vz)/1g メモリ (KVM) 月額 6 ドル

errantwebは2017年1月に設立されました。価格が安く、リソースが豊富です。データセンターは...

Linux ホスト/サーバーに PPTP をインストールして展開する方法

2018年最もホットなプロジェクト:テレマーケティングロボットがあなたの参加を待っていますサーバーに...

ウェブサイトの内部リンクの最適化に関するこれらの詳細に気づきましたか?

以前の記事のいくつかで、著者はサイトの重さに影響を与えるいくつかの要因について簡単に触れました。内部...

過去からの教訓:「組み合わせ」で構築されるSEO

初めてウェブサイトを作りました。最初の記事を書いてから、もう3ヶ月近くになります。苦労や苦労も感じて...

SEOは何も考えずに想像することを拒否し、データに基づいて話す必要があります

SEO に取り組む時間が長くなればなるほど、SEO について学ぶ価値のあることがさらに増えることに気...

テンセントゲームズブランドのアップグレード:ゲームコンセプトの革命

テンセントではゲームに関する概念革命が起こっている。 11月21日、テンセントゲームズは新しいブラン...

郡レベルのポータル: インターネットで採掘される次の金鉱

ポータル Web サイトとは何ですか? 郡レベルのポータルを構築する理由は何ですか?ポータルサイトと...

百度とパーフェクトワールドが中国サイト「宗衡」の買収を協議中と報道

信頼できる業界関係者によると、百度はパーフェクトワールドと中衡中国網の買収について協議している。両者...

ゲームウェブサイト向け百度百科事典プロモーションの実績

SEO やオンライン マーケティングはますます難しくなってきているとよく聞きます。実際、インターネッ...

ウェブサイトはサイト内でのキーワードの競合を避けるべきである

ウェブマスターや SEO 担当者とのコミュニケーションの中で、次のような誤解がよく見られます。同じキ...

百度の衰退から立ち直る方法

前回、「今回のアップデート後の百度の衰退と回復方法について」についてお話ししました。今回は、百度の衰...

デザイン思考: ユーザーのニーズを満たすことだけを考えるのではなく

[編集者注] この記事の著者は @一只土贼 です。デザイン思考はデザインコンセプトです。その焦点はも...