このチュートリアルは、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 コントローラー ポッドを自動スケーリングする方法を示します。
チュートリアルを実行するには、次の条件を満たすマシンが必要です。
ラボとチュートリアルを最大限に活用するには、開始する前に次のことを実行することをお勧めします。
背景ブログを確認する
ラボの20 分間のビデオ概要をご覧ください。
このチュートリアルでは次のテクノロジを使用します。
各チャレンジの手順には、アプリを構成するために使用される YAML ファイルの完全なテキストが含まれています。 GitHub リポジトリからテキストをコピーすることもできます。 各 YAML ファイルのテキストとともに GitHub へのリンクが提供されます。
このチュートリアルには 4 つの課題が含まれています。
このチャレンジでは、 minikube クラスターを作成し、サンプル アプリとしてPodinfo をインストールします。
minikubeクラスターを作成します。 数秒後、デプロイメントが成功したことを確認するメッセージが表示されます。
$ minikube start 🏄 完了!kubectl はデフォルトで「minikube」クラスターと「default」名前空間を使用するように設定されました
Podinfo は、 「Kubernetes でマイクロサービスを実行するためのベスト プラクティスを紹介する、Go で作成された Web アプリケーション」です。 フットプリントが小さいため、サンプル アプリとして使用しています。
任意のテキスト エディターを使用して、次の内容を含む1-deployment.yamlという YAML ファイルを作成します (またはGitHub からコピーします)。 単一のレプリカとサービスを持つデプロイメントを定義します。
apiバージョン: apps/v1 種類: デプロイメント
メタデータ:
名前: podinfo
仕様:
セレクタ:
matchLabels:
アプリ: podinfo
テンプレート:
メタデータ:
ラベル:
アプリ: podinfo
仕様:
コンテナ:
-名前: podinfo
イメージ: stefanprodan/podinfo
ポート:
-コンテナポート: 9898
---
apiバージョン: v1
種類: サービス
メタデータ:
名前: podinfo
仕様:
ポート:
- ポート: 80
ターゲットポート: 9898
ノードポート: 30001
セレクタ:
アプリ: podinfo
タイプ: ロードバランサー
アプリをデプロイします。
$ kubectl apply -f 1-deployment.yamlデプロイメント.apps/podinfo が作成されました サービス/podinfo が作成されました
STATUS
列の値が Running である
ことで示されるように、Podinfo ポッドがデプロイされていることを確認します。
$ kubectl get pods NAME READY STATUS RESTARTS AGE podinfo-5d76864686-rd2s5 1/1 実行中 0 3分38秒
ブラウザで Podinfo を開きます。 podinfo ページからの挨拶は、 Podinfo が実行中であることを示します。
$ minikubeサービスpodinfo
このチャレンジでは、 NGINX Ingress Controller をデプロイし、トラフィックを Podinfo アプリにルーティングするように設定します。
NGINX Ingress Controller をインストールする最も速い方法は、 Helmを使用することです。
NGINX リポジトリを Helm に追加します。
$ helm リポジトリに nginx-stable を追加します https://helm.nginx.com/stable
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 がインストールされました。
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秒
任意のテキスト エディターを使用して、次の内容を含む2-ingress.yamlという YAML ファイルを作成します (またはGitHub からコピーします)。 トラフィックを Podinfo にルーティングするために必要な Ingress マニフェストを定義します。
apiバージョン: networking.k8s.io/v1 種類: Ingress
メタデータ:
名前: podinfo
仕様:
ingressClassName: nginx
ルール:
- ホスト: "example.com"
http:
パス:
- バックエンド:
サービス:
名前: podinfo
ポート:
番号: 80
パス: /
パスタイプ: プレフィックス
Ingress リソースをデプロイします。
$ kubectl apply -f 2-ingress.yaml ingress.networking.k8s.io/podinfo が作成されました
このチャレンジでは、さまざまなトラフィック負荷下での 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 を超えるメトリックがあります。
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 <なし> <なし>
Kubernetes クラスター内のホスト上にシェルを備えた一時的なBusyBoxポッドを作成します。
$ kubectl run -ti --rm=true busybox --image=busyboxコマンドプロンプトが表示されない場合は、Enterキーを押してみてください。 / #
NGINX Ingress Controller によって生成されたメトリックを一覧表示し、 nginx_connections_active
が含まれていることを確認します。 のために <IP アドレス>
手順 1 の値を代入します。
/# wget -qO- <IP アドレス>:9113/メトリクス
シェルを終了して Kubernetes サーバーに戻ります。
/#出口
NGINX Ingress Controller がnginx_connections_active
メトリックを追跡していることがわかったので、メトリックを収集 (「スクレイピング」) するためのツールが必要です。このチュートリアルではPrometheus を使用します。
NGINX Ingress Controller に関しては、 Helm がPrometheus をインストールする最も速い方法です。
Prometheus リポジトリを Helm に追加します。
$ helm リポジトリに prometheus-community を追加します https://prometheus-community.github.io/helm-charts
Prometheus をダウンロードしてインストールします。
$ helm install prometheus prometheus-community/prometheus \ --set server.service.type=NodePort --set server.service.nodePort=30010
インストールを確認します。完了するまでに通常 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秒
Prometheus を開きます。 minikube 環境で次のコマンドを実行すると、デフォルトのブラウザで Prometheus ダッシュボードが開きます。
$ minikubeサービスprometheus-server
次のようなページが表示されれば、サーバーが動作していることが確認できます。
アクティブ接続メトリックの現在の値を表示するには、検索バーに「nginx_ingress_nginx_connections_active」
と入力します。 アクティブな接続が 1 つ表示されます。これは、NGINX Ingress Controller ポッドを 1 つデプロイしているためです。
次のセクションでは、オープンソースの負荷テスト ツールであるLocust を使用してトラフィックの急増をシミュレートし、Prometheus で NGINX Ingress Controller のパフォーマンスを確認します。 ここで Locust を展開します。
任意のテキスト エディターを使用して、次の内容を含む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
タイプ: ロードバランサー
ローカストを展開:
$ kubectl apply -f 3-locust.yaml configmap/locust-script が作成されました。deployment.apps/locust が作成されました。service/locust が作成されました。
ブラウザで Locust を開きます。
$ minikube サービス イナゴ
フィールドに次の値を入力します。
「スウォーミングの開始」ボタンをクリックして、トラフィックを Podinfo アプリに送信します。
Prometheus ダッシュボードに戻り、NGINX Ingress Controller がどのように応答するかを確認します。 変更を確認するには、 nginx_ingress_nginx_connections_active
に対して新しいクエリを実行する必要がある場合があります。
次の画面出力に示されているように、多数の接続が確立されると、単一の NGINX Ingress Controller ポッドは、遅延なしで増加したトラフィックを処理するのに苦労します。 Prometheus グラフは、NGINX Ingress Controller ポッドあたり約 100 のアクティブ接続がレイテンシの急上昇の転換点であることを明らかにしています。 この情報を使用して、レイテンシの増加を回避するために NGINX Ingress Controller ポッドの数を増やす必要があるタイミングを判断できます。
最後の課題では、トラフィック量の増加に応じてリソースを自動スケーリングする構成を構築します。 このチュートリアルでは自動スケーリングに KEDA を使用するため、まずKEDA をインストールし、スケーリングがいつどのように行われるかを定義するポリシーを作成します。 チャレンジ 3 と同様に、Locust を使用してトラフィックの急増をシミュレートし、Prometheus を使用して、自動スケーリングが有効になっているときの NGINX Ingress Controller のパフォーマンスを観察します。
Kubernetes イベント駆動型オートスケーラーであるKEDA は、メトリック サーバー (Kubernetes のメトリックを保存および変換するコンポーネント) を統合し、Prometheus (およびその他のツール) から直接メトリックを消費できます。 これらのメトリックを使用してHorizontal Pod Autoscaler (HPA) を作成し、Prometheus によって収集されたメトリックをブリッジして、Kubernetes にフィードします。
NGINX Ingress Controller および Prometheus と同様に、チュートリアルでは Helm を使用して KEDA をインストールします。
KEDA を Helm リポジトリに追加します。
$ helm repo add kedacore https://kedacore.github.io/charts 「kedacore」がリポジトリに追加されました
KEDA をインストールします。
$ helm install keda kedacore/keda NAME: keda NAMESPACE: default STATUS: deployed REVISION: 1 テストスイート: なし
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 のスケーリング方法を指定するパラメータを定義します。 次の構成:
nginx_connections_active
メトリックの値に基づいて自動スケーリングをトリガーします。次の手順を実行します。
任意のテキスト エディターを使用して、次の内容を含む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」
ScaledObject
をデプロイします。
$ kubectl apply -f 4-scaled-object.yaml scaledobject.keda.sh/nginx-scale が作成されました
自動スケーリングの有効性を実際にテストするには、チャレンジ 3 と比較して接続数を 2 倍にします。
ブラウザで Locust サーバーに戻ります。 フィールドに次の値を入力し、 「Start swarming」ボタンをクリックします。
Prometheus と Locust ダッシュボードに戻ります。 Prometheus グラフの下のピンク色のボックスは、スケールアップおよびスケールダウンする NGINX Ingress Controller ポッドの数を示しています。
ターミナルに戻り、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 コンテンツにリダイレクトされます。"