Cloud Intelligence™Cloud Intelligence™

Cloud Intelligence™

Autoscaling orientado a eventos no Kubernetes: o poder do KEDA

By Chimbu ChinnaduraiJun 26, 20236 min read

Esta página também está disponível em English, Deutsch, Español, Français, Italiano e 日本語.

O Kubernetes revolucionou a orquestração de containers e permitiu que as empresas implantem e gerenciem aplicações em escala. O autoscaling é um recurso fundamental do Kubernetes, que ajusta os recursos dinamicamente conforme a demanda dos workloads.

Embora o escalonamento horizontal por CPU e memória seja a métrica mais comum, ele costuma deixar passar boa parte da complexidade das aplicações modernas. Neste post, vamos ver como o Kubernetes Event-driven Autoscaling ( KEDA) pode resolver esses desafios de forma eficaz.

**Kubernetes Event-driven Autoscaling (KEDA)**

O Kubernetes Event-driven Autoscaling ( KEDA) é um componente open-source para Kubernetes que amplia o autoscaling ao habilitar o escalonamento orientado a eventos com base em métricas customizadas e gatilhos externos. Ele estende o Horizontal Pod Autoscaler ( HPA) padrão do Kubernetes e oferece um autoscaling mais flexível e granular.

Confira alguns dos recursos do KEDA:

  • Autoscaling orientado a eventos: o KEDA escala aplicações com base em eventos externos, como o número de mensagens em um tópico Kafka ou de eventos em um Azure Event Hub. Assim, dá para escalar suas aplicações em tempo real conforme a demanda.
  • Scalers nativos: o KEDA já vem com um catálogo de scalers para diversas plataformas de nuvem, bancos de dados, sistemas de mensageria e telemetria, CI/CD e muito mais. Isso facilita dar os primeiros passos com autoscaling orientado a eventos.
  • Suporte a vários tipos de workloads: o KEDA suporta diversos tipos de workloads, como Deployments, Jobs e recursos customizados com o subrecurso /scale. Isso o torna uma solução flexível para uma ampla gama de aplicações.
  • Extensível: o KEDA é extensível, ou seja, você pode trazer seus próprios scalers ou usar scalers mantidos pela comunidade. Isso dá flexibilidade para atender às necessidades específicas de cada aplicação.
  • Economia de custos: o KEDA pode ajudar a reduzir custos de nuvem ao escalar suas aplicações para zero quando elas não estão em uso. A economia pode ser bem expressiva, principalmente para aplicações com workloads variáveis.
  • Independente de fornecedor: o KEDA é vendor-agnostic, então funciona com qualquer cluster Kubernetes. É uma ótima escolha para quem quer rodar Kubernetes on-premises, na nuvem ou na edge.
  • Configuração e gerenciamento simplificados: o KEDA adota uma abordagem declarativa por meio de manifests do Kubernetes. Você define regras e gatilhos de autoscaling em arquivos YAML ou JSON, o que torna simples configurar e gerenciar o comportamento de autoscaling das suas aplicações.

O KEDA na prática

Vamos ver como o KEDA pode ser usado no GKE para fazer autoscaling com base em métricas de mensagens do pub/sub. A aplicação de exemplo e os manifests do Kubernetes estão disponíveis no repositório do GitHub.

Pré-requisitos

  • Um cluster GKE com workload identity habilitado
  • Helm e Kubectl

Configurar os recursos de Pub/Sub

Execute os comandos abaixo para criar um tópico e uma assinatura de pub/sub.

GCP_PROJECT_ID=$(gcloud config get-value project)
TOPIC_NAME=keda-demo-topic
SUBSCRIPTION_NAME=keda-demo-topic-subscription

# Create Topic
gcloud pubsub topics create $TOPIC_NAME --project $GCP_PROJECT_ID

# Create Subscription
gcloud pubsub subscriptions create $SUBSCRIPTION_NAME \
--topic $TOPIC_NAME \
--project $GCP_PROJECT_ID

Configurar o Workload Identity para o KEDA

O GCP Workload Identity permite que workloads em clusters GKE assumam a identidade de service accounts do Identity and Access Management ( IAM) para acessar serviços do Google Cloud. O Workload Identity é a forma recomendada para que workloads em execução no GKE acessem os serviços do Google Cloud com segurança e fácil gerenciamento.

