Because native HPA only offers scaling by memory and CPU, extending its capabilities with KEDA is fundamental to achieving reliable resource autoscaling.
Before KEDA 2.11.0, replacing your HPA resources with ScaledObjects would require the deletion of the existing HPA before you create a new ScaledObject for a deployment resource.
If your platform team is currently introducing KEDA to your organization, instead of requesting planned updates for existing applications, the teams can now progressively update their HPA resource, or your platform team can programmatically send pull requests updating all the HPA manifests to perform an HPA take-over across all your company HPA resources.
Given you already have a deployment and an HPA in place:
apiVersion: apps/v1 kind: Deployment metadata: labels: app: example-service name: example-service spec: selector: matchLabels: app: example-service replicas: 2 template: metadata: labels: app: example-service spec: containers: - name: nginx image: nginxinc/nginx-unprivileged resources: limits: cpu: 700m memory: 500Mi requests: cpu: 100m memory: 300Mi ports: - containerPort: 80 --- apiVersion: autoscaling/v2 kind: HorizontalPodAutoscaler metadata: name: example-service spec: scaleTargetRef: apiVersion: apps/v1 kind: Deployment name: example-service minReplicas: 2 maxReplicas: 10 metrics: - resource: name: cpu target: averageUtilization: 50 type: Utilization type: Resource - resource: name: memory target: averageUtilization: 50 type: Utilization type: Resource
You can replace the existing HPA with a ScaledObject including the same inputs, as well as extend functionalities with scalers such as CronJobs:
apiVersion: keda.sh/v1alpha1 kind: ScaledObject metadata: name: example-service annotations: scaledobject.keda.sh/transfer-hpa-ownership: "true" # Use to transfer an existing HPA ownership to this ScaledObject spec: scaleTargetRef: apiVersion: apps/v1 kind: Deployment name: example-service minReplicaCount: 2 maxReplicaCount: 10 advanced: horizontalPodAutoscalerConfig: name: example-service # Custom HPA name is required and should match the existing HPA name triggers: - type: memory metricType: AverageValue metadata: value: "50" - type: cpu metricType: AverageValue metadata: value: "50" - type: cron metadata: timezone: America/Chicago # The acceptable values would be a value from the IANA Time Zone Database. start: 0 8 * * 1-6 # At 08:00 on every day-of-week from Monday through Saturday. end: 0 18 * * 1-6 # At 18:00 on every day-of-week from Monday through Saturday. desiredReplicas: "5" - type: new-relic metadata: nrql: "SELECT rate(count(apm.service.transaction.duration), 1 second) as 'Web throughput' FROM Metric WHERE (appName like 'example-service-%') AND (transactionType = 'Web') since 20 seconds ago" threshold: '10' authenticationRef: name: __REDACTED__ kind: ClusterTriggerAuthentication
By using the combination of the annotation
autoscaling.keda.sh/transfer-hpa-ownership: "true" and by setting
advanced.horizontalPodAutoscalerConfig.name to match the existing HPA name, you are able to achive drop-in replacement of the HPA resource without any disruption.
This is an experimental feature. We encourage you to try it out in your cluster and report back what you find.