このチュートリアルは、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 🏄 Done! kubectl is now configured to use "minikube" cluster and "default" namespace by default
Podinfo は、 「Kubernetes でマイクロサービスを実行するためのベスト プラクティスを紹介する、Go で作成された Web アプリケーション」です。 フットプリントが小さいため、サンプル アプリとして使用しています。
任意のテキスト エディターを使用して、次の内容を含む1-deployment.yamlという YAML ファイルを作成します (またはGitHub からコピーします)。 単一のレプリカとサービスを持つデプロイメントを定義します。
apiVersion: apps/v1 kind: Deployment
metadata:
name: podinfo
spec:
selector:
matchLabels:
app: podinfo
template:
metadata:
labels:
app: podinfo
spec:
containers:
- name: podinfo
image: stefanprodan/podinfo
ports:
- containerPort: 9898
---
apiVersion: v1
kind: Service
metadata:
name: podinfo
spec:
ports:
- port: 80
targetPort: 9898
nodePort: 30001
selector:
app: podinfo
type: LoadBalancer
アプリをデプロイします。
$ kubectl apply -f 1-deployment.yaml deployment.apps/podinfo created
service/podinfo created
STATUS
列の値が Running である
ことで示されるように、Podinfo ポッドがデプロイされていることを確認します。
$ kubectl get podsNAME READY STATUS RESTARTS AGE
podinfo-5d76864686-rd2s5 1/1 Running 0 3m38s
ブラウザで Podinfo を開きます。 podinfo ページからの挨拶は、 Podinfo が実行中であることを示します。
$ minikube service podinfo
このチャレンジでは、 NGINX Ingress Controller をデプロイし、トラフィックを Podinfo アプリにルーティングするように設定します。
NGINX Ingress Controller をインストールする最も速い方法は、 Helmを使用することです。
NGINX リポジトリを Helm に追加します。
$ helm repo add 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
NAME: main
LAST DEPLOYED: Tue Mar 15 09:49:17 2022
NAMESPACE: default
STATUS: deployed
REVISION: 1
TEST SUITE: None
NOTES: The NGINX Ingress Controller has been installed.
STATUS
列の値がRunning である
ことで示されるように、NGINX Ingress Controller ポッドがデプロイされていることを確認します (読みやすくするために、出力は 2 行に分かれています)。
$ kubectl get podsNAME READY STATUS ...
main-nginx-ingress-779b74bb8b-mtdkr 1/1 Running ...
podinfo-5d76864686-fjncl 1/1 Running ...
... RESTARTS AGE
... 0 18s
... 0 2m36s
任意のテキスト エディターを使用して、次の内容を含む2-ingress.yamlという YAML ファイルを作成します (またはGitHub からコピーします)。 トラフィックを Podinfo にルーティングするために必要な Ingress マニフェストを定義します。
apiVersion: networking.k8s.io/v1 kind: Ingress
metadata:
name: podinfo
spec:
ingressClassName: nginx
rules:
- host: "example.com"
http:
paths:
- backend:
service:
name: podinfo
port:
number: 80
path: /
pathType: Prefix
Ingress リソースをデプロイします。
$ kubectl apply -f 2-ingress.yaml ingress.networking.k8s.io/podinfo created
このチャレンジでは、さまざまなトラフィック負荷下での 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 Running ...
podinfo-5d76864686-nl8ws 1/1 Running ...
... IP NODE NOMINATED NODE READINESS GATES
... 172.17.0.4 minikube <none> <none>
... 172.17.0.3 minikube <none> <none>
Kubernetes クラスター内のホスト上にシェルを備えた一時的なBusyBoxポッドを作成します。
$ kubectl run -ti --rm=true busybox --image=busyboxIf you don't see a command prompt, try pressing enter.
/ #
NGINX Ingress Controller によって生成されたメトリックを一覧表示し、 nginx_connections_active
が含まれていることを確認します。 のために <IP アドレス>
手順 1 の値を代入します。
/# wget -qO- <IP_address>:9113/metrics
シェルを終了して Kubernetes サーバーに戻ります。
/# exit
NGINX Ingress Controller がnginx_connections_active
メトリックを追跡していることがわかったので、メトリックを収集 (「スクレイピング」) するためのツールが必要です。このチュートリアルではPrometheus を使用します。
NGINX Ingress Controller に関しては、 Helm がPrometheus をインストールする最も速い方法です。
Prometheus リポジトリを Helm に追加します。
$ helm repo add 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 podsNAME 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 ...
... STATUS RESTARTS AGE
... Running 0 3m23s
... Running 0 5m41s
... ContainerCreating 0 7s
... Running 0 7s
... Running 0 7s
... ContainerCreating 0 7s
... ContainerCreating 0 7s
Prometheus を開きます。 minikube 環境で次のコマンドを実行すると、デフォルトのブラウザで Prometheus ダッシュボードが開きます。
$ minikube service 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というスクリプトを定義します。
apiVersion: v1
kind: ConfigMap
metadata:
name: locust-script
data:
locustfile.py: |-
from locust import HttpUser, task, between
class 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: Deployment
metadata:
name: locust
spec:
selector:
matchLabels:
app: locust
template:
metadata:
labels:
app: locust
spec:
containers:
- name: locust
image: locustio/locust
ports:
- containerPort: 8089
volumeMounts:
- mountPath: /home/locust
name: locust-script
volumes:
- name: locust-script
configMap:
name: locust-script
---
apiVersion: v1
kind: Service
metadata:
name: locust
spec:
ports:
- port: 8089
targetPort: 8089
nodePort: 30015
selector:
app: locust
type: LoadBalancer
ローカストを展開:
$ kubectl apply -f 3-locust.yaml configmap/locust-script created
deployment.apps/locust created
service/locust created
ブラウザで Locust を開きます。
$ minikube service locust
フィールドに次の値を入力します。
「スウォーミングの開始」ボタンをクリックして、トラフィックを 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" has been added to your repositories
KEDA をインストールします。
$ helm install keda kedacore/keda NAME: keda
NAMESPACE: default
STATUS: deployed
REVISION: 1
TEST SUITE: None
KEDA が 2 つのポッドとして実行されていることを確認します。 (読みやすさを考慮して、 NAME
列の一部の値は短縮されています。 また、 RESTARTS
列は省略されており、値は0
すべてのポッドに対して。
$ kubectl get pods NAME READY STATUS AGE
keda-operator-8644dcdb79-492x5 1/1 Running 59s
keda-operator-metrics-apiserver-66d... 1/1 Running 59s
locust-77c699c94d-dvb5n 1/1 Running 8m59s
main-nginx-ingress-779b74bb8b-v7ggw 1/1 Running 48m
podinfo-5d76864686-c98rb 1/1 Running 50m
prometheus-alertmanager-d6d94cf4b-8... 2/2 Running 37m
prometheus-kube-state-metrics-7cd8f... 1/1 Running 37m
prometheus-node-exporter-j4qf4 1/1 Running 37m
prometheus-pushgateway-56745d8d8b-9n4nl 1/1 Running 37m
prometheus-server-b78c9449f-6ktn9 2/2 Running 37m
ここで、KEDA ScaledObject
カスタム リソース定義 (CRD) を使用して、NGINX Ingress Controller のスケーリング方法を指定するパラメータを定義します。 次の構成:
nginx_connections_active
メトリックの値に基づいて自動スケーリングをトリガーします。次の手順を実行します。
任意のテキスト エディターを使用して、次の内容を含む4-scaled-object.yamlという YAML ファイルを作成します (またはGitHub からコピーします)。 これは KEDA ScaledObject
を定義します。
apiVersion: keda.sh/v1alpha1 kind: ScaledObject
metadata:
name: nginx-scale
spec:
scaleTargetRef:
kind: Deployment
name: main-nginx-ingress
minReplicaCount: 1
maxReplicaCount: 20
cooldownPeriod: 30
pollingInterval: 1
triggers:
- type: prometheus
metadata:
serverAddress: http://prometheus-server
metricName: nginx_connections_active_keda
query: |
sum(avg_over_time(nginx_ingress_nginx_connections_active{app="main-nginx-ingress"}[1m]))
threshold: "100"
ScaledObject
をデプロイします。
$ kubectl apply -f 4-scaled-object.yaml scaledobject.keda.sh/nginx-scale created
自動スケーリングの有効性を実際にテストするには、チャレンジ 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 ...
... TARGETS MINPODS MAXPODS REPLICAS AGE
... 101500m/100 (avg) 1 20 10 2m45s
アクティブな接続の数のみに基づいて自動スケーリングを行う場合、潜在的な制限が生じます。 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 の一部です。 q。"