# Autoscaling based on custom metrics ### Deploy an app with custom metrics ```shell cat <<EOF | kubectl apply -f - kind: ServiceMonitor apiVersion: monitoring.coreos.com/v1 metadata: name: sample-app labels: app: sample-app spec: selector: matchLabels: app: sample-app endpoints: - port: http interval: 30s --- apiVersion: v1 kind: Service metadata: name: sample-app labels: app: sample-app spec: ports: - name: http port: 8080 targetPort: 8080 selector: 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: luxas/autoscale-demo:v0.1.2 name: metrics-provider ports: - name: http containerPort: 8080 EOF ``` ### Create KEDA ScaledObject ```shell cat <<EOF | kubectl apply -f - apiVersion: keda.sh/v1alpha1 kind: ScaledObject metadata: name: prometheus-scaledobject namespace: default spec: scaleTargetRef: name: sample-app pollingInterval: 30 cooldownPeriod: 60 minReplicaCount: 1 maxReplicaCount: 10 advanced: horizontalPodAutoscalerConfig: behavior: scaleDown: stabilizationWindowSeconds: 60 policies: - type: Percent value: 100 periodSeconds: 15 scaleUp: stabilizationWindowSeconds: 0 triggers: - type: prometheus metadata: serverAddress: http://prometheus-operated.kubesphere-monitoring-system.svc:9090 metricName: http_requests_total threshold: '100' query: sum(rate(http_requests_total{service="sample-app"}[2m])) EOF ``` ### Check custom metrics exposed ```shell kubectl get --raw "/apis/external.metrics.k8s.io/v1beta1" | jq . kubectl get scaledobjects.keda.sh prometheus-scaledobject -o jsonpath={.metadata.labels} kubectl get --raw "/apis/external.metrics.k8s.io/v1beta1/namespaces/default/prometheus-http---prometheus-operated-kubesphere-monitoring-system-svc-9090-http_requests_total?labelSelector=scaledobject.keda.sh/name=prometheus-scaledobject" | jq . ``` ### Autoscaling based on custom metrics ```shell ## watch the sample-app to scale watch kubectl get deployment sample-app ## Put some load on the app kubectl run utils -it --image arunvelsriram/utils bash wget https://hey-release.s3.us-east-2.amazonaws.com/hey_linux_amd64 mv hey_linux_amd64 hey && chmod +x hey ./hey -c 20 -n 100000000 http://sample-app.default.svc:8080/metrics ```