ブログ | NGINX

NGINX チュートリアル: 自動スケーリングでKubernetesのレイテンシを削減

NGINX-F5 水平黒タイプ RGB の一部
ダニエレ・ポレンチッチ サムネイル
ダニエレ・ポレンチッチ
2022年3月15日公開

このチュートリアルは、2022 年 3 月の Microservices の概念を実践する 4 つのチュートリアルのうちの 1 つです。 Kubernetes ネットワーキング:

さらに多くの Kubernetes ネットワークユースケースで NGINX を使用するための詳細なガイダンスが必要ですか? 無料の電子書籍「NGINX を使用した Kubernetes トラフィックの管理」をダウンロードしてください。 実用ガイド

あなたの組織は Kubernetes でアプリを構築し、それが人気を集めています。 1 日あたりの訪問者数が数人から数百人 (場合によっては数千人) に増加しました。 しかし、問題があります...トラフィックの増加によりボトルネックが発生し、顧客に対して遅延やタイムアウトが発生します。 エクスペリエンスを改善できなければ、人々はアプリの使用をやめてしまいます。

勇敢な Kubernetes エンジニアであるあなたには解決策があります。 トラフィックをルーティングするために Ingress コントローラをデプロイし、トラフィックの変動に合わせて Ingress コントローラ ポッドの数が瞬時に拡大および縮小されるように自動スケーリング ポリシーを設定します。 これで、Ingress コントローラー ポッドはトラフィックの急増をシームレスに処理し (「レイテンシーとはおさらばです!」)、トラフィックが減少するとスケールダウンしてリソースを節約し (「コスト削減」を実現) ます。 よくやった、君。

ラボとチュートリアルの概要

このブログは、マイクロサービス2022 年 3 月のユニット 1 「高トラフィックの Web サイト向けの Kubernetes クラスターの設計」のラボに付随するもので、NGINX Ingress Controller を使用してアプリを公開し、高トラフィックに応じて Ingress コントローラー ポッドを自動スケーリングする方法を示します。

チュートリアルを実行するには、次の条件を満たすマシンが必要です。

  • 2CPU以上
  • 2 GBの空きメモリ
  • 20 GB の空きディスク容量
  • インターネット接続
  • Docker、Hyperkit、Hyper‑V、KVM、Parallels、Podman、VirtualBox、VMware Fusion/Workstation などのコンテナまたは仮想マシン マネージャー
  • minikubeがインストールされている
  • Helmがインストールされました
  • ブラウザ ウィンドウを起動できるようにする構成。 それが不可能な場合は、ブラウザ経由で関連サービスにアクセスする方法を検討する必要があります。

ラボとチュートリアルを最大限に活用するには、開始する前に次のことを実行することをお勧めします。

このチュートリアルでは次のテクノロジを使用します。

各チャレンジの手順には、アプリを構成するために使用される YAML ファイルの完全なテキストが含まれています。 GitHub リポジトリからテキストをコピーすることもできます。 各 YAML ファイルのテキストとともに GitHub へのリンクが提供されます。

このチュートリアルには 4 つの課題が含まれています。

  1. Kubernetes クラスター上でシンプルなアプリを構成する
  2. NGINX Ingress Controller を使用してトラフィックをアプリにルーティングする
  3. トラフィックの生成と監視
  4. NGINX Ingress コントローラーの自動スケール

課題1: Kubernetes クラスター上でシンプルなアプリを構成する

このチャレンジでは、 minikube クラスターを作成し、サンプル アプリとしてPodinfo をインストールします

Minikube クラスターを作成する

minikubeクラスターを作成します。 数秒後、デプロイメントが成功したことを確認するメッセージが表示されます。

$ minikube start 🏄 完了!kubectl はデフォルトで「minikube」クラスターと「default」名前空間を使用するように設定されました 

Podinfoアプリをインストールする

