K8s pod autoscaling with KEDA ¶
Kubernetes, a powerful container orchestration platform, revolutionized the way applications are deployed and managed. However, scaling applications to meet fluctuating workloads can be a complex task. KEDA, a Kubernetes-based Event-Driven Autoscaler, provides a simple yet effective solution to automatically scale Kubernetes Pods based on various metrics, including resource utilization, custom metrics, and external events.
Goal ¶
To install and configure KEDA on an EKS Cluster created on the binbash Leverage way.
Note
To read more on how to create the EKS Cluster on the binbash Leverage way, read here.
Note for the following example we will be using a Kedacore plugin called http-add-on.
Note
To lear more about KEDA read the official site.
Assumptions ¶
We are assuming the binbash Leverage Landing Zone is deployed, an account called apps-devstg
was created and region us-east-1
is being used. In any case you can adapt these examples to other scenarios.
Installation ¶
To install KEDA, just enable it in the components layer here.
Note enable_keda
has to be enabled and, for the next example, also enable enable_keda_http_add_on
.
To read more on how to enable components see here.
Giving it a try! ¶
Now, let's create an example so we can show how KEDA Works
We will deploy a simple NGINX server.
These are the manifests for NGINX.
Let's create a namespace:
apiVersion: v1
kind: Namespace
metadata:
name: demoapps
labels:
name: demoapps
This is the nginx.yaml
:
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-deployment
namespace: demoapps
labels:
app: nginx
spec:
replicas: 1
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx-container
image: nginx:latest
And this is the service.yaml
:
apiVersion: v1
kind: Service
metadata:
name: nginx-svc
namespace: demoapps
spec:
type: NodePort
selector:
app: nginx
ports:
- protocol: TCP
port: 80
targetPort: 80
Deploy the resources using kubectl
.
Info
Note you can use kubectl
through binbash Leverage, for more info read here.
These are the deployed resources:
NAME READY STATUS RESTARTS AGE
pod/nginx-deployment-5bb85d69d8-g997n 1/1 Running 0 55s
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
service/nginx-svc NodePort 10.100.222.129 <none> 80:30414/TCP 54s
NAME READY UP-TO-DATE AVAILABLE AGE
deployment.apps/nginx-deployment 1/1 1 1 56s
NAME DESIRED CURRENT READY AGE
replicaset.apps/nginx-deployment-5bb85d69d8 1 1 1 56s
To try it, create a port-forward to the service and hit it from your browser.
kubectl port-forward -n demoapps svc/nginx-svc 8080:80
Try it!
curl localhost:8080
Now, it has no horizontal autoscaling tool (HPA), so it won't scale. I.e. it always will have one pod (as per the manifests).
Let's create then a KEDA autoscaler!
This is the manifest:
apiVersion: http.keda.sh/v1alpha1
kind: HTTPScaledObject
metadata:
name: nginx-scaledobject
namespace: demoapps
spec:
hosts:
- "thehostname.internal"
targetPendingRequests: 100
scaleTargetRef:
deployment: nginx-deployment
service: nginx-svc
port: 80
replicas:
min: 0
max: 10
It can be seen an HPA and a custom resource were created:
NAME REFERENCE TARGETS MINPODS MAXPODS REPLICAS AGE
horizontalpodautoscaler.autoscaling/keda-hpa-nginx-scaledobject Deployment/nginx-deployment <unknown>/100 (avg) 1 10 0 15s
NAME TARGETWORKLOAD TARGETSERVICE MINREPLICAS MAXREPLICAS AGE ACTIVE
nginx-scaledobject apps/v1/Deployment/nginx-deployment nginx-svc:80 0 10 52s
Note in the HPA no replicas are in place, i.e. no pods for our app. Now if you try:
kubectl port-forward -n demoapps svc/nginx-svc 8080:80
...it will fail, since no pod are available to answer the service.
Instead we have to hit a KEDA intercepter, that will route the traffic using the Hosts in the HTTPScaledObject
object.
We've set thehostname.internal
as the name, so let's port-forward the intercepter...
kubectl port-forward -n keda svc/keda-add-ons-http-interceptor-proxy 8080:8080
...and hit it with the Host header set:
curl localhost:8080 -H "Host: thehostname.internal"
If you check the HPA now it will have at least one replica.
Note
Note the first query will have a delay since the pod has to be created.
Then if you cancel the port-forward and wait for a while, the deployment will be scaled-down to zero again.
Voilà!
Note
There are other ways to configure KEDA, e.g. using Prometheus metrics, read more here.
Final thoughts ¶
Given the scale-to-zero feature for pods, KEDA is a great match to Karpenter!