DEV Community

Cover image for Keda ScaledObject As Code Using CDK8S
๐Ÿš€ Vu Dao ๐Ÿš€ for AWS Community Builders

Posted on โ€ข Edited on

8 2

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 of managing project configuration as code.
  • Getting started with cdk8s

๐Ÿš€ 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 found the manifest in GH release section. Here I import the current latest version of keda v2.8.0 and output the imports folder in src/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


Enter fullscreen mode Exit fullscreen mode
  • Import result ```

โšก $ tree src/imports/
src/imports/
โ””โ”€โ”€ keda.sh.ts

0 directories, 1 file


## ๐Ÿš€ **Write code** <a name="Write-code"></a>
- Overview of keda scaledObjects in this post

  <img src=https://raw.githubusercontent.com/vumdao/keda-hands-on/master/docs/images/flow.png width=900>

- It's much more convinient 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 usecase of creating scaledObject (SO) for Apache airflow worker component. It contains 3 triggers (Scalers) in the SO

### 1. [Cron](https://keda.sh/docs/2.8/scalers/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](https://keda.sh/docs/2.8/scalers/postgresql/) - Scale applications based on a PostgreSQL query.
  - This scaler bases on the output of query command to scaleout works, here we count the number of running/queued airflow task instances belongs to scheduled pipeline (eg. running reports). Divide the count number to 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](https://keda.sh/docs/2.8/scalers/cpu/) - Scale applications based on cpu metrics
  - This is optional as it ensure provisioning workers when CPU Utilization is higher than 80%

- PostgreSQL Scaler requires `TriggerAuthentication` to provide password of airflow user in order to query the database. The credential is get from K8S secret `airflow-secret` within the `airflow` namespace
Enter fullscreen mode Exit fullscreen mode
const pgAuth = new TriggerAuthentication(this, 'KedaPostgresAuthentication', {
  metadata: {
    name: 'keda-airflow-postgresql-auth',
    namespace: 'airflow',
  },
  spec: {
    secretTargetRef: [{
      parameter: 'password',
      name: 'airflow-secret',
      key: 'postgresql-password',
    }],
  },
});
Enter fullscreen mode Exit fullscreen mode

- 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 this vaule.
  - `cooldownPeriod`: The period to wait after the last trigger reported active before scaling the resource back to 0.

## ๐Ÿš€ **Build keda scaledobjects from code** <a name="Build-keda-scaledobjects-from-code"></a>
- Source code:
Enter fullscreen mode Exit fullscreen mode

โšก $ tree src/
src/
โ”œโ”€โ”€ imports
โ”‚ โ””โ”€โ”€ keda.sh.ts
โ”œโ”€โ”€ keda-airflow.ts
โ””โ”€โ”€ main.ts

1 directory, 3 files


- Build resource
Enter fullscreen mode Exit fullscreen mode

โšก $ 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
Enter fullscreen mode Exit fullscreen mode

โšก $ tree dist/
dist/
โ””โ”€โ”€ keda
โ””โ”€โ”€ airflow-keda-so.yaml

1 directory, 1 file


## ๐Ÿš€ **Apply and test** <a name="Apply-and-test">
- Apply manifest and check result
Enter fullscreen mode Exit fullscreen mode

# 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 <a name="Conclusion"></a>
- Within the Scaledobject class, you can jump to definition to understand the meaning of each properties and also know which required/optional attributes.
- We can create a custom construct and base on that to provision multiple KEDA scaledobjects with customize specs/meta such as min/max/desired replicas, triggers, trigger authentication, etc.

---





Enter fullscreen mode Exit fullscreen mode

Top comments (2)

Collapse
 
jackpham85 profile image
jackpham85 โ€ข

It is really useful for me. That is a great example. Thanks

Collapse
 
vumdao profile image
๐Ÿš€ Vu Dao ๐Ÿš€ โ€ข โ€ข Edited

. #KEDA and #Karpenter together help us scaling down to zero the Dev/Test clusters at non-working hours and scaling up automatically before working time.

Here is an example of scaling down/up Solr at 9PM/7AM


apiVersion: keda.sh/v1alpha1
kind: ScaledObject
metadata:
name: solr1
spec:
minReplicaCount: 0
scaleTargetRef:
kind: StatefulSet
name: solr1
triggers:
- metadata:
desiredReplicas: "1"
end: 0 21 * * *
start: 0 7 * * *
timezone: Asia/Ho_Chi_Minh
type: cron

Best Practices for Running  Container WordPress on AWS (ECS, EFS, RDS, ELB) using CDK cover image

Best Practices for Running Container WordPress on AWS (ECS, EFS, RDS, ELB) using CDK

This post discusses the process of migrating a growing WordPress eShop business to AWS using AWS CDK for an easily scalable, high availability architecture. The detailed structure encompasses several pillars: Compute, Storage, Database, Cache, CDN, DNS, Security, and Backup.

Read full post