Podinfo は、 「Kubernetes でマイクロサービスを実行するためのベスト プラクティスを紹介する、Go で作成された Web アプリケーション」です。 フットプリントが小さいため、サンプル アプリとして使用しています。

  1. 任意のテキスト エディターを使用して、次の内容を含む1-deployment.yamlという YAML ファイルを作成します (またはGitHub からコピーします)。 単一のレプリカとサービスを持つデプロイメントを定義します。

    apiバージョン: apps/v1 種類: デプロイメント 
    メタデータ: 
    名前: podinfo 
    仕様: 
    セレクタ: 
    matchLabels: 
    アプリ: podinfo 
    テンプレート: 
    メタデータ: 
    ラベル: 
    アプリ: podinfo 
    仕様: 
    コンテナ: 
    -名前: podinfo 
    イメージ: stefanprodan/podinfo 
    ポート: 
    -コンテナポート: 9898 
    --- 
    apiバージョン: v1 
    種類: サービス 
    メタデータ: 
    名前: podinfo 
    仕様: 
    ポート: 
    - ポート: 80 
    ターゲットポート: 9898 
    ノードポート: 30001 
    セレクタ: 
    アプリ: podinfo 
    タイプ: ロードバランサー 
    
  2. アプリをデプロイします。

    $ kubectl apply -f 1-deployment.yamlデプロイメント.apps/podinfo が作成されました サービス/podinfo が作成されました
    
  3. STATUS列の値が Running であることで示されるように、Podinfo ポッドがデプロイされていることを確認します。

    $ kubectl get pods NAME READY STATUS RESTARTS AGE podinfo-5d76864686-rd2s5 1/1 実行中 0 3分38秒
    
  4. ブラウザで Podinfo を開きます。 podinfo ページからの挨拶は、 Podinfo が実行中であることを示します。

    $ minikubeサービスpodinfo
    

チャレンジ2: NGINX Ingress Controller を使用してトラフィックをアプリにルーティングする

このチャレンジでは、 NGINX Ingress Controller をデプロイしトラフィックを Podinfo アプリにルーティングするように設定します。

NGINX Ingress Controller をデプロイする

NGINX Ingress Controller をインストールする最も速い方法は、 Helmを使用することです。

  1. NGINX リポジトリを Helm に追加します。

    $ helm リポジトリに nginx-stable を追加します https://helm.nginx.com/stable 
    
  2. F5 NGINX によって管理されている NGINX オープンソースベースのNGINX Ingress Controllerをダウンロードしてインストールします。出力の最後の行でインストールが成功したことが確認できます。

    $ helm install main nginx-stable/nginx-ingress \ --set controller.watchIngressWithoutClass=true \ --set controller.service.type=NodePort \ --set controller.service.httpPort.nodePort=30005名前: main 最終デプロイ日: 2022年3月15日火曜日 09:49:17 名前空間: デフォルト ステータス: デプロイ済み リビジョン: 1 テストスイート: なし 注記: NGINX Ingress Controller がインストールされました。
    
  3. STATUS列の値がRunning であることで示されるように、NGINX Ingress Controller ポッドがデプロイされていることを確認します (読みやすくするために、出力は 2 行に分かれています)。

    $ kubectl get pods NAME READY STATUS ... main-nginx-ingress-779b74bb8b-mtdkr 1/1 実行中 ... podinfo-5d76864686-fjncl 1/1 実行中 ... ... 年齢をリスタート... 0 18秒... 0 2分36秒
    

アプリへのトラフィックをルーティングする

  1. 任意のテキスト エディターを使用して、次の内容を含む2-ingress.yamlという YAML ファイルを作成します (またはGitHub からコピーします)。 トラフィックを Podinfo にルーティングするために必要な Ingress マニフェストを定義します。

    apiバージョン: networking.k8s.io/v1 種類: Ingress 
    メタデータ: 
    名前: podinfo 
    仕様: 
    ingressClassName: nginx 
    ルール: 
    - ホスト: "example.com" 
    http: 
    パス: 
    - バックエンド: 
    サービス: 
    名前: podinfo 
    ポート: 
    番号: 80 
    パス: / 
    パスタイプ: プレフィックス 
    
  2. Ingress リソースをデプロイします。

    $ kubectl apply -f 2-ingress.yaml ingress.networking.k8s.io/podinfo が作成されました 
    

