複数の 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-app と test-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` フィールドの設定ストレステスト用に Apache Benchmark (
ab) がインストールされていること。Apache Benchmark のインストール インストール後、動作を確認します。
ステップ 1:アプリケーションとサービスの作成
2 つの Deployment と、それぞれに対応する Service を作成します。次のステップで作成する Ingress は、異なる URL パスを通じて各 Service にトラフィックをルーティングします。
次の内容で
nginx1.yamlを作成します。マニフェストを適用します。
kubectl apply -f nginx1.yaml次の内容で
nginx2.yamlを作成します。マニフェストを適用します。
kubectl apply -f nginx2.yaml
ステップ 2:Ingress の作成
次の内容で
ingress.yamlを作成します。フィールド 説明 host受信リクエストのドメイン名。この例では test.example.comを使用します。path受信リクエストと照合される URL パス。各パスは、その backendService に転送されます。backend一致するパスのトラフィックを受信する Service 名とポート。 主要なフィールド:マニフェストを適用します。
kubectl apply -f ingress.yamlIngress がデプロイされたことを確認します。
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/homeをtest-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 ファイルの変更
ACK コンソールにログインします。左側のナビゲーションウィンドウで、[クラスター] をクリックします。
[クラスター] ページで、ご利用のクラスターの名前をクリックします。左側のナビゲーションウィンドウで、[アプリケーション] > [Helm] を選択します。
[Helm] ページで、ack-alibaba-cloud-metrics-adapter をクリックします。[リソース] セクションで adapter-config をクリックし、右上隅の [YAML の編集] をクリックします。
既存のコンテンツを以下に置き換え、[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_requestsはnginx_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 自動スケーリング」をご参照ください。

メトリクスの公開状況の確認
次のコマンドを実行して、アダプターが変換されたメトリクスを公開していることを確認します。
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"
}
]
}トラフィックがない場合、value が 0 になるのは正常です。リクエストが到着すると、HPA はゼロ以外の値を受け取ります。
ステップ 4:HPA の作成
各 HPA は単一の Deployment をターゲットとし、selector.matchLabels を使用して共有メトリクスをサービス名でフィルターします。アダプターがメトリクスクエリを実行する際、ラベルセレクター (例:{service="sample-app"}) を <<.LabelMatchers>> プレースホルダーに挿入するため、各 HPA は自身のアプリケーションのリクエストレートのみを参照します。
averageValue: 30 というターゲットは、各 Pod が 1 秒あたり 30 リクエストを超えて処理しないようにすることを意味します。HPA は、実行中のすべての Pod でこの平均を維持するようにレプリカ数を調整します。
次の内容で
hpa.yamlを作成します。マニフェストを適用します。
kubectl apply -f hpa.yamlHPA のステータスを確認します。
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 分かかります。
/homeパス (test-appにルーティングされる) に 5,000 リクエストを送信します。ab -c 50 -n 5000 test.example.com/homeHPA のステータスを確認します。
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 80mtest-hpaは、test-appのリクエストレートが Pod あたり 30 リクエスト/秒のしきい値を超えたため、3 レプリカにスケールアウトしました。sample-appにはトラフィックが到達しなかったため、sample-hpaは 1 レプリカのままでした。ルートパス (
sample-appにルーティングされる) に 5,000 リクエストを送信します。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 96msample-hpaは新しいトラフィックに応答して 2 レプリカにスケールアウトしました。ストレステストが終了した後、test-hpaは 1 レプリカにスケールバックしました。これにより、両方の HPA がそれぞれのアプリケーションメトリクスを個別に追跡していることが確認できます。
次のステップ
複数ゾーンにまたがる高可用性デプロイメントについては、「複数ゾーンにまたがる迅速かつ同時な弾性スケーリングの実装」をご参照ください。
カスタム OS イメージを使用して複雑な環境での弾性スケーリングを簡素化するには、「カスタムイメージによる弾性最適化」をご参照ください。