Kubernetes pod scaling by custom metrics with Keda

$ mkdir keda && cd keda
$ kubectl create ns keda
$ helm repo add kedacore https://kedacore.github.io/charts && helm repo update
$ helm install keda kedacore/keda --namespace keda # --set logLevel=debug
$ kubectl get --raw "/apis/external.metrics.k8s.io/v1beta1" | jq
{
"kind": "APIResourceList",
"apiVersion": "v1",
"groupVersion": "external.metrics.k8s.io/v1beta1",
"resources": []
}
export NS_NAME=scale-by-aws-sqs
export REGION=us-east-1
export QUEUE_NAME=keda-test
export QueueURL=$(aws sqs create-queue --queue-name=${QUEUE_NAME} --region=$REGION --output=text --query=QueueUrl)
export AWS_ACCESS_KEY_ID=$(cat ~/.aws/credentials | grep access_key_id | awk '{ print $(NF)}')
export AWS_SECRET_ACCESS_KEY=$(cat ~/.aws/credentials | grep secret_access_key | awk '{ print $(NF)}')
export SQS_IMAGE='jamalshahverdiev/keda-aws-sqs-consumer:latest'
export KEDA_SCALEDOBJECT_TEMPLATE_FILE=keda-scaledobject-template.yaml
export DEPLOYMENT_TEMPLATE_FILE=consumer-deployment-template.yaml
export KEDA_TRIGGER_TEMPLATE=keda-trigger-template.yaml
export KEDA_TRIGGER_NAME=keda-trigger-auth-aws-credentials
export KEDA_DEPLOYMENT_NAME=keda-scale-by-aws-sqs
export CONATNER_NAME=sqs-consumer
export SECRET_NAME=${NS_NAME}-secrets
$ cat <<'EOF' > ${KEDA_TRIGGER_TEMPLATE}
---
apiVersion: keda.sh/v1alpha1
kind: TriggerAuthentication
metadata:
name: ${KEDA_TRIGGER_NAME}
namespace: ${NS_NAME}
spec:
secretTargetRef:
- parameter: awsAccessKeyID
name: ${SECRET_NAME}
key: AWS_ACCESS_KEY_ID
- parameter: awsSecretAccessKey
name: ${SECRET_NAME}
key: AWS_SECRET_ACCESS_KEY
EOF
$ cat <<'EOF' > ${KEDA_SCALEDOBJECT_TEMPLATE_FILE}
---
apiVersion: keda.sh/v1alpha1
kind: ScaledObject
metadata:
name: app-${NS_NAME}
namespace: ${NS_NAME}
spec:
scaleTargetRef:
name: ${KEDA_DEPLOYMENT_NAME}
triggers:
- type: aws-sqs-queue
authenticationRef:
name: ${KEDA_TRIGGER_NAME}
metadata:
queueURL: ${QueueURL}
awsRegion: "${REGION}"
queueLength: "5"
EOF
$ cat <<'EOF' > ${DEPLOYMENT_TEMPLATE_FILE}
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: ${KEDA_DEPLOYMENT_NAME}
namespace: ${NS_NAME}
spec:
selector:
matchLabels:
service: ${KEDA_DEPLOYMENT_NAME}
replicas: 1
template:
metadata:
labels:
service: ${KEDA_DEPLOYMENT_NAME}
spec:
containers:
- image: ${SQS_IMAGE}
name: ${CONATNER_NAME}
env:
- name: AWS_ACCESS_KEY_ID
valueFrom:
secretKeyRef:
name: ${SECRET_NAME}
key: AWS_ACCESS_KEY_ID
- name: AWS_SECRET_ACCESS_KEY
valueFrom:
secretKeyRef:
name: ${SECRET_NAME}
key: AWS_SECRET_ACCESS_KEY
- name: AWS_DEFAULT_REGION
value: ${REGION}
EOF
$ cat <<'EOF' > create_queue_with_object.sh
#!/usr/bin/env bash
kubectl create namespace ${NS_NAME}
kubectl create secret generic ${SECRET_NAME} --namespace=${NS_NAME} --from-literal=AWS_ACCESS_KEY_ID=$AWS_ACCESS_KEY_ID --from-literal=AWS_SECRET_ACCESS_KEY=$AWS_SECRET_ACCESS_KEY
for file in ${KEDA_SCALEDOBJECT_TEMPLATE_FILE} ${DEPLOYMENT_TEMPLATE_FILE} ${KEDA_TRIGGER_TEMPLATE}; do
cat ${file} | envsubst > ${file}_rendered && kubectl apply -f ${file}_rendered
done
EOF
$ chmod +x create_queue_with_object.sh && ./create_queue_with_object.sh
$ kubectl get triggerauthentications.keda.sh -n scale-by-aws-sqs
NAME PODIDENTITY SECRET ENV VAULTADDRESS
keda-trigger-auth-aws-credentials scale-by-aws-sqs-secrets
$ kubectl get scaledobjects.keda.sh -n scale-by-aws-sqs
NAME SCALETARGETKIND SCALETARGETNAME MIN MAX TRIGGERS AUTHENTICATION READY ACTIVE FALLBACK AGE
app-scale-by-aws-sqs apps/v1.Deployment keda-scale-by-aws-sqs aws-sqs-queue keda-trigger-auth-aws-credentials True False False 5m39s
$ kubectl get horizontalpodautoscalers.autoscaling -n scale-by-aws-sqs
NAME REFERENCE TARGETS MINPODS MAXPODS REPLICAS AGE
keda-hpa-app-scale-by-aws-sqs Deployment/keda-scale-by-aws-sqs 0/5 (avg) 1 100 1 6m1s
$ kubectl logs -f -n keda $(kubectl get pods -n keda | grep keda-operator | awk '{ print $1 }')
$ kubectl scale deployment --replicas 0 -n $NS_NAME $KEDA_DEPLOYMENT_NAME
$ for x in {1..200}; do
result=$(aws sqs send-message --message-body="Queue message number ${x}" --queue-url=$QueueURL --region=$REGION)
echo ${result}
done
$ watch -n2 "kubectl get pods -n ${NS_NAME} | wc -l"
$ watch -n2 "kubectl get pods -n ${NS_NAME}"

--

--

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store