課題3: トラフィックの生成と監視

このチャレンジでは、さまざまなトラフィック負荷下での NGINX Ingress Controller のパフォーマンスを観察します。 準備手順として、NGINX Ingress Controller から利用可能なメトリックをリストしPrometheus をデプロイしLocust をインストールします。 次に、Locust を使用してトラフィックの急増をシミュレートし、Prometheus のパフォーマンスへの影響を追跡します

すでにおわかりのように、Ingress コントローラーは、Kubernetes との統合のためのコードとリバース プロキシ (この場合は NGINX) をバンドルした通常の Kubernetes ポッドです。 アプリが大量のトラフィックを受信する場合は、NGINX Ingress Controller が過負荷になったときに発生する遅延を回避するために、NGINX Ingress Controller ポッドレプリカの数を増やす必要がある可能性があります。

利用可能なメトリックの一覧

いつ、どの程度スケールするかを知るには、NGINX Ingress Controller のパフォーマンスに関する正確な情報が必要です。 このチュートリアルでは、スケーリングするタイミングを決定するために使用される NGINX メトリックは、アクティブな接続の数 ( nginx_connections_active ) です。 ここで、NGINX Ingress Controller がそのメトリックを追跡していることを確認します。

NGINX Ingress Controller は複数のメトリックを公開します。 このチュートリアルで使用している NGINX オープンソース ベースのモデルでは 8 つのメトリック、 NGINX Plus ベースのモデルでは 80 を超えるメトリックがあります。

  1. NGINX Ingress Controller ポッドの IP アドレスを取得して、メトリックのリストを照会できるようにします。 アドレスはIPフィールドに表示されます。172.17.0.4 。 (読みやすくするために、 RESTARTS列とAGE列は省略され、出力は 2 行に分かれています。)

    $ kubectl get pods -o wide NAME READY STATUS ... main-nginx-ingress-779b74bb8b-6hdwx 1/1 実行中 ... podinfo-5d76864686-nl8ws 1/1 実行中 ... ... IP ノード指名ノード準備ゲート...172.17.0.4 minikube <なし> <なし> ... 172.17.0.3 minikube <なし> <なし>
    
  2. Kubernetes クラスター内のホスト上にシェルを備えた一時的なBusyBoxポッドを作成します。

    $ kubectl run -ti --rm=true busybox --image=busyboxコマンドプロンプトが表示されない場合は、Enterキーを押してみてください。 / # 
    
  3. NGINX Ingress Controller によって生成されたメトリックを一覧表示し、 nginx_connections_activeが含まれていることを確認します。 のために <IP アドレス> 手順 1 の値を代入します。

    /# wget -qO- <IP アドレス>:9113/メトリクス
    
  4. シェルを終了して Kubernetes サーバーに戻ります。

    /#出口 
    

Prometheusをデプロイする

NGINX Ingress Controller がnginx_connections_activeメトリックを追跡していることがわかったので、メトリックを収集 (「スクレイピング」) するためのツールが必要です。このチュートリアルではPrometheus を使用します。