Execute os comandos abaixo para configurar o workload identity para o KEDA.

KEDA_GCP_SERVICE_ACCOUNT=keda-operator
KEDA_NAMESPACE=keda
KEDA_K8S_SERVICE_ACCOUNT=keda-operator

#Create GCP service account
gcloud iam service-accounts create $KEDA_GCP_SERVICE_ACCOUNT \
--project=$GCP_PROJECT_ID

#Create IAM role bindings
gcloud projects add-iam-policy-binding $GCP_PROJECT_ID \
--member "serviceAccount:$KEDA_GCP_SERVICE_ACCOUNT@$GCP_PROJECT_ID.iam.gserviceaccount.com" \
--role "roles/monitoring.viewer"

#Allow kubernetes service account to impersonate GCP service account
gcloud iam service-accounts add-iam-policy-binding $KEDA_GCP_SERVICE_ACCOUNT@$GCP_PROJECT_ID.iam.gserviceaccount.com \
    --role roles/iam.workloadIdentityUser \
    --member "serviceAccount:$GCP_PROJECT_ID.svc.id.goog[$KEDA_NAMESPACE/$KEDA_K8S_SERVICE_ACCOUNT]"

Instalar o KEDA

Veja abaixo as opções disponíveis para instalar o KEDA no cluster Kubernetes.

Vamos usar o Helm Chart para implantar o KEDA no cluster GKE.

  • Adicione e atualize o repositório Helm.
helm repo add kedacore https://kedacore.github.io/charts
helm repo update
  • Instale a versão mais recente do helm chart do KEDA.
helm upgrade -install keda kedacore/keda \
--namespace keda \
--set 'serviceAccount.annotations.iam\.gke\.io\/gcp-service-account'="$KEDA_SERVICE_ACCOUNT@$GCP_PROJECT_ID.iam.gserviceaccount.com" \
--create-namespace \
--debug \
--wait

Confira os logs dos pods do keda e verifique se a aplicação está rodando sem erros.

As chamadas do webhook do KEDA são atendidas na porta 9443. Por isso, qualquer regra de firewall entre o control plane -> node precisa permitir requisições nessa porta. No GKE, as regras de firewall geradas automaticamente liberam apenas as portas 443 e 10250, então é preciso criar uma nova regra para liberar a porta 9443.

Exemplo de comando gcloud para a regra de firewall:

gcloud compute firewall-rules create allow-api-server-to-keda-webhook \
--description="Allow kubernetes api server to keda webhook call on worker nodes TCP port 9443" \
--direction=INGRESS \
--priority=1000 \
--network=$VPC-NETWORK-NAME \
--action=ALLOW \
--rules=tcp:9443 \
--source-ranges=$CONTROL-PLANE-IP-RANGE \
--target-tags=$NETWORK-TAGS-ASSIGNED-TO-NODES

Implantar a aplicação de exemplo

Configure o workload identity para que a aplicação de exemplo consuma as mensagens da assinatura pub/sub.

SAMPLE_APP_GCP_SERVICE_ACCOUNT=keda-demo
SAMPLE_APP_NAMESPACE=default
SAMPLE_APP_K8S_SERVICE_ACCOUNT=keda-demo

#Create GCP service account
gcloud iam service-accounts create $SAMPLE_APP_GCP_SERVICE_ACCOUNT \
--project=$GCP_PROJECT_ID

#Create IAM role bindings
gcloud projects add-iam-policy-binding $GCP_PROJECT_ID \
--member "serviceAccount:$SAMPLE_APP_GCP_SERVICE_ACCOUNT@$GCP_PROJECT_ID.iam.gserviceaccount.com" \
--role "roles/pubsub.subscriber"

#Allow kubernetes service account to impersonate GCP service account
gcloud iam service-accounts add-iam-policy-binding $SAMPLE_APP_GCP_SERVICE_ACCOUNT@$GCP_PROJECT_ID.iam.gserviceaccount.com \
    --role roles/iam.workloadIdentityUser \
    --member "serviceAccount:$GCP_PROJECT_ID.svc.id.goog[$KEDA_NAMESPACE/$KEDA_SERVICE_ACCOUNT]"

Implante a aplicação de exemplo no cluster GKE.

