あなたは最新の Platform Ops または DevOps エンジニアです。 オープンソース (および場合によっては商用) ツールのライブラリを使用して、開発チームの新しいアプリとコンテナをテスト、展開、管理します。 開発、テスト、ステージング、本番環境でこれらのコンテナとポッドを実行するために Kubernetes を選択しました。 マイクロサービスのアーキテクチャと概念を導入し、ほとんどの場合、うまく機能しています。 しかし、この旅の途中でいくつかの障害に遭遇しました。
たとえば、新しいクラスター、サービス、アプリケーションを構築して展開する場合、トラフィックを落とさずにこれらの新しいリソースを簡単に本番環境に統合または移行するにはどうすればよいでしょうか。 従来のネットワーク アプライアンスでは、DNS レコード、ロード バランサー、ファイアウォール、プロキシの構成変更を実装するときに、再ロードまたは再起動が必要になります。 DNS、ロード バランサ、ファイアウォール ルールを更新するには「サービス停止」または「メンテナンス ウィンドウ」が必要になるため、これらの調整はダウンタイムを発生させずに再構成することはできません。 多くの場合、面倒なサービス チケットを送信し、別のチームが承認して変更を加えるまで待たなければなりません。
メンテナンス ウィンドウにより、チームが行き詰まったり、アプリケーションの配信が滞ったりして、「トラフィックを管理するにはもっと良い方法があるはずだ!」と言わざるを得なくなる可能性があります。 それでは、高速道路に戻るための解決策を検討してみましょう。
複数の Kubernetes クラスターがある場合は、トラフィックを両方のクラスターに同時にルーティングするのが理想的です。 さらに良い選択肢は、A/B、カナリア、またはブルーグリーンのトラフィック分割を実行し、トラフィックのごく一部をテストとして送信することです。 これを行うには、 ngx_http_split_clients_module
とともに NGINX Plus を使用します。
HTTP Split Clients モジュールはNGINX Open Source によって作成されており、キーに基づいてリクエストの比率を分散できます。 このユースケースでは、クラスターは NGINX の「上流」です。そのため、クライアントのリクエストが到着すると、トラフィックは 2 つのクラスターに分割されます。 クライアント要求を決定するために使用されるキーは、利用可能な NGINX クライアント$variable
です。 ただし、すべてのリクエストに対してこれを制御するには、 $request_id
変数を使用します。これは、NGINX によってすべての受信リクエストに割り当てられる一意の番号です。
分割比率を構成するには、各クラスターに割り当てる割合を決定します。 この例では、 K8s Cluster1 を本番環境用の「大規模クラスター」として使用し、 Cluster2 を本番環境前のテスト用の「小規模クラスター」として使用します。 ステージング用の小さなクラスターがある場合は、90:10 の比率を使用して、トラフィックの 10% を小さなクラスターでテストし、新しい変更を大きなクラスターに展開する前にすべてが機能していることを確認できます。 リスクが高すぎると思われる場合は、比率を 95:5 に変更できます。 実のところ、0 ~ 100% の間で任意の比率を選択できます。
ほとんどのリアルタイムの本番トラフィックでは、2 つのクラスターのサイズが同じである 50:50 の比率が望ましいでしょう。 ただし、クラスターのサイズやその他の詳細に基づいて、他の比率を簡単に提供できます。 比率を 0:100 (または 100:0) に簡単に設定でき、ダウンタイムなしでクラスター全体をアップグレード、パッチ適用、修復、さらには交換することもできます。 NGINX split_clients が
リクエストをライブ クラスターにルーティングし、一方で問題に対処できるようにします。
# Nginx マルチ クラスター ロード バランシング
# Cluster1:Cluster2 比率の HTTP 分割クライアント構成
# 100、99、50、1、0% の比率を指定します (必要に応じて追加/変更)
# ベース:
# https://www.nginx.com/blog/dynamic-a-b-testing-with-nginx-plus/
# Chris Akker – 2024 年 1 月
#
split_clients $request_id $split100 {
* cluster1-cafe; # すべてのトラフィックを cluster1 へ
}
split_clients $request_id $split99 {
99% cluster1-cafe; # 99% cluster1、1% cluster2
* cluster2-cafe;
}
split_clients $request_id $split50 {
50% cluster1-cafe; # 50% cluster1、50% cluster2
* cluster2-cafe;
}
split_clients $request_id $split1 {
1.0% cluster1-cafe; # 1% を cluster1 に、99% を cluster2 に
* cluster2-cafe;
}
split_clients $request_id $split0 {
* cluster2-cafe; # すべてのトラフィックを cluster2 に
}
# 比率に基づいてアップストリームのクラスターを選択
map $split_level $upstream {
100 $split100;
99 $split99;
50 $split50;
1.0 $split1;
0 $split0;
default $split50;
}
必要な比率 (例: 90:10、80:20、60:40 など) に合わせて上記の構成を追加または編集できます。
注記: NGINX には、ストリーム コンテキストでの TCP 接続用のSplit Clients モジュール
もあり、これは HTTP 以外のトラフィックにも使用できます。 これにより、HTTP リクエストではなく、新しい TCP 接続に基づいてトラフィックが分割されます。
次に使用できる機能は、NGINX Plusキー値ストアです。 これは、さまざまなデータ ストレージのユース ケースに使用できる NGINX 共有メモリ ゾーン内のキー値オブジェクトです。 ここでは、上のセクションで説明した分割比率の値を保存するために使用します。 NGINX Plus を使用すると、NGINX をリロードせずに任意のキー値レコードを変更できます。これにより、API 呼び出しでこの分割値を変更し、動的な分割関数を作成できます。
私たちの例に基づくと、次のようになります。
{“cafe.example.com”:90}
この KeyVal レコードの内容は次のとおりです。
キーは「cafe.example.com」ホスト名です
分割比率の値は「90」です
NGINX 構成ファイルに分割比率をハードコーディングする代わりに、キー値メモリを使用できます。 これにより、NGINX で静的分割値を変更するために必要な NGINX のリロードが不要になります。
この例では、NGINX は、90% を大きなCluster1で、残りの 10% を小さなCluster2で分割比率として 90:10 を使用するように構成されています。 これはキー値レコードなので、設定を再読み込みすることなく、NGINX Plus API を使用してこの比率を動的に変更できます。 Split Clients モジュールは、比率の値を変更するとすぐに、次のリクエストでこの新しい比率の値を使用します。
KV レコードを作成し、50/50 の比率から始めます。
NGINX Plus に API コマンドを送信して、KeyValue ストアに新しいレコードを追加します。
curl -iX POST -d '{"cafe.example.com":50}' http://nginxlb:9000/api/8/http/keyvals/split
KV レコードを変更し、90/10 比率に変更します。
HTTP PATCH メソッドを使用してメモリ内の KeyVal レコードを更新し、KeyVal 分割比率を 90 に変更します。
curl -iX PATCH -d '{"cafe.example.com":90}' http://nginxlb:9000/api/8/http/keyvals/split
次に、実稼働前テスト チームが新しいアプリケーション コードの準備が整っていることを確認し、それを大規模なCluster1にデプロイして、比率を 100% に変更します。 これにより、すべてのトラフィックが直ちにCluster1に送信され、トラフィックの中断、サービスの停止、メンテナンス ウィンドウ、再起動、再ロード、大量のチケットが発生することなく、新しいアプリケーションが「ライブ」になります。 選択した時点でこの分割比率を変更するには、1 回の API 呼び出しだけが必要です。
もちろん、90% から 100% に簡単に変更できるということは、比率を 100:0 から 50:50 (または 0:100) に簡単に変更できることを意味します。 したがって、ホット バックアップ クラスターを用意したり、新しいリソースを使用してクラスターを水平方向に拡張したりできます。 フルスロットルで、最新のソフトウェア、ハードウェア、ソフトウェア パッチを使用して新しいクラスターを完全に構築し、アプリケーションを展開して、一定期間にわたって接続を 1 つも切断することなくトラフィックを移行することもできます。
動的キー値ストアで HTTP分割クライアント モジュールを使用すると、次のユースケースを実現できます。
キーと値の構成の例を次に示します。
# キー値ストア、バックアップ状態ファイル、タイムアウトを定義し、同期を有効にします
keyval_zone zone=split:1m state=/var/lib/nginx/state/split.keyval timeout=365d sync;
keyval $host $split_level zone=split;
これは cafe.example.com アプリケーション構成の例です。
# TLS を使用して、cafe.example.com のサーバーとロケーション ブロックを定義します。 server { listen 443 ssl; server_name cafe.example.com; status_zone https://cafe.example.com; ssl_certificate /etc/ssl/nginx/cafe.example.com.crt; ssl_certificate_key /etc/ssl/nginx/cafe.example.com.key; location / { status_zone /; proxy_set_header Host $host; proxy_http_version 1.1; proxy_set_header "Connection" ""; proxy_pass https://$upstream; # トラフィックはアップストリーム ブロックに分割されます } # クラスターごとに 1 つずつ、2 つのアップストリーム ブロックを定義します。 # サーバーは NLK によって動的に管理され、状態ファイルのバックアップが作成されます。 # Cluster1 アップストリーム upstream cluster1-cafe { zone cluster1-cafe 256k; least_time last_byte; keepalive 16; #NLK コントローラーによって管理されるサーバー state /var/lib/nginx/state/cluster1-cafe.state; } # Cluster2 アップストリーム upstream cluster2-cafe { zone cluster2-cafe 256k; least_time last_byte; keepalive 16; #NLK コントローラーによって管理されるサーバー state /var/lib/nginx/state/cluster2-cafe.state; }
アップストリーム サーバーの IP:ポートは、 NGINX Loadbalancer for Kubernetesによって管理されます。これは、NGINX Plus API を使用して NGINX Plus を動的に構成する新しいコントローラーです。 詳細は、次のセクションをご覧ください。
人気の監視および視覚化ツールであるGrafanaを使用して、時間の経過に伴う HTTP 分割トラフィックを見てみましょう。 NGINX Prometheus Exporter ( njsベース) を使用してすべての NGINX Plus メトリックをエクスポートし、Grafana によって収集およびグラフ化します。 Prometheus と Grafana の設定の詳細については、こちらをご覧ください。
グラフには 4 つのアップストリーム サーバーがあります。 Cluster1用に 2 つ、 Cluster2用に 2 つ。 HTTP 負荷生成ツールを使用して HTTP リクエストを作成し、NGINX Plus に送信します。
以下の 3 つのグラフでは、グラフの先頭で分割比率が 50:50 であることがわかります。
そして、12:56:30に比率は10:90に変わります。
その後、13:00:00に90:10に変わります。
Prometheus と Grafana の動作構成は、NGINX Loadbalancer for Kubernetes GitHub リポジトリで確認できます。
NGINX Plus API とNGINX Loadbalancer for Kubernetesコントローラーを使用して、静的 NGINX Upstream 構成を動的クラスター アップストリームに変更できます。 この無料プロジェクトは、 NGINX Ingress Controller を監視し、TCP/HTTP ロード バランシング用に構成された外部NGINX Plusインスタンスを自動的に更新するKubernetes コントローラーです。 デザインが非常にシンプルで、インストールと操作も簡単です。 このソリューションを導入すると、Kubernetes 環境で TCP/HTTP 負荷分散を実装できるため、リロードを必要とせずに、新しいアプリやサービスがすぐに検出され、トラフィックで利用できるようになります。
NGINX Loadbalancer for Kubernetes は Kubernetes クラスター内に配置されます。 NGINX Ingress Controller ( nginx-ingress
) サービスを監視するために Kubernetes に登録されます。 Ingress コントローラーに変更があると、NGINX Loadbalancer for Kubernetes は Worker Ips と NodePort TCP ポート番号を収集し、IP:ポートをNGINX Plus API経由で NGINX Plus に送信します。
NGINX アップストリーム サーバーはリロードを必要とせずに更新され、NGINX Plus はトラフィックを適切なアップストリーム サーバーと Kubernetes NodePort に負荷分散します。 高可用性を実現するために、追加の NGINX Plus インスタンスを追加できます。
以下のスクリーンショットには、NGINX Loadbalancer for Kubernetes がデプロイされ、その機能を実行していることを示す 2 つのウィンドウがあります。
nginx-ingress
のLoadBalancer
注記: この例では、Kubernetesワーカーノードは10.1.1.8と10.1.1.10です。
Kubernetes で実行されるアプリケーションがオープンインターネットに公開されるケースが増えるにつれて、セキュリティが必要になります。 幸いなことに、NGINX Plus には、階層化された多層防御アーキテクチャを作成するために使用できるエンタープライズ クラスのセキュリティ機能があります。
NGINX Plus をクラスターの前に配置してsplit_clients
関数を実行することで、その存在を活用して有益なセキュリティ機能を追加してみませんか? ここでは、セキュリティを強化するために使用できる NGINX Plus の機能のいくつかと、それらの設定、テスト、展開に使用できる他のドキュメントへのリンクと参照を示します。
Kubernetes クラスターのエッジでのネットワークの課題に悩まされている場合は、この NGINX マルチクラスター ソリューションを試してみることを検討してください。 NGINX Loadbalancer for Kubernetes ソフトウェアを試用して、ご感想をお聞かせください。 ソースコードはオープンソース(Apache 2.0 ライセンス)であり、すべてのインストール手順はGitHub で入手できます。
フィードバックを提供するには、リポジトリにコメントを残すか、 NGINX コミュニティ Slackでメッセージを送信してください。
「このブログ投稿には、入手できなくなった製品やサポートされなくなった製品が参照されている場合があります。 利用可能な F5 NGINX 製品およびソリューションに関する最新情報については、 NGINX 製品ファミリーをご覧ください。 NGINX は現在 F5 の一部です。 以前の NGINX.com リンクはすべて、F5.com の同様の NGINX コンテンツにリダイレクトされます。"