En los últimos artículos que he escrito sobre Kubernetes me estoy centrando en todo lo que tiene que ver con la monitorización, tanto con Prometheus como con Azure Monitor por ahora, y el autoescalado. Hoy quiero hablarte de KEDA, otra forma de autoescalar tus aplicaciones en base a eventos externos.
¿Qué es KEDA?
KEDA son las siglas de Kubernetes-based Event Driven Autoscaling. Se trata de un componente que puedes desplegar en tu clúster de Kubernetes, esté donde esté, y que te ayuda a autoescalar tus aplicaciones en base a diferentes eventos, utilizando lo que llama scalers. Estos pueden ser mensajes en colas de mensajería de diferentes plataformas (Apache Kafka, AWS SQS Queue, RabbitMQ Queue, Azure Event Hubs, etc), bases de datos (MySQL, PostgreSQL) o incluso servidores de métricas como Prometheus, AWS Cloudwatch o Azure Monitor. La lista va creciendo cada vez más y más.
Una vez decidido cuál será el evento que hará escalar tu aplicación, se crea un recurso llamado ScaledObject con el scaler oportuno y KEDA, por debajo, crea un HorizontalPodAutoscaler por nosotros y lo asocia a dicho recurso para saber cuándo tiene que subir o bajar el número de réplicas de nuestro Deployment o Job.