NGINX Ingress Controller に関しては、 Helm がPrometheus をインストールする最も速い方法です。

  1. Prometheus リポジトリを Helm に追加します。

    $ helm リポジトリに prometheus-community を追加します https://prometheus-community.github.io/helm-charts
    
  2. Prometheus をダウンロードしてインストールします。

    $ helm install prometheus prometheus-community/prometheus \ --set server.service.type=NodePort --set server.service.nodePort=30010
    
  3. インストールを確認します。完了するまでに通常 60 秒ほどかかります。 次のサンプル出力では、検証コマンドがhelm installコマンドのわずか数秒後に実行されたため、インストールが進行中であり、一部の Prometheus ポッドのSTATUSフィールドにContainerCreating が報告されています。 すべてのポッドのステータスがRunning になったら、インストールは完了です。 (読みやすくするために、出力は 2 行に分かれています。)

    $ kubectl get pods NAME READY ... main-nginx-ingress-779b74bb8b-mtdkr 1/1 ... podinfo-5d76864686-fjncl 1/1 ... prometheus-alertmanager-d6d94cf4b-85ww5 0/2 ... prometheus-kube-state-metrics-7cd8f95cb-86hhs 0/1 ... prometheus-node-exporter-gqxfz 1/1 ... prometheus-pushgateway-56745d8d8b-qnwcb 0/1 ... prometheus-server-b78c9449f-kwhzp 0/2 ... ... ステータスが年齢を再開します... ランニング 0 3分23秒... ランニング 0 5分41秒... コンテナを作成しています 0 7秒... 0 7秒で走っています... 0 7秒で走っています... コンテナを作成しています 0 7 秒... コンテナ作成 0 7秒
    
  4. Prometheus を開きます。 minikube 環境で次のコマンドを実行すると、デフォルトのブラウザで Prometheus ダッシュボードが開きます。

    $ minikubeサービスprometheus-server
    

    次のようなページが表示されれば、サーバーが動作していることが確認できます。

  5. アクティブ接続メトリックの現在の値を表示するには、検索バーに「nginx_ingress_nginx_connections_active」と入力します。 アクティブな接続が 1 つ表示されます。これは、NGINX Ingress Controller ポッドを 1 つデプロイしているためです。

Locustをインストールする

次のセクションでは、オープンソースの負荷テスト ツールであるLocust を使用してトラフィックの急増をシミュレートし、Prometheus で NGINX Ingress Controller のパフォーマンスを確認します。 ここで Locust を展開します。

  1. 任意のテキスト エディターを使用して、次の内容を含む3-locust.yamlという YAML ファイルを作成します (またはGitHub からコピーします)。 Deployment オブジェクトと Service オブジェクトは Locust ポッドを定義します。 ConfigMap オブジェクトは、正しいヘッダーを備えたポッドに送信されるリクエストを生成するlocustfile.pyというスクリプトを定義します。

    apiバージョン: v1 
    種類: ConfigMap 
    メタデータ: 
    名前: locust-script 
    データ: 
    locustfile.py: |- 
    locust から HttpUser、task、between をインポート
    
    クラス QuickstartUser(HttpUser): 
    wait_time = between(0.7, 1.3) 
    
    @task 
    def hello_world(self): 
    self.client.get("/", headers={"Host": "example.com"}) 
    --- 
    apiVersion: apps/v1 
    kind: デプロイメント 
    メタデータ: 
    名前: locust 
    仕様: 
    セレクタ: 
    matchLabels: 
    アプリ: locust 
    テンプレート: 
    メタデータ: 
    ラベル: 
    アプリ: locust 
    仕様: 
    コンテナ: 
    -名前: locust 
    イメージ: locustio/locust 
    ポート: 
    -コンテナポート: 8089 
    ボリュームマウント: 
    - マウントパス: /home/locust 
    名前: locust-script 
    ボリューム: 
    - 名前: locust-script 
    configMap: 
    名前: locust-script 
    --- 
    apiVersion: v1 
    種類: サービス 
    メタデータ: 
    名前: locust 
    仕様: 
    ポート: 
    - ポート: 8089 
    ターゲットポート: 8089 
    ノードポート: 30015 
    セレクタ: 
    アプリ: locust 
    タイプ: ロードバランサー 
    
  2. ローカストを展開:

    $ kubectl apply -f 3-locust.yaml configmap/locust-script が作成されました。deployment.apps/locust が作成されました。service/locust が作成されました。 
    