cat <<EOF | kubectl apply -f -
---
apiVersion: v1
kind: ServiceAccount
metadata:
  annotations:
    iam.gke.io/gcp-service-account: keda-demo@$GCP_PROJECT_ID.iam.gserviceaccount.com
  name: keda-demo
---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: keda-demo
spec:
  selector:
    matchLabels:
      app: keda-demo
  replicas: 1
  template:
    metadata:
      labels:
        app: keda-demo
    spec:
      serviceAccountName: keda-demo
      containers:
      - image: simbu1290/keda-demo:v1
        name: consumer
        env:
        - name: PUB_SUB_PROJECT
          value: $GCP_PROJECT_ID
        - name: PUB_SUB_TOPIC
          value: "keda-demo-topic"
        - name: PUB_SUB_SUBSCRIPTION
          value: "keda-demo-topic-subscription"
EOF

Implantar o KEDA Event Scaler

O KEDA se integra de forma transparente a vários Scalers (fontes de eventos) e usa Custom Resources ( CRDs) para definir as ações e parâmetros de escalonamento desejados. O KEDA monitora a fonte de eventos e envia esses dados ao Horizontal Pod Autoscaler ( HPA) para acelerar o escalonamento de um recurso.

Aqui vamos usar o event scaler do Google Cloud Platform‎ Pub/Sub para demonstrar o autoscaling. A relação de escalonamento entre uma fonte de eventos e um workload específico (por exemplo, Deployment ou StatefulSet) é configurada por meio da Custom Resource Definition ScaledObject.

O TriggerAuthentication permite descrever os parâmetros de autenticação de forma separada do ScaledObject e dos containers do deployment. Ele também habilita métodos de autenticação mais avançados, como pod identity e reaproveitamento de credenciais.

Implante os recursos abaixo para o autoscaling — o KEDA fará o escalonamento com base no número de mensagens não confirmadas na assinatura.

cat <<EOF | kubectl apply -f -
---
apiVersion: keda.sh/v1alpha1
kind: TriggerAuthentication
metadata:
  name: keda-demo-trigger-auth-gcp-credentials
spec:
  podIdentity:
    provider: gcp
---
apiVersion: keda.sh/v1alpha1
kind: ScaledObject
metadata:
  name: keda-demo-pubsub-scaledobject
spec:
  scaleTargetRef:
    apiVersion: apps/v1 # Optional. Default: apps/v1
    kind: Deployment    # Optional. Default: Deployment
    name: keda-demo     # Mandatory. Must be in the same namespace as the ScaledObject
  pollingInterval: 5    # Optional. Default: 30 seconds
  minReplicaCount: 1    # Optional. Default: 0
  maxReplicaCount: 10   # Optional. Default: 100
  triggers:
  - type: gcp-pubsub
    authenticationRef:
      kind: TriggerAuthentication
      name: keda-demo-trigger-auth-gcp-credentials
    metadata:
      mode: "SubscriptionSize" # Optional - Default is SubscriptionSize - SubscriptionSize or OldestUnackedMessageAge
      value: "5" # Optional - Default is 5 for SubscriptionSize | Default is 10 for OldestUnackedMessageAge
      subscriptionName: "keda-demo-topic-subscription" # Mandatory
EOF

Veja o recurso HPA criado pelo KEDA.

Use o script abaixo para publicar mensagens de teste no tópico e acompanhar as ações de escalonamento executadas pelo HPA com base nas métricas fornecidas pelo KEDA.

#!/bin/bash

project_id=$GCP_PROJECT_ID
topic_name=$TOPIC_NAME

while true; do
    message="Hello, Pub/Sub!"
    gcloud pubsub topics publish ${topic_name} \
    --message "${message}" \
    --project ${project_id}
    sleep 1
done

Demo de escalonamento do KEDA

Neste post, exploramos o funcionamento do KEDA em uma aplicação que escalou com base em métricas do GCP Pub/Sub.

O KEDA se mostra uma ferramenta valiosa para escalonamento baseado em eventos em ambientes Kubernetes, permitindo escalar aplicações com eficiência, customizar métricas e responder a eventos em tempo real. Com o KEDA, dá para otimizar custos e o gerenciamento de recursos, garantindo que as aplicações sejam dinamicamente escaláveis e atendam à demanda dos workloads.