Instalar KEDA en tu clúster
Antes de comenzar a utilizar KEDA necesitas desplegarlo en tu Kubernetes. La forma más sencilla es a través de Helm:
#Install helm 3 if you don't have it
brew install helm
#Add KEDA repo to Helm
helm repo add kedacore https://kedacore.github.io/charts
#Update Helm repo
helm repo update
#My cluster info
RESOURCE_GROUP="KEDA"
AKS_NAME="aks-keda"
#Get AKS credentials
az aks get-credentials --resource-group $RESOURCE_GROUP --name $AKS_NAME
#Create a namespace called keda
kubectl create namespace keda
#Install keda components inside the namespace
helm install keda kedacore/keda --namespace keda
#See pods
kubectl get pods --namespace kedaEn este ejemplo estoy utilizando Helm 3 en Mac. Si no lo tienes instalado puedes hacerlo a través de Homebrew con la primera línea del código anterior. Añade el repo de KEDA y asigna a kubectl las credenciales del clúster donde quieres desplegarlo. Crea un namespace llamado keda y en él instala los componentes a través del chart kedacore/keda. Si todo ha salido bien deberías de ver dos pods dentro de ese namespace:
➜ kubectl get pods -n keda
NAME READY STATUS RESTARTS AGE
keda-operator-5895ff46b9-jbxbn 1/1 Running 0 20s
keda-operator-metrics-apiserver-6774776dbc-4nnhs 1/1 Running 0 20sDesplegar una aplicación de ejemplo
Ahora que ya tienes KEDA desplegado lo siguiente que necesitas es una aplicación que autoescalar. Da igual lo que sea, ya que vamos a hacerla subir o bajar en réplicas en base a eventos ajenos a ella, en este caso. Para este ejemplo voy a utilizar el siguiente despliegue:
apiVersion: apps/v1
kind: Deployment
metadata:
name: web-deployment
labels:
app: web
spec:
replicas: 1
selector:
matchLabels:
app: web
template:
metadata:
labels:
app: web
spec:
containers:
- name: nginx
image: nginx:latest
ports:
- name: http
containerPort: 80
Como puedes ver es un Nginx básico con una sola réplica. Al desplegarlo deberías de ver algo como lo siguiente:
➜ kubectl apply -f web-deployment.yaml
deployment.apps/web-deployment created
➜ kubectl get pods
NAME READY STATUS RESTARTS AGE
web-deployment-7bfddfc4f-9kxjn 1/1 Running 0 6sLo último que te queda por definir es en base a qué escalamos esta aplicación.
Crear un ScaledObject para tu despliegue
Como te decía al principio de este artículo, existen diferentes scalers sobre los que puedes basar el autoescalado. Para este ejemplo voy a utilizar el tipo Azure Storage Queue. Por ello, antes que nada, necesito crear una cola de mensajería en Azure Storage, que llamaré tasks.
#Create a storage account on Azure
STORAGE_NAME="boxoftasks"
az storage account create --name $STORAGE_NAME --resource-group $RESOURCE_GROUP
ACCOUNT_KEY=$(az storage account keys list --resource-group $RESOURCE_GROUP --account-name $STORAGE_NAME --query "[0].value" --output tsv)
#Create a queue
az storage queue create --name "tasks" \
--account-name $STORAGE_NAME \
--account-key $ACCOUNT_KEY
#Get storage connection string
CONNECTION_STRING=$(az storage account show-connection-string --name $STORAGE_NAME --resource-group $RESOURCE_GROUP -o tsv)
#Create secret with the storage connection string
kubectl create secret generic storage-secret --from-literal=connection-string=$CONNECTION_STRINGAdemás, como puedes ver en el código anterior, lo último que hago es crear un secreto que guardará la cadena de conexión de la cuenta de almacenamiento donde está mi cola. Por último, creo el recurso ScaledObject que indicara los umbrales asociados a la misma:
apiVersion: keda.k8s.io/v1alpha1
kind: TriggerAuthentication
metadata:
name: trigger-auth-queue
spec:
secretTargetRef:
- parameter: connection
name: storage-secret
key: connection-string
---
apiVersion: keda.k8s.io/v1alpha1
kind: ScaledObject
metadata:
name: queue-scaledobject
labels:
deploymentName: web-deployment
spec:
scaleTargetRef:
deploymentName: web-deployment
pollingInterval: 15
coolDownPeriod: 30
minReplicaCount: 0
maxReplicaCount: 10
triggers:
- type: azure-queue
metadata:
queueName: tasks
queueLength: '5' # Optional. Queue length target for HPA. Default: 5 messages
authenticationRef:
name: trigger-auth-queuePara poder asociar la cadena de conexión al ScaledObject necesito hacer uso de otro recurso llamado TriggerAuthentication, al que a su vez asocio al secreto creado anteriormente, aunque existen otras formas de autenticación.
Una vez que apliques los cambios ocurrirán dos cosas: por un lado se creará un recurso del tipo ScaledObject con el trigger azure-queue:
➜ kubectl get scaledobject
NAME DEPLOYMENT TRIGGERS AGE
queue-scaledobject web-deployment azure-queue 59sY por otro un HPA asociado a dicho objecto:
➜ kubectl get hpa
NAME REFERENCE TARGETS MINPODS MAXPODS REPLICAS AGE
keda-hpa-web-deployment Deployment/web-deployment <unknown>/5 (avg) 1 10 0 79sProbar el autoescalado con KEDA
Para comprobar que todo funciona correctamente, con Azure CLI puedes generar varios mensajes de una forma sencilla:
#Generate messages
while true; do az storage message put --content "Hello from KEDA" --queue-name "tasks" --account-name $STORAGE_NAME --account-key $STORAGE_KEY; doneSi vigilas el HPA asociado comprobarás que poco a poco va subiendo en replicas:
➜ kubectl get hpa -w
NAME REFERENCE TARGETS MINPODS MAXPODS REPLICAS AGE
keda-hpa-web-deployment Deployment/web-deployment <unknown>/5 (avg) 1 10 0 23m
keda-hpa-web-deployment Deployment/web-deployment 4/5 (avg) 1 10 1 23m
keda-hpa-web-deployment Deployment/web-deployment 13/5 (avg) 1 10 1 23m
keda-hpa-web-deployment Deployment/web-deployment 7334m/5 (avg) 1 10 3 24m
keda-hpa-web-deployment Deployment/web-deployment 5800m/5 (avg) 1 10 5 24m
keda-hpa-web-deployment Deployment/web-deployment 6334m/5 (avg) 1 10 6 24m
keda-hpa-web-deployment Deployment/web-deployment 5750m/5 (avg) 1 10 8 24m
keda-hpa-web-deployment Deployment/web-deployment 5600m/5 (avg) 1 10 10 25m
keda-hpa-web-deployment Deployment/web-deployment 6200m/5 (avg) 1 10 10 25mPara comprobar el efecto contrario, elimina los mensajes de la cola con el comando clear:
#Clean queue
az storage message clear --queue-name "tasks" --account-name $STORAGE_NAME --account-key $STORAGE_KEYVerás que a los pocos minutos volverás a tener cero réplicas de tu aplicación:
➜ kubectl get hpa -w
NAME REFERENCE TARGETS MINPODS MAXPODS REPLICAS AGE
keda-hpa-web-deployment Deployment/web-deployment <unknown>/5 (avg) 1 10 0 23m
keda-hpa-web-deployment Deployment/web-deployment 4/5 (avg) 1 10 1 23m
keda-hpa-web-deployment Deployment/web-deployment 13/5 (avg) 1 10 1 23m
keda-hpa-web-deployment Deployment/web-deployment 7334m/5 (avg) 1 10 3 24m
keda-hpa-web-deployment Deployment/web-deployment 5800m/5 (avg) 1 10 5 24m
keda-hpa-web-deployment Deployment/web-deployment 6334m/5 (avg) 1 10 6 24m
keda-hpa-web-deployment Deployment/web-deployment 5750m/5 (avg) 1 10 8 24m
keda-hpa-web-deployment Deployment/web-deployment 5600m/5 (avg) 1 10 10 25m
keda-hpa-web-deployment Deployment/web-deployment 6200m/5 (avg) 1 10 10 25m
keda-hpa-web-deployment Deployment/web-deployment 6900m/5 (avg) 1 10 10 25m
keda-hpa-web-deployment Deployment/web-deployment 7/5 (avg) 1 10 10 25m
keda-hpa-web-deployment Deployment/web-deployment 0/5 (avg) 1 10 10 26m
keda-hpa-web-deployment Deployment/web-deployment 0/5 (avg) 1 10 10 31m
keda-hpa-web-deployment Deployment/web-deployment <unknown>/5 (avg) 1 10 0 31m¡Saludos!
Si quieres seguir aprendiendo sobre contenedores, tienes una lista de vídeos en mi canal de YouTube 👇🏻
Docker CLI: Comandos esenciales que todo developer debe conocer
Domina los Dockerfiles: De lo básico a multi-stage
4 formas de crear un Dockerfile sin empezar desde cero
¿No entiendes las redes en Docker? Mira este vídeo
Cómo NO perder tus datos en Docker: Guía definitiva
Deja de configurar contenedores a mano: Aprende Docker Compose 🐙
Cómo subir tus imágenes a Docker Hub (Guía paso a paso)
Publica y automatiza tus imágenes de Docker con GitHub


¿Qué son los contenedores? Docker desde cero para principiantes
return(GiS); julio 10, 2024 10:00 am