トラフィックの急増をシミュレートし、パフォーマンスへの影響を観察する

  1. ブラウザで Locust を開きます。

    $ minikube サービス イナゴ
    

  2. フィールドに次の値を入力します。

    • ユーザー数– 1000
    • 出現率– 10
    • ホスト– http://main-nginx-ingress
  3. 「スウォーミングの開始」ボタンをクリックして、トラフィックを Podinfo アプリに送信します。

  4. Prometheus ダッシュボードに戻り、NGINX Ingress Controller がどのように応答するかを確認します。 変更を確認するには、 nginx_ingress_nginx_connections_activeに対して新しいクエリを実行する必要がある場合があります。

    次の画面出力に示されているように、多数の接続が確立されると、単一の NGINX Ingress Controller ポッドは、遅延なしで増加したトラフィックを処理するのに苦労します。 Prometheus グラフは、NGINX Ingress Controller ポッドあたり約 100 のアクティブ接続がレイテンシの急上昇の転換点であることを明らかにしています。 この情報を使用して、レイテンシの増加を回避するために NGINX Ingress Controller ポッドの数を増やす必要があるタイミングを判断できます。

課題4: NGINX Ingress コントローラーの自動スケール

最後の課題では、トラフィック量の増加に応じてリソースを自動スケーリングする構成を構築します。 このチュートリアルでは自動スケーリングに KEDA を使用するため、まずKEDA をインストールし、スケーリングがいつどのように行われるかを定義するポリシーを作成します。 チャレンジ 3 と同様に、Locust を使用してトラフィックの急増をシミュレートし、Prometheus を使用して、自動スケーリングが有効になっているときの NGINX Ingress Controller のパフォーマンスを観察します。

KEDAをインストールする

Kubernetes イベント駆動型オートスケーラーであるKEDA は、メトリック サーバー (Kubernetes のメトリックを保存および変換するコンポーネント) を統合し、Prometheus (およびその他のツール) から直接メトリックを消費できます。 これらのメトリックを使用してHorizontal Pod Autoscaler (HPA) を作成し、Prometheus によって収集されたメトリックをブリッジして、Kubernetes にフィードします。

