すべてのプロダクト
Search
ドキュメントセンター

Container Service for Kubernetes:Nginx Ingress のトラフィックメトリクスを使用した複数アプリケーションのスケーリング

最終更新日:Mar 26, 2026

複数の Pod レプリカを実行するとアプリケーションの安定性は向上しますが、トラフィックのピーク時以外はリソースがアイドル状態になりがちです。手動でのスケーリングは時間がかかり、エラーも発生しやすくなります。このチュートリアルでは、NGINX Ingress Controller によって公開される nginx_ingress_controller_requests メトリクスを使用して、2 つのアプリケーションに対して同時に Horizontal Pod Autoscaler (HPA) を駆動する方法を説明します。これにより、各アプリケーションは自身のリクエストレートに基づいて独立してスケーリングされます。

Container Service for Kubernetes (ACK) クラスターの NGINX Ingress Controller は、コミュニティ版の拡張バージョンです。

仕組み

メトリクスパイプラインは、nginx_ingress_controller_requests → Alibaba Cloud Prometheus → ack-alibaba-cloud-metrics-adapter → External Metrics API → HPA コントローラーの順に実行されます。アダプターは、生の Prometheus カウンターを 1 秒あたりのレートに変換します。その後、各 HPA は共有メトリクスをサービス名でフィルターするため、sample-apptest-app は同じメトリクスソースから独立してスケーリングされます。

nginx_ingress_controller_requests はカウンターメトリック (累積合計リクエスト数) です。アダプターは 2 分間のウィンドウで rate() を適用し、これを 1 秒あたりのリクエスト数に変換します。

HPA は、カスタムメトリクスタイプではなく外部メトリクスタイプを使用します。これは、nginx_ingress_controller_requests が特定の Kubernetes オブジェクト (Pod や Deployment など) に関連付けられていないためです。外部メトリクスは、クラスターの外部で公開されるインフラストラクチャレベルのメトリクスに適したタイプです。

前提条件

開始する前に、以下を確認してください。

  • ご利用の ACK クラスターに Alibaba Cloud Prometheus モニタリングがデプロイされていること。詳細については、「Alibaba Cloud Prometheus を使用したモニタリング」をご参照ください。

  • ack-alibaba-cloud-metrics-adapter コンポーネントがデプロイされ、その prometheus.url フィールドが設定されていること。`prometheus.url` フィールドの設定

    prometheus.url の設定方法

    1. [ACK クラスター] ページで、対象クラスターの名前をクリックします。左側のナビゲーションウィンドウで、[アプリケーション] > [Helm] を選択します。

    2. [Helm] ページで ack-alibaba-cloud-metrics-adapter を見つけ、[操作] 列の [更新] をクリックします。

    3. [リリースを更新] パネルで、alibabaCloudMetricsAdapter.prometheus.url をご利用の Prometheus データリクエスト URL に設定し、[OK] をクリックします。> 注: Prometheus データリクエスト URL の取得方法の詳細については、「Prometheus データリクエスト URL の取得方法」をご参照ください。アダプター設定フィールドの完全なリストについては、「ack-alibaba-cloud-metrics-adapter コンポーネント設定ファイルの詳細説明」をご参照ください。

  • ストレステスト用に Apache Benchmark (ab) がインストールされていること。Apache Benchmark のインストール インストール後、動作を確認します。

    コマンド例

    • macOS: ``bash brew install httpd ``

    • Ubuntu または Debian: ``bash sudo apt update sudo apt install apache2-utils ``

    • CentOS 8 または RHEL: ``bash sudo yum install httpd-tools ``

    • Windows: Apache Lounge から Windows ビルドをダウンロードします。展開した bin フォルダに移動し、ab.exe を実行します。

    ab -V

ステップ 1:アプリケーションとサービスの作成

2 つの Deployment と、それぞれに対応する Service を作成します。次のステップで作成する Ingress は、異なる URL パスを通じて各 Service にトラフィックをルーティングします。

  1. 次の内容で nginx1.yaml を作成します。

    YAML の例

    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: test-app
      namespace: default
      labels:
        app: test-app
    spec:
      replicas: 1
      selector:
        matchLabels:
          app: test-app
      template:
        metadata:
          labels:
            app: test-app
        spec:
          containers:
          - image: registry-cn-hangzhou.ack.aliyuncs.com/acs/sample-app:v1-b070784-aliyun
            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

    マニフェストを適用します。

    kubectl apply -f nginx1.yaml
  2. 次の内容で nginx2.yaml を作成します。

    YAML の例

    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: sample-app
      namespace: default
      labels:
        app: sample-app
    spec:
      replicas: 1
      selector:
        matchLabels:
          app: sample-app
      template:
        metadata:
          labels:
            app: sample-app
        spec:
          containers:
          - image: registry-cn-hangzhou.ack.aliyuncs.com/acs/sample-app:v1-b070784-aliyun
            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

    マニフェストを適用します。

    kubectl apply -f nginx2.yaml

ステップ 2:Ingress の作成

  1. 次の内容で ingress.yaml を作成します。

    フィールド説明
    host受信リクエストのドメイン名。この例では test.example.com を使用します。
    path受信リクエストと照合される URL パス。各パスは、その backend Service に転送されます。
    backend一致するパスのトラフィックを受信する Service 名とポート。

    YAML の例

    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

    主要なフィールド:マニフェストを適用します。

    kubectl apply -f ingress.yaml
  2. Ingress がデプロイされたことを確認します。

    kubectl get ingress -o wide

    想定される出力:

    NAME           CLASS   HOSTS              ADDRESS       PORTS   AGE
    test-ingress   nginx   test.example.com   10.XX.XX.10   80      55s

    これで、NGINX Ingress Controller は test.example.com/sample-app に、test.example.com/hometest-app にルーティングします。両方のリクエストパスは、Alibaba Cloud Prometheus の nginx_ingress_controller_requests メトリクスによって追跡されます。

