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

Container Service for Kubernetes:NGINX Ingressコントローラーのメトリックに基づいて、複数のアプリケーションの水平ポッド自動スケーリングを構成する

最終更新日:Dec 13, 2024

アプリケーションを複数のポッドにデプロイして、アプリケーションの安定性を高めることができます。 しかし、この方法はコストを増加させ、オフピーク時間帯に資源の浪費を引き起こす。 アプリケーションのポッドを手動でスケーリングすることもできます。 ただし、この方法ではO&Mワークロードが増加し、ポッドをリアルタイムでスケーリングできません。 上記の問題を解決するには、NGINX Ingressコントローラーのメトリックに基づいて、複数のアプリケーションの水平ポッド自動スケーリングを設定します。 このようにして、アプリケーションのポッドは負荷に基づいて自動的にスケーリングされます。 この方法は、アプリケーションの安定性と回復力を改善し、リソース使用を最適化し、コストを削減します。 このトピックでは、NGINX Ingressコントローラーのメトリックに基づいて、複数のアプリケーションの水平ポッド自動スケーリングを設定する方法について説明します。

前提条件

NGINX Ingressコントローラーのメトリックに基づいて複数のアプリケーションの水平ポッド自動スケーリングを構成するには、Managed Service for Prometheusメトリックをhorizontal pod Autoscaler (HPA) でサポートされているメトリックに変換し、必要なコンポーネントをデプロイする必要があります。

背景情報

運用環境のリクエスト数に基づいてアプリケーションのポッドを自動的にスケーリングするには、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メトリックに基づいてポッドを自動的にスケーリングするように設定されています。

  1. 次のYAMLテンプレートを使用して、デプロイとサービスを作成します。

    1. 次の内容に基づいて、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
    2. 次の内容に基づいて、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
  2. 次の内容に基づいて、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パラメーターに一致するリクエストが転送されるサービスの名前とポート。

  3. 次のコマンドを実行してIngressを照会します。

    kubectl get ingress -o wide

    期待される出力:

    NAME           CLASS   HOSTS              ADDRESS       PORTS   AGE                                                  
    test-ingress   nginx   test.example.com   10.10.10.10   80      55s
  4. 上記のリソースオブジェクトをデプロイした後、/および /home URLパスにリクエストを送信して、指定したホストにアクセスできます。 NGINX Ingressコントローラーは、リクエストのURLパスに基づいて、リクエストをtest-appおよびsample-appアプリケーションに自動的にルーティングします。 各アプリケーションへのリクエストに関する情報は、Managed Service for Prometheusメトリックnginx_ingress_controller_requestsから取得できます。

  5. alibaba-cloud-metrics-adapterコンポーネントのadapter.configファイルを変更して、PrometheusメトリックをHPAでサポートされているメトリックに変換します。

    説明

    adapter.configファイルを変更する前に、alibaba-cloud-metrics-adapterコンポーネントがクラスターにインストールされ、prometheus.urlファイルが設定されていることを確認してください。

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

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

    3. クリックack-alibaba-cloud-metrics-adapter.

    4. では、リソースセクション、をクリックadapter-config.

    5. On theadapter-configページをクリックします。YAMLの編集右上隅にあります。

    6. のコードを置き換えるをクリックし、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
  6. 次のコマンドを実行して、メトリックを照会します。

    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"
        }
      ]
    }
  7. 次の内容に基づいて、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
  8. 次のコマンドを実行して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
  9. HPAを設定した後、ストレステストを実行して、リクエスト数が増加したときにアプリケーションのポッドが自動的にスケールアウトされるかどうかを確認します。

    1. 次のコマンドを実行して、ホストの /home URLパスでストレステストを実行します。

      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
    3. 次のコマンドを実行して、ホストのルートパスでストレステストを実行します。

      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

      出力は、リクエスト数がスケーリングしきい値を超えると、アプリケーションのポッドが自動的にスケールアウトされることを示しています。

関連ドキュメント

  • マルチゾーン負荷分散は、データサービスの高可用性シナリオで一般的に使用される展開ソリューションです。 ゾーンをまたいでデプロイされたアプリケーションに、重いワークロードを処理するのに十分なリソースがない場合は、アプリケーションの各ゾーンに特定の数のノードをACKで作成することができます。 詳細については、「クロスゾーンデプロイの自動スケーリングの設定」をご参照ください。

  • 複雑なシナリオで水平ポッドの自動スケーリングを高速化するカスタムイメージを作成する方法の詳細については、「カスタムイメージの作成」をご参照ください。