Autoscaling using datadog as a external metrics provider

kubernetes hpa datadog external metrics

3 min read | by Jordi Prats

Since Kubernetes v1.2 we can autoscale an application based on metrics like CPU provided by the metrics-server. As of Kubernetes v1.6, it is possible to autoscale off of custom metrics and later on, starting Kubernetes v1.10, we can autoscale using any metric from outside the cluster, like the ones collected by datadog

To be able to configure an HPA object to use datadog's metrics we will have to enable the metrics provider. If we are using it's helm chart to deploy the Cluster Agent we will have to set the following values:

datadog:  appKey: abcd...  apiKey: efgh... clusterAgent:  enabled: true  metricsProvider:  enabled: true 

Once the Cluster Agent have been upgraded and the metrics provider is available:

$ kubectl get pods -n datadog NAME READY STATUS RESTARTS AGE datadog-2pc4x 3/3 Running 0 7m13s datadog-cluster-agent-6cc7cf55d6-6946r 1/1 Running 1 120m datadog-kube-state-metrics-699964c777-wrkwz 1/1 Running 0 100m datadog-xk79r 3/3 Running 0 6m49s $ kubectl get apiservice | grep datadog v1beta1.external.metrics.k8s.io datadog/datadog-cluster-agent-metrics-api True 100m 

We can now start pushing HPA objects with references to external metrics, for example:

apiVersion: autoscaling/v2beta1 kind: HorizontalPodAutoscaler metadata:  name: ampa spec:  scaleTargetRef:  apiVersion: apps/v1  kind: Deployment  name: ampa  minReplicas: 2  maxReplicas: 22  metrics:  - type: External  external:  metricName: kubernetes.kubelet.cpu.usage  metricSelector:  matchLabels:  cluster_name: example  targetAverageValue: 50 

The important setting that controls how the HPA behaves are:

  • metricName: Defines the metrics we are going to use to autoscale, it can be any metric that the Cluster Agent retrieves, for example kubernetes_state.deployment.replicas_available or kubernetes.kubelet.cpu.usage
  • metricsSelector.matchLabels: We can specify a set of tags we are going to use to filter the metric
  • targetValue or targetAverageValue: We are setting the desired value of the metric that will be used to scale up and down the objecy defined under spec.scaleTargetRef. If we use targetValue, it's values is the absolute value. For targetAverageValue we are defining the individual value for each replica (so it divides the value by the number of replicas)

We can achieve similar results using prometheus as an external metrics provider

Update: To use the final autoscaling/v2 version there are some minor changes:

apiVersion: autoscaling/v2 kind: HorizontalPodAutoscaler metadata:  name: ampa spec:  minReplicas: 2  maxReplicas: 22  scaleTargetRef:  apiVersion: apps/v1  kind: Deployment  name: spin-fiat  metrics:  - type: External  external:  metric:  name: kubernetes.kubelet.cpu.usage  selector:  matchLabels:  cluster_name: example  target:  averageValue: "50"  type: AverageValue 

We can use kubectl convert to adjust the existing manifests.


Posted on 10/01/2022

Categories