Keda ScaledObject As Code Using CDK8S
Abstract
keda is Kubernetes Event-driven Autoscaling and it's been used wisely now. In this blog, it provides the way to create Keda scaledobject CRD as code using CDK8S typescript.
With importing Keda CRDs and using CDK8S you can create Keda scaledobjects using your familiar programming languages such as typescript as scale.
Table Of Contents
๐ Pre-requisite
Install typescript, node, and cdk8s as well as projen (optional) which is a tool for managing project configuration as code.
๐ Overview of Keda
KEDA works alongside standard Kubernetes components like the Horizontal Pod Autoscaler and can extend functionality without overwriting or duplication.
KEDA supports multiple triggers within an Scaledobject. Each trigger is exposed split as a metric and the HPA Controller does a MAX between all the metrics.
๐ Import Keda CRDs
Keda does not provide its CRDs separately so we can find the manifest in GH release section. Here I import the current latest version of keda v2.8.0 and output the
imports
folder insrc/imports
โก $ cdk8s import https://github.com/kedacore/keda/releases/download/v2.8.0/keda-2.8.0.yaml --output src/imports/ ------------------------------------------------------------------------------------------------ A new version 2.0.88 of cdk8s-cli is available (current 2.0.13). Run "npm install -g cdk8s-cli" to install the latest version on your system. For additional installation methods, see https://cdk8s.io/docs/latest/getting-started ------------------------------------------------------------------------------------------------ Importing resources, this may take a few moments... keda.sh keda.sh/clustertriggerauthentication keda.sh/scaledjob keda.sh/scaledobject keda.sh/triggerauthentication
Import result
โก $ tree src/imports/ src/imports/ โโโ keda.sh.ts 0 directories, 1 file
๐ Write code
Overview of keda scaledObjects in this post
It's much more convenient to use visual code writing KEDA scaledobject in typescript language. We can read the document and find all references of construct, objects and properties of KEDA CRDs
This blog provides the use case of creating scaledObject (SO) for Apache airflow worker component. It contains 3 triggers (Scalers) in the SO
1. Cron - Scale applications based on a cron schedule.
- Airflow server scheduled pipelines and worker components are scaled out at that time, but it takes time to start nodes, join node to cluster and Pod ready (about 2-3mins) so we use cron to pre-scale workers
2. PostgreSQL - Scale applications based on a PostgreSQL query.
This scaler based on the output of the query command to scaleout works, here we count the number of running/queued airflow task instances belonging to the scheduled pipeline (eg. running reports). Divide the count number by Airflow worker concurrency (eg. 16 as default)
targetQueryValue: '1.5'
- The result of above calculation divide to this target value to decide how many pods will be scaled out
3. CPU - Scale applications based on cpu metrics
This is optional as it ensures provisioning workers when CPU Utilization is higher than 80%
PostgreSQL Scaler requires
TriggerAuthentication
to provide a password of airflow user in order to query the database. The credential is get from K8S secretairflow-secret
within theairflow
namespaceconst pgAuth = new TriggerAuthentication(this, 'KedaPostgresAuthentication', { metadata: { name: 'keda-airflow-postgresql-auth', namespace: 'airflow', }, spec: { secretTargetRef: [{ parameter: 'password', name: 'airflow-secret', key: 'postgresql-password', }], }, });
Some SO specs need to know
pollingInterval
: This is the interval to check each trigger on. By default KEDA will check each trigger source on every ScaledObject every 30 seconds. So to reduce the query connections/workload to airflow database we need to care about this value.cooldownPeriod
: The period to wait after the last trigger is reported active before scaling the resource back to 0.
๐ Build keda scaledobjects from code
Source code:
โก $ tree src/ src/ โโโ imports โ โโโ keda.sh.ts โโโ keda-airflow.ts โโโ main.ts 1 directory, 3 files
Build resource
โก $ npx projen build ๐พ build ยป default | ts-node --project tsconfig.dev.json .projenrc.ts ๐พ build ยป compile | tsc --build ๐พ build ยป post-compile ยป synth | cdk8s synth No manifests synthesized ๐พ build ยป test | jest --passWithNoTests --all --updateSnapshot No tests found, exiting with code 0 ----------|---------|----------|---------|---------|------------------- File | % Stmts | % Branch | % Funcs | % Lines | Uncovered Line #s ----------|---------|----------|---------|---------|------------------- All files | 0 | 0 | 0 | 0 | ----------|---------|----------|---------|---------|------------------- ๐พ build ยป test ยป eslint | eslint --ext .ts,.tsx --fix --no-error-on-unmatched-pattern src test build-tools projenrc .projenrc.ts
Manifest yaml file
โก $ tree dist/ dist/ โโโ keda โโโ airflow-keda-so.yaml 1 directory, 1 file
๐ Apply and test
Apply manifest and check the result
# k apply -f dist/keda/airflow-keda-so.yaml # k get so -n airflow NAME SCALETARGETKIND SCALETARGETNAME MIN MAX TRIGGERS AUTHENTICATION READY ACTIVE FALLBACK AGE airflow-worker-1 apps/v1.StatefulSet airflow-worker 2 12 cron keda-airflow-postgresql-auth True True False 2d21h # k get hpa -n airflow NAME REFERENCE TARGETS MINPODS MAXPODS REPLICAS AGE keda-hpa-airflow-worker-1 StatefulSet/airflow-worker 500m/1 (avg), 500m/1 (avg) + 2 more... 2 12 2 2d21h
๐ Conclusion
Within the Scaledobject class, you can jump to the definition to understand the meaning of each property and also know which required/optional attributes.
We can create a custom construct and based on that provision multiple KEDA scaledobjects with customised specs/meta such as min/max/desired replicas, triggers, trigger authentication, etc.
Subscribe to my newsletter
Read articles from Vu Dao directly inside your inbox. Subscribe to the newsletter, and don't miss out.
Written by
Vu Dao
Vu Dao
๐ AWSome Devops | AWS Community Builder | AWS SA || โ๏ธ CloudOpz โ๏ธ