Horizontal Pod Autoscaler(HPA)とは?

Horizontal Pod Autoscaling (HPA) は、各種メトリクスからアプリケーションのPodをオートスケールできるようにする機能です。

HPAはKubernetes v1.2 で導入されました。当時はmetrics-server というリソースからアクセスする CPU などの基本的なメトリクスからのみオートスケールすることが可能でしたが、Kubernetes v1.6では、クラスター内から収集されたユーザー定義のカスタム外部メトリクスからのオートスケールが可能になりました。また、Kubernetes v1.10では外部メトリクスのサポートが導入され、ユーザーはクラスタ外からの任意のメトリクスからオートスケールを行うことができるようになりました。

HPAのメリット

  • 要求に応じてPodを手動で追加・削除する必要がなくなります
  • トラフィックの急増にうまく対応でき、サービスのパフォーマンスを維持しやすくなります
  • 固定数のPodを割り当てる場合と比較して、より合理的・経済的にリソースを利用することができるようになります

Metrics Adapterの仕組み

New Relic Metrics Adapterは、アプリケーションや、Webサーバーが1秒間に受け取ったリクエスト数など、New RelicのTelemetry Data Platformに保存されている各種データを使ってPodをオートスケールできるようになります。Metrics Adapterは、NRQLクエリに基づいてNR NerdGraph APIからメトリクス値を取得し、この値をKubernetesの外部メトリクスAPIに送信します。これにより、HPAは外部メトリクスに基づきPodをスケールすることができるようになります。

metrics adapter architecture

Metrics Adapterのインストール方法

Metrics Adapterをインストールするには、newrelic-k8s-metrics-adapterHelmチャートを適用します。これは、New RelicのKubernetes integrationをインストールする際に使用するnri-bundleのGroupsチャートにも含まれています。

  1. New Relic Kubernetes integrationをインストールしていない場合はインストールします。
  2. 次のコマンドを使用して、インストールをアップグレードし、New Relic MetricsAdapterを含めます。もちろん、初期のインストール時にこれらのフラグを指定することも可能です。
helm upgrade --install newrelic newrelic/nri-bundle \
--namespace newrelic --create-namespace --reuse-values \
--set metrics-adapter.enabled=true \
--set newrelic-k8s-metrics-adapter.personalAPIKey=YOUR_NEW_RELIC_PERSONAL_API_KEY \
--set newrelic-k8s-metrics-adapter.config.accountID=YOUR_NEW_RELIC_ACCOUNT_ID \
--set newrelic-k8s-metrics-adapter.config.externalMetrics.external_metric_name.query=NRQL query

大事なのは以下の2つのオプションです。

  1. newrelic-k8s-metrics-adapter.personalAPIKey :
    • ここはエージェントインストール時に使うライセンスキーではなく、User API Keyになります。あらかじめ作成して設定しましょう
  2. newrelic-k8s-metrics-adapter.config.externalMetrics.external_metric_name.query
    • HPAで使用したいデータを取得するクエリをメトリクス名を指定します。ここでexternal_metric_name部分にはクエリで取得したデータのメトリクス名を指定します。例えばnginxのリクエスト数でスケールさせたい場合はexternal_metric_name部分をnginx_average_requestsなどとしておき、実際のクエリは以下のように指定しておきます

FROM Metric SELECT average(nginx.server.net.requestsPerSecond) SINCE 2 MINUTES AGO

本例のhelm upgrade時のvalueへの設定例は以下ようになります。

helm upgrade --install newrelic newrelic/nri-bundle \
--namespace newrelic --create-namespace --reuse-values \
--set metrics-adapter.enabled=true \
--set newrelic-k8s-metrics-adapter.personalAPIKey=YOUR_NEW_RELIC_PERSONAL_API_KEY \
--set newrelic-k8s-metrics-adapter.config.accountID=YOUR_NEW_RELIC_ACCOUNT_ID \
--set newrelic-k8s-metrics-adapter.config.externalMetrics.nginx_average_requests.query="FROM Metric SELECT average(nginx.server.net.requestsPerSecond) SINCE 2 MINUTES AGO"

これでNew Relic側の設定は完了です。続いてクラスター側でHPAのマニフェストを作成していきます。

HPA側の設定方法

例えばnginxのリクエスト量をもとにスケールしたい場合は、以下のようにHPA側を設定します。New Relic側で設定するメトリクス名をnginx_average_requestsとした場合、マニフェストは以下のようになります。

kind: HorizontalPodAutoscaler
apiVersion: autoscaling/v2beta2
metadata:
  name: nginx-scaler
spec:
  scaleTargetRef:
    apiVersion: apps/v1
    kind: Deployment
    name: nginx
  minReplicas: 1
  maxReplicas: 10
  metrics:
    - type: External
      external:
        metric:
          name: nginx_average_requests
          selector:
            matchLabels: 
              k8s.namespaceName: nginx
        target:
          type: Value 
          value: 10000

これで、HPA側はnginx_average_requestsのメトリクスをベースにスケーリングすることになります。そして、その値はMetrics Adapterで設定したクエリを実行した結果になります。

データはMetric以外からも取得可能

上記の例はMetricからデータを収集しましたが、New Relicに保存されているデータであればどんなデータでもOKです。例えば、以下のような、アプリケーションのパフォーマンス状況をベースにしたスケーリング条件も簡単に作成できます。

  • アプリケーション全体のレイテンシー
  • 負荷の高い特定機能のアクセス数やレイテンシー
  • エラーレート

まとめ

New Relic Metrics Adapterを使用することで、Podのオートスケーリングに使用するデータをクラスター内に保持しておく必要がなくなりました。これは、クラスター内に各種メトリクスなどのテレメトリーデータを保存するデータベースの運用から開放されます。運用のための運用をまたひとつ軽減することが可能になります。

また、New Relic内に保存されている様々なデータをもとに条件を作成することができるので、よりアプリケーションの挙動に応じたスケーリングを実現可能になります。

ぜひ、Metrics Adapterを使ってより良いクラスター運用を実現してください!