ステップ 3:Prometheus メトリクスを HPA 互換のメトリクスに変換

adapter-config は、生の Prometheus シリーズを HPA が読み取り可能な External Metrics API フォーマットに変換する方法を ack-alibaba-cloud-metrics-adapter に指示します。

adapter-config ファイルの変更

  1. ACK コンソールにログインします。左側のナビゲーションウィンドウで、[クラスター] をクリックします。

  2. [クラスター] ページで、ご利用のクラスターの名前をクリックします。左側のナビゲーションウィンドウで、[アプリケーション] > [Helm] を選択します。

  3. [Helm] ページで、ack-alibaba-cloud-metrics-adapter をクリックします。[リソース] セクションで adapter-config をクリックし、右上隅の [YAML の編集] をクリックします。

  4. 既存のコンテンツを以下に置き換え、[OK] をクリックします。

    フィールド効果
    seriesQuerynginx_ingress_controller_requests生の Prometheus カウンターを選択します
    metricsQuerysum(rate(<<.Series>>{<<.LabelMatchers>>}[2m]))カウンターを 2 分間の 1 秒あたりのレートに変換します。<<.LabelMatchers>> は、クエリ時に HPA のラベルセレクター (例:{service="sample-app"}) に置き換えられます。
    name.matches + name.as^(.*)_requests${1}_per_secondメトリクス名を変更します:nginx_ingress_controller_requestsnginx_ingress_controller_per_second になります。
    resources.namespacedfalseメトリクスを名前空間に紐付けず、クラスター全体の外部メトリクスとして公開します。
    rules:
    - metricsQuery: sum(rate(<<.Series>>{<<.LabelMatchers>>}[2m]))
      name:
        as: ${1}_per_second
        matches: ^(.*)_requests
      resources:
        namespaced: false
      seriesQuery: nginx_ingress_controller_requests

    このルールは次の処理を行います。設定の詳細については、「Alibaba Cloud Prometheus メトリクスに基づく水平 Pod 自動スケーリング」をご参照ください。

    image

メトリクスの公開状況の確認

次のコマンドを実行して、アダプターが変換されたメトリクスを公開していることを確認します。

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": "2025-07-25T07:56:04Z",
      "value": "0"
    }
  ]
}

トラフィックがない場合、value0 になるのは正常です。リクエストが到着すると、HPA はゼロ以外の値を受け取ります。

ステップ 4:HPA の作成

各 HPA は単一の Deployment をターゲットとし、selector.matchLabels を使用して共有メトリクスをサービス名でフィルターします。アダプターがメトリクスクエリを実行する際、ラベルセレクター (例:{service="sample-app"}) を <<.LabelMatchers>> プレースホルダーに挿入するため、各 HPA は自身のアプリケーションのリクエストレートのみを参照します。

averageValue: 30 というターゲットは、各 Pod が 1 秒あたり 30 リクエストを超えて処理しないようにすることを意味します。HPA は、実行中のすべての Pod でこの平均を維持するようにレプリカ数を調整します。

  1. 次の内容で hpa.yaml を作成します。

    YAML の例

    apiVersion: autoscaling/v2
    kind: HorizontalPodAutoscaler
    metadata:
      name: sample-hpa
      namespace: default
    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:
    # クエリ時に <<.LabelMatchers>> に挿入され、メトリクスをこのサービスのみにフィルターします。
                  service: sample-app
    # 外部メトリクスは Value と AverageValue のターゲットタイプのみをサポートします。
            target:
              type: AverageValue
              averageValue: 30  # ターゲット:Pod あたり 30 リクエスト/秒
    ---
    apiVersion: autoscaling/v2
    kind: HorizontalPodAutoscaler
    metadata:
      name: test-hpa
      namespace: default
    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:
    # クエリ時に <<.LabelMatchers>> に挿入され、メトリクスをこのサービスのみにフィルターします。
                  service: test-app
    # 外部メトリクスは Value と AverageValue のターゲットタイプのみをサポートします。
            target:
              type: AverageValue
              averageValue: 30  # ターゲット:Pod あたり 30 リクエスト/秒

    マニフェストを適用します。

    kubectl apply -f hpa.yaml
  2. 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 とも 0/30 (avg) と表示されています。これは、現在のメトリクス値が 0 (トラフィックなし) であり、ターゲットが Pod あたり 30 リクエスト/秒であることを示しています。

ステップ 5:結果の確認

Apache Benchmark を使用してトラフィックを送信し、各 HPA が独立して応答する様子を観察します。

負荷が開始された後、レプリカ数にスケールアウトの決定が反映されるまで 1~2 分かかります。
  1. /home パス (test-app にルーティングされる) に 5,000 リクエストを送信します。

    ab -c 50 -n 5000 test.example.com/home
  2. 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

    test-hpa は、test-app のリクエストレートが Pod あたり 30 リクエスト/秒のしきい値を超えたため、3 レプリカにスケールアウトしました。sample-app にはトラフィックが到達しなかったため、sample-hpa は 1 レプリカのままでした。

  3. ルートパス (sample-app にルーティングされる) に 5,000 リクエストを送信します。

    ab -c 50 -n 5000 test.example.com/
  4. 再度 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

    sample-hpa は新しいトラフィックに応答して 2 レプリカにスケールアウトしました。ストレステストが終了した後、test-hpa は 1 レプリカにスケールバックしました。これにより、両方の HPA がそれぞれのアプリケーションメトリクスを個別に追跡していることが確認できます。

次のステップ