🖥️

[Kubernetes]Datadog Metricsを利用してHPAしてみる

2024/05/23に公開

概要

CPU/Memory以外にアクセス数や何らかの集計をした値を元にHPAしたくなるケースがあるかと思います。
そんな際にもしDatadogを利用している場合には、Custom Metrics Serverを利用することでより柔軟なHPAが可能となります。

Custom Metrics

K8sが metrics.k8s.io というAPIを公開しており、それを利用することで文字通りカスタマイズしたメトリクスを利用してHPAしてくれるようです。

Provided that you use the autoscaling/v2 API version, you can configure a HorizontalPodAutoscaler to scale based on a custom metric (that is not built in to Kubernetes or any Kubernetes component). The HorizontalPodAutoscaler controller then queries for these custom metrics from the Kubernetes API.

https://kubernetes.io/docs/tasks/run-application/horizontal-pod-autoscale/#scaling-on-custom-metrics

https://github.com/DataDog/helm-charts/tree/main/charts/datadog#custom-metrics-server

詳しいことはこちらも参考にしてみてください(2019年の情報なのでそこから更新はありそうですが、大枠の理解は捗ると思います)。
https://qiita.com/loftkun/items/9170877ad3b345016c7a

今回はDatadogを中心にしていますが、Prometheus, Prometheus Adapterを利用することでも同様にカスタマイズしたメトリクスを利用してHPAができます。
例えばこちらがわかりやすかったです。
https://zenn.dev/lapi/articles/e7ae967aa5161b

実装

DatadogのHelm Chart的には以下のようなvalues.yamlにします。
custom metricsを利用するためには datadog.datadog.appKeydatadog.clusterAgent の設定が必要です。

datadog:
  datadog:
    apiKey: ${datadog_api_key}
    appKey: ${datadog_app_key}
  clusterAgent:
    enabled: true
    # DatadogMetricのための設定はこのあたり
    # Ref: https://docs.datadoghq.com/ja/containers/cluster_agent/external_metrics/?tab=helm
    metricsProvider:
      enabled: true
      useDatadogMetrics: true

続いてカスタムメトリクスとして以下のような定義を書きます。

apiVersion: datadoghq.com/v1alpha1
kind: DatadogMetric
metadata:
  name: nginx-autoscale
spec:
  query: sum:istio_requests.count{kube_deployment:nginx}.rollup(avg, 10)

spec.query はDatadogの Metrics Explorer から動作確認ができるのでデバッグが非常にやりやすいです。

DeploymentとHPAの設定はそれぞれ以下のような感じです。

apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx
spec:
  replicas: 1 # HPAに任せる
  selector:
    matchLabels:
      app: nginx
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
        - image: nginx
          name: nginx
          ports:
            - containerPort: 80
---
apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
  name: nginx-hpa
spec:
  scaleTargetRef:
    apiVersion: apps/v1
    kind: Deployment
    name: nginx
  minReplicas: 1
  maxReplicas: 10
  metrics:
  # `External`はkubernetesクラスタ内のリソースとは関係しないメトリクスを利用する際に指定するらしい
  # Ref: https://kubernetes.io/ja/docs/tasks/run-application/horizontal-pod-autoscale-walkthrough/#%E8%A4%87%E6%95%B0%E3%81%AE%E3%83%A1%E3%83%88%E3%83%AA%E3%82%AF%E3%82%B9%E3%82%84%E3%82%AB%E3%82%B9%E3%82%BF%E3%83%A0%E3%83%A1%E3%83%88%E3%83%AA%E3%82%AF%E3%82%B9%E3%82%92%E5%9F%BA%E3%81%AB%E3%82%AA%E3%83%BC%E3%83%88%E3%82%B9%E3%82%B1%E3%83%BC%E3%83%AA%E3%83%B3%E3%82%B0%E3%81%99%E3%82%8B
  - type: External
    external:
      metric:
        # datadogmetric@<namespace>:<datadogmetric_name>の形式で定義する
        name: datadogmetric@default:nginx-autoscale
      # 対象のmetricsをPod数で割った値がこの値に近づくように目指してscale-in/outする
      target:
        type: AverageValue
        averageValue: 1k

注意点

HPA設定後に実際にメトリクスが取れてない(まだそのメトリクスを取得するためのアクセスが発生していない)場合にはdatadog cluster agentで以下のようなエラーが出ます。

"Failed to compute desired number of replicas based on listed metrics."

何か設定ミスしたのかな?となるエラー文なのでとても困りますが、メトリクスが取れるようになったら正常に動いてくれるようになります。

It normally means that no data is available for avg:kubernetes.cpu.usage{app:myapp,release:myapp}.rollup(30), you can put this query in a Notebook to visualize the data used for autoscaling.

https://github.com/DataDog/watermarkpodautoscaler/issues/102

その他参考

https://speakerdeck.com/chaspy/v2beta2-and-examples-of-using-hpa-external-metrics-with-datadog

https://engineering.mercari.com/blog/entry/20220218-cd149f6298/

https://blog.studysapuri.jp/entry/2020/11/30/scheduled-scaling-with-hpa

Discussion