アプリケーションを複数のポッドにデプロイして、アプリケーションの安定性を高めることができます。 しかし、この方法はコストを増加させ、オフピーク時間帯に資源の浪費を引き起こす。 アプリケーションのポッドを手動でスケーリングすることもできます。 ただし、この方法ではO&Mワークロードが増加し、ポッドをリアルタイムでスケーリングできません。 上記の問題を解決するには、NGINX Ingressコントローラーのメトリックに基づいて、複数のアプリケーションの水平ポッド自動スケーリングを設定します。 このようにして、アプリケーションのポッドは負荷に基づいて自動的にスケーリングされます。 この方法は、アプリケーションの安定性と回復力を改善し、リソース使用を最適化し、コストを削減します。 このトピックでは、NGINX Ingressコントローラーのメトリックに基づいて、複数のアプリケーションの水平ポッド自動スケーリングを設定する方法について説明します。
前提条件
NGINX Ingressコントローラーのメトリックに基づいて複数のアプリケーションの水平ポッド自動スケーリングを構成するには、Managed Service for Prometheusメトリックをhorizontal pod Autoscaler (HPA) でサポートされているメトリックに変換し、必要なコンポーネントをデプロイする必要があります。
Managed Service for Prometheusコンポーネントがインストールされています。 詳細については、「Prometheusのマネージドサービスの有効化」をご参照ください。
alibaba-cloud-metrics-adapterがインストールされています。 詳細については、「PrometheusメトリックのManaged Serviceに基づく水平ポッドのスケーリング」をご参照ください。
ストレステストツールApache Benchmarkがインストールされています。 詳細については、「Apache Benchmark」をご参照ください。
背景情報
運用環境のリクエスト数に基づいてアプリケーションのポッドを自動的にスケーリングするには、http_requests_totalメトリックを使用してリクエスト数を収集します。 NGINX Ingressコントローラーのメトリックに基づいて、水平ポッドの自動スケーリングを構成することを推奨します。
IngressはKubernetes APIオブジェクトです。 Ingressは、要求のホストとURLパスに基づいてクライアント要求をサービスに転送します。 次に、サービスはリクエストをバックエンドポッドにルーティングします。
NGINX Ingressコントローラーは、クラスター内のIngressを制御するためにContainer Service for Kubernetes (ACK) クラスターにデプロイされます。 NGINX Ingressコントローラは、高性能でカスタムのトラフィック管理を提供します。 ACKが提供するNGINX Ingressコントローラーは、オープンソースバージョンに基づいて開発され、Alibaba Cloudサービスのさまざまな機能と統合されており、簡素化されたユーザーエクスペリエンスを提供します。
手順
このトピックでは、NGINX Ingressコントローラーによって受信された外部要求を転送するために、2つのClusterIPサービスが作成されます。 次の例では、HPAは、トラフィック負荷を示すnginx_ingress_controller_requests
メトリックに基づいてポッドを自動的にスケーリングするように設定されています。
次のYAMLテンプレートを使用して、デプロイとサービスを作成します。
次の内容に基づいて、nginx1.yamlという名前のファイルを作成します。 次に、
kubectl apply -f nginx1.yaml
コマンドを実行して、test-appという名前のアプリケーションとtest-appという名前のサービスを作成します。apiVersion: apps/v1 kind: Deployment metadata: name: test-app labels: app: test-app spec: replicas: 1 selector: matchLabels: app: test-app template: metadata: labels: app: test-app spec: containers: - image: skto/sample-app:v2 name: metrics-provider ports: - name: http containerPort: 8080 --- apiVersion: v1 kind: Service metadata: name: test-app namespace: default labels: app: test-app spec: ports: - port: 8080 name: http protocol: TCP targetPort: 8080 selector: app: test-app type: ClusterIP
次の内容に基づいて、nginx2.yamlという名前のファイルを作成します。 次に、
kubectl apply -f nginx2.yaml
コマンドを実行して、sample-appという名前のアプリケーションとsample-appという名前のサービスを作成します。apiVersion: apps/v1 kind: Deployment metadata: name: sample-app labels: app: sample-app spec: replicas: 1 selector: matchLabels: app: sample-app template: metadata: labels: app: sample-app spec: containers: - image: skto/sample-app:v2 name: metrics-provider ports: - name: http containerPort: 8080 --- apiVersion: v1 kind: Service metadata: name: sample-app namespace: default labels: app: sample-app spec: ports: - port: 80 name: http protocol: TCP targetPort: 8080 selector: app: sample-app type: ClusterIP
次の内容に基づいて、ingress.yamlという名前のファイルを作成します。 次に、
kubectl apply -f ingress.yaml
コマンドを実行してIngressを作成します。apiVersion: networking.k8s.io/v1 kind: Ingress metadata: name: test-ingress namespace: default spec: ingressClassName: nginx rules: - host: test.example.com http: paths: - backend: service: name: sample-app port: number: 80 path: / pathType: ImplementationSpecific - backend: service: name: test-app port: number: 8080 path: /home pathType: ImplementationSpecific
host: バックエンドサービスへの外部アクセスを有効にするために使用されるドメイン名。 この例では、
test.example.com
が使用されます。path: リクエストの照合に使用されるURLパス。 Ingressによって受信された要求は、Ingressルールと照合され、対応するサービスに転送されます。 次に、サービスはリクエストをバックエンドポッドにルーティングします。
backend:
path
パラメーターに一致するリクエストが転送されるサービスの名前とポート。
次のコマンドを実行してIngressを照会します。
kubectl get ingress -o wide
期待される出力:
NAME CLASS HOSTS ADDRESS PORTS AGE test-ingress nginx test.example.com 10.10.10.10 80 55s
上記のリソースオブジェクトをデプロイした後、
/
および/home
URLパスにリクエストを送信して、指定したホストにアクセスできます。 NGINX Ingressコントローラーは、リクエストのURLパスに基づいて、リクエストをtest-appおよびsample-appアプリケーションに自動的にルーティングします。 各アプリケーションへのリクエストに関する情報は、Managed Service for Prometheusメトリックnginx_ingress_controller_requests
から取得できます。alibaba-cloud-metrics-adapterコンポーネントのadapter.configファイルを変更して、PrometheusメトリックをHPAでサポートされているメトリックに変換します。
説明adapter.configファイルを変更する前に、alibaba-cloud-metrics-adapterコンポーネントがクラスターにインストールされ、prometheus.urlファイルが設定されていることを確認してください。
ACKコンソールにログインします。 左側のナビゲーションウィンドウで、[クラスター] をクリックします。
[クラスター] ページで、管理するクラスターの名前をクリックします。 左側のナビゲーションウィンドウで、 を選択します。
クリックack-alibaba-cloud-metrics-adapter.
では、リソースセクション、をクリックadapter-config.
On theadapter-configページをクリックします。YAMLの編集右上隅にあります。
のコードを置き換える値をクリックし、OKページの下部にあります。
ConfigMapを設定する方法の詳細については、「Prometheusメトリックのマネージドサービスに基づく水平ポッドのスケーリング」をご参照ください。
rules: - metricsQuery: sum(rate(<<.Series>>{<<.LabelMatchers>>}[2m])) name: as: ${1}_per_second matches: ^(.*)_requests resources: namespaced: false overrides: controller_namespace: resource: namespace seriesQuery: nginx_ingress_controller_requests
次のコマンドを実行して、メトリックを照会します。
kubectl get --raw "/apis/external.metrics.k8s.io/v1beta1/namespaces/*/nginx_ingress_controller_per_second" | jq .
期待される出力:
{ "kind": "ExternalMetricValueList", "apiVersion": "external.metrics.k8s.io/v1beta1", "metadata": {}, "items": [ { "metricName": "nginx_ingress_controller_per_second", "metricLabels": {}, "timestamp": "2022-03-31T10:11:37Z", "value": "0" } ] }
次の内容に基づいて、hpa.yamlという名前のファイルを作成します。 次に、
kubectl apply -f hpa.yaml
コマンドを実行して、sample-appアプリケーションとtest-appアプリケーションの両方にHPAを設定します。apiVersion: autoscaling/v2beta2 kind: HorizontalPodAutoscaler metadata: name: sample-hpa spec: scaleTargetRef: apiVersion: apps/v1 kind: Deployment name: sample-app minReplicas: 1 maxReplicas: 10 metrics: - type: External external: metric: name: nginx_ingress_controller_per_second selector: matchLabels: # You can configure this parameter to filter metrics. The value of this parameter is passed to the <<.LabelMatchers>> field in the adapter.config file. service: sample-app # You can specify only thresholds of the Value or AverageValue type for external metrics. target: type: AverageValue averageValue: 30 ---------- apiVersion: autoscaling/v2beta2 kind: HorizontalPodAutoscaler metadata: name: test-hpa spec: scaleTargetRef: apiVersion: apps/v1 kind: Deployment name: test-app minReplicas: 1 maxReplicas: 10 metrics: - type: External external: metric: name: nginx_ingress_controller_per_second selector: matchLabels: # You can configure this parameter to filter metrics. The value of this parameter is passed to the <<.LabelMatchers>> field in the adapter.config file. service: test-app # You can specify only thresholds of the Value or AverageValue type for external metrics. target: type: AverageValue averageValue: 30
次のコマンドを実行してHPA情報を照会します。
kubectl get hpa
期待される出力:
NAME REFERENCE TARGETS MINPODS MAXPODS REPLICAS AGE sample-hpa Deployment/sample-app 0/30 (avg) 1 10 1 74s test-hpa Deployment/test-app 0/30 (avg) 1 10 1 59m
HPAを設定した後、ストレステストを実行して、リクエスト数が増加したときにアプリケーションのポッドが自動的にスケールアウトされるかどうかを確認します。
次のコマンドを実行して、ホストの
/home
URLパスでストレステストを実行します。ab -c 50 -n 5000 test.example.com/home
次のコマンドを実行してHPA情報を照会します。
kubectl get hpa
期待される出力:
NAME REFERENCE TARGETS MINPODS MAXPODS REPLICAS AGE sample-hpa Deployment/sample-app 0/30 (avg) 1 10 1 22m test-hpa Deployment/test-app 22096m/30 (avg) 1 10 3 80m
次のコマンドを実行して、ホストのルートパスでストレステストを実行します。
ab -c 50 -n 5000 test.example.com/
次のコマンドを実行してHPA情報を照会します。
kubectl get hpa
期待される出力:
NAME REFERENCE TARGETS MINPODS MAXPODS REPLICAS AGE sample-hpa Deployment/sample-app 27778m/30 (avg) 1 10 2 38m test-hpa Deployment/test-app 0/30 (avg) 1 10 1 96m
出力は、リクエスト数がスケーリングしきい値を超えると、アプリケーションのポッドが自動的にスケールアウトされることを示しています。
関連ドキュメント
マルチゾーン負荷分散は、データサービスの高可用性シナリオで一般的に使用される展開ソリューションです。 ゾーンをまたいでデプロイされたアプリケーションに、重いワークロードを処理するのに十分なリソースがない場合は、アプリケーションの各ゾーンに特定の数のノードをACKで作成することができます。 詳細については、「クロスゾーンデプロイの自動スケーリングの設定」をご参照ください。
複雑なシナリオで水平ポッドの自動スケーリングを高速化するカスタムイメージを作成する方法の詳細については、「カスタムイメージの作成」をご参照ください。