Cloud Intelligence™Cloud Intelligence™

Cloud Intelligence™

Autoscaling event-driven in Kubernetes: tutta la potenza di KEDA

By Chimbu ChinnaduraiJun 26, 20236 min read

Questa pagina è disponibile anche in English, Deutsch, Español, Français, 日本語 e Português.

Kubernetes ha rivoluzionato l'orchestrazione dei container, permettendo alle aziende di distribuire e gestire applicazioni su larga scala. L'autoscaling è una delle sue funzionalità cardine: adatta dinamicamente le risorse in base alla domanda dei workloads.

Lo scaling orizzontale basato su CPU e memoria è la metrica più diffusa, ma spesso non basta a rappresentare la complessità delle applicazioni moderne. In questo articolo vediamo come Kubernetes Event-driven Autoscaling (KEDA) possa rispondere a queste esigenze in modo efficace.

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

Kubernetes Event-driven Autoscaling (KEDA) è un componente open source per Kubernetes che amplia le capacità di autoscaling, abilitando lo scaling event-driven a partire da metriche personalizzate e trigger esterni. Estende l'Horizontal Pod Autoscaler (HPA) standard di Kubernetes, rendendo l'autoscaling più flessibile e granulare.

Ecco alcune delle funzionalità di KEDA:

  • Autoscaling event-driven: KEDA scala le applicazioni in base a eventi esterni, come il numero di messaggi in un topic Kafka o il numero di eventi in un Azure Event Hub. In questo modo è possibile scalare in tempo reale per assecondare la domanda.
  • Scaler integrati: KEDA include un catalogo di scaler già pronti per le principali piattaforme cloud, database, sistemi di messaggistica, sistemi di telemetria, CI/CD e molto altro. Bastano pochi passaggi per iniziare a usare l'autoscaling event-driven.
  • Supporto per più tipologie di workloads: KEDA supporta diverse tipologie di workloads, come Deployment, Job e risorse personalizzate dotate di subresource /scale. È quindi una soluzione flessibile, adatta a un'ampia gamma di applicazioni.
  • Estensibile: KEDA è estensibile: si possono integrare scaler propri o utilizzare quelli mantenuti dalla community. La flessibilità che serve per rispondere alle esigenze specifiche di ogni applicazione.
  • Risparmio sui costi: KEDA aiuta a ridurre i costi cloud scalando le applicazioni a zero quando non servono. Un risparmio considerevole, soprattutto per le applicazioni con workloads variabili.
  • Vendor-agnostic: KEDA è vendor-agnostic e funziona con qualsiasi cluster Kubernetes. Una scelta ideale per le organizzazioni che usano Kubernetes on-premises, in cloud o all'edge.
  • Configurazione e gestione semplificate: KEDA propone un approccio dichiarativo alla configurazione tramite manifest Kubernetes. Le regole di autoscaling e i trigger si definiscono in file YAML o JSON, semplificando configurazione e gestione del comportamento di autoscaling delle applicazioni.

KEDA in azione

Vediamo come KEDA può essere usato in GKE per eseguire l'autoscaling sulla base delle metriche dei messaggi pub/sub. L'applicazione di esempio e i file manifest Kubernetes sono disponibili nel repo GitHub.

Prerequisiti

  • Un cluster GKE con workload identity abilitata
  • Helm e Kubectl

Configurare le risorse Pub/Sub

Eseguire i comandi seguenti per creare un topic e una subscription 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

Configurare Workload Identity per KEDA

GCP Workload Identity permette ai workloads nei cluster GKE di impersonare gli account di servizio Identity and Access Management (IAM) per accedere ai servizi Google Cloud. È il metodo consigliato per i workloads in esecuzione su GKE che devono accedere ai servizi Google Cloud in modo sicuro e gestibile.

Eseguire i comandi seguenti per configurare workload identity per 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]"

Installare KEDA

Di seguito le diverse opzioni disponibili per installare KEDA su un cluster Kubernetes.

Useremo Helm Chart per distribuire KEDA nel cluster GKE.

  • Aggiungere e aggiornare il repo Helm.
helm repo add kedacore https://kedacore.github.io/charts
helm repo update
  • Installare l'ultima versione della Helm chart di 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

Verificare i log dei pod keda e accertarsi che l'applicazione sia in esecuzione senza errori.

Le chiamate al webhook di KEDA passano dalla porta 9443: occorre quindi assicurarsi che le regole firewall fra control plane e nodi consentano il traffico su tale porta. In GKE, le regole firewall generate automaticamente abilitano solo le porte 443 e 10250: è necessario crearne una nuova per aprire la porta 9443.

Esempio di comando gcloud per creare la regola 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

Distribuire l'applicazione di esempio

Configurare workload identity per l'applicazione di esempio, in modo che possa consumare i messaggi dalla subscription 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]"

Distribuire l'applicazione di esempio nel 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

Distribuire KEDA Event Scaler

KEDA si integra in modo nativo con diversi Scaler (sorgenti di eventi) e si appoggia alle Custom Resource (CRD) per definire le azioni e i parametri di scaling desiderati. KEDA monitora la sorgente di eventi e trasmette i dati all'Horizontal Pod Autoscaler (HPA), che a sua volta scala rapidamente la risorsa.

In questo esempio useremo l'event scaler Google Cloud Platform Pub/Sub per mostrare l'auto scaling in azione. La relazione di scaling tra una sorgente di eventi e uno specifico workload (ad esempio Deployment, StatefulSet) si configura tramite la Custom Resource Definition ScaledObject.

TriggerAuthentication permette di descrivere i parametri di autenticazione separatamente dallo ScaledObject e dai container del deployment. Inoltre abilita metodi di autenticazione più avanzati, come la pod identity e il riuso delle credenziali.

Distribuire le risorse seguenti per l'autoscaling: KEDA scalerà l'applicazione in base al numero di messaggi non confermati nella subscription.

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

Esaminare la risorsa HPA creata da KEDA.

Lo script seguente pubblica messaggi di test sul topic e permette di osservare le azioni di scaling eseguite dall'HPA in base alle metriche fornite da 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 dello scaling con KEDA

In questo articolo abbiamo esplorato le funzionalità di KEDA, mostrandolo all'opera in un'applicazione che scala in base alle metriche di GCP Pub/Sub.

KEDA si è rivelato uno strumento prezioso per lo scaling event-based negli ambienti Kubernetes: consente di scalare le applicazioni in modo efficiente, personalizzando le metriche e reagendo agli eventi in tempo reale. Grazie a KEDA, le aziende possono ottimizzare costi e gestione delle risorse, ottenendo applicazioni dinamicamente scalabili e pronte a rispondere alla domanda dei workloads.