NGINX Ingress Controller および Prometheus と同様に、チュートリアルでは Helm を使用して KEDA をインストールします。

  1. KEDA を Helm リポジトリに追加します。

    $ helm repo add kedacore https://kedacore.github.io/charts 「kedacore」がリポジトリに追加されました 
    
  2. KEDA をインストールします。

    $ helm install keda kedacore/keda NAME: keda NAMESPACE: default STATUS: deployed REVISION: 1 テストスイート: なし
    
  3. KEDA が 2 つのポッドとして実行されていることを確認します。 (読みやすさを考慮して、 NAME列の一部の値は短縮されています。 また、 RESTARTS列は省略されており、値は0すべてのポッドに対して。

    $ kubectl get pods NAME READY STATUS AGE keda-operator-8644dcdb79-492x5 1/1 59 秒実行中 keda-operator-metrics-apiserver-66d...  1/1 実行中 59 秒locust-77c699c94d-dvb5n 1/1 実行中 8 分 59 秒 main-nginx-ingress-779b74bb8b-v7ggw 1/1 実行中 48 分 podinfo-5d76864686-c98rb 1/1 実行中 50 分 prometheus-alertmanager-d6d94cf4b-8...  2/2 37 分 prometheus-kube-state-metrics-7cd8f を実行中...  1/1 実行中 37 分 prometheus-node-exporter-j4qf4 1/1 実行中 37 分 prometheus-pushgateway-56745d8d8b-9n4nl 1/1 実行中 37 分 prometheus-server-b78c9449f-6ktn9 2/2 実行中 37 分
    

自動スケーリングポリシーを作成する

ここで、KEDA ScaledObjectカスタム リソース定義 (CRD) を使用して、NGINX Ingress Controller のスケーリング方法を指定するパラメータを定義します。 次の構成:

  • Prometheus によって収集されたnginx_connections_activeメトリックの値に基づいて自動スケーリングをトリガーします。
  • 既存のポッドがそれぞれ 100 のアクティブ接続に達すると、新しいポッドをデプロイします。
  • NGINX Ingress Controller ポッドを 1 個から最大 20 個まで自動スケールします。

次の手順を実行します。

  1. 任意のテキスト エディターを使用して、次の内容を含む4-scaled-object.yamlという YAML ファイルを作成します (またはGitHub からコピーします)。 これは KEDA ScaledObjectを定義します。

    apiバージョン: keda.sh/v1alpha1 種類: ScaledObject 
    メタデータ: 
    名前: nginx-scale 
    仕様: 
    scaleTargetRef: 
    種類: デプロイメント 
    名前: main-nginx-ingress 
    minReplicaCount: 1 
    最大レプリカ数: 20 
    クールダウン期間: 30 
    ポーリング間隔: 1 
    トリガー: 
    - タイプ: prometheus 
    メタデータ: 
    サーバーアドレス: http://prometheus-server 
    メトリック名: nginx_connections_active_keda 
    クエリ: | 
    sum(avg_over_time(nginx_ingress_nginx_connections_active{app="main-nginx-ingress"}[1m])) 
    しきい値: 「100」 
    
  2. ScaledObjectをデプロイします。

    $ kubectl apply -f 4-scaled-object.yaml scaledobject.keda.sh/nginx-scale が作成されました 
    

トラフィックの急増をシミュレートし、自動スケーリングがパフォーマンスに与える影響を観察する

自動スケーリングの有効性を実際にテストするには、チャレンジ 3 と比較して接続数を 2 倍にします。

  1. ブラウザで Locust サーバーに戻ります。 フィールドに次の値を入力し、 「Start swarming」ボタンをクリックします。

    • ユーザー数– 2000
    • 出現率– 10
    • ホスト– http://main-nginx-ingress
  2. Prometheus と Locust ダッシュボードに戻ります。 Prometheus グラフの下のピンク色のボックスは、スケールアップおよびスケールダウンする NGINX Ingress Controller ポッドの数を示しています。

  3. ターミナルに戻り、KEDA HPA を手動で検査します。 出力のREPLICASフィールドには、現在デプロイされているポッドレプリカの数が表示されます。 (読みやすくするために、出力は 2 行に分かれています。)

    $ kubectl get hpa NAME REFERENCE ... keda-hpa-nginx-scale Deployment/main-nginx-ingress ... ... ターゲット MINPODS MAXPODS レプリカ AGE ... 101500m/100(平均)1 20 10 2分45秒
    

次のステップ

アクティブな接続の数のみに基づいて自動スケーリングを行う場合、潜在的な制限が生じます。 NGINX Ingress Controller が(スケーリングしても)非常にビジーになり、接続を切断する必要がある場合、オートスケーラーはアクティブな接続が少なくなったと判断し、リクエストが減少したと解釈して、レプリカの数を減らします。 これによりパフォーマンスが悪化する可能性がありますが、メトリックの組み合わせを活用することで、そのような事態を防ぐことができます。 たとえば、 nginxplus_connections_dropped (NGINX Plus に基づく NGINX Ingress Controller で利用可能) は、ドロップされたクライアント接続を追跡します。

NGINX Ingress Controller を NGINX Plus および NGINX App Protect とともに試用するには、今すぐ30 日間の無料トライアルを開始するか、弊社にお問い合わせの上、ユースケースについてご相談ください

NGINX Open Source で NGINX Ingress Controller を試すには、リリース ソース コードを入手するか、 DockerHubからビルド済みコンテナーをダウンロードします。


「このブログ投稿には、入手できなくなった製品やサポートされなくなった製品が参照されている場合があります。 利用可能な F5 NGINX 製品およびソリューションに関する最新情報については、 NGINX 製品ファミリーをご覧ください。 NGINX は現在 F5 の一部です。 以前の NGINX.com リンクはすべて、F5.com の同様の NGINX コンテンツにリダイレクトされます。"