Scala i workload GKE da e verso zero utilizzando HPA

Questo tutorial mostra come ottimizzare l'utilizzo delle risorse in Google Kubernetes Engine (GKE) configurando i workload in modo che vengano scalati automaticamente a zero repliche quando sono inattivi e vengano scalati di nuovo man mano che la domanda aumenta. Questo approccio integra il gestore della scalabilità automatica orizzontale dei pod (HPA) con l'infrastruttura di scalabilità automatica gestita di GKE per gestire lo scaling in base alle metriche esterne.

Configura il deployment in modo che venga scalato a zero impostando il valore del campo minReplicas su 0 e definendo una metrica di tipo External o Object nel manifest HPA. GKE monitora queste metriche tramite la risorsa personalizzata AutoscalingMetric, che contribuisce a garantire una gestione efficiente delle risorse per le tue applicazioni.

Con questa configurazione, non è necessario utilizzare adattatori di metriche di terze parti, come KEDA, per scalare i workload GKE. Questa soluzione gestisce l'importazione delle metriche e i consigli di scalabilità direttamente nel control plane GKE, riducendo l'overhead di gestione del cluster.

In questo tutorial, esegui il deployment di un'applicazione worker asincrona di esempio che elabora i messaggi da una coda Pub/Sub. Configura un autoscaler orizzontale dei pod per monitorare la profondità della coda (pubsub.googleapis.com:num_undelivered_messages) utilizzando una risorsa personalizzata AutoscalingMetric:

  • Quando i messaggi arrivano nell'abbonamento, GKE aumenta il numero di pod worker per elaborare la coda.
  • Quando la coda è vuota:GKE riduce automaticamente lo scale up del deployment dei worker a zero repliche.

Questo tutorial è rivolto a sviluppatori di applicazioni, amministratori e operatori di piattaforme e DevOps che vogliono ottimizzare l'utilizzo delle risorse in GKE scalando i carichi di lavoro a zero quando sono inattivi.

Considerazioni

Prima di configurare i workload in modo che vengano scalati a zero, esamina le seguenti considerazioni:

  • Il ridimensionamento dei workload da e verso zero utilizzando HPA richiede che il control plane e i nodi del cluster GKE eseguano la versione 1.37 o successive nei cluster nuovi ed esistenti sottoposti ad upgrade. Se utilizzi un cluster esistente, verifica la sua versione o esegui l'upgrade del cluster o dei relativi nodi alla versione 1.37 o successiva.
  • Il manifest HPA deve utilizzare la configurazione apiVersion: autoscaling/v2 per supportare l'impostazione minReplicas: 0 e le metriche esterne.
  • Prima di eseguire il downgrade dei pool di nodi a una versione precedente alla 1.37, aggiorna tutti i manifest HPA configurati per lo scale up e lo scale down da zero impostando il campo minReplicas su 1 o un valore superiore. Le versioni precedenti alla 1.37 non supportano l'impostazione minReplicas: 0, che può causare il blocco dei carichi di lavoro a zero repliche.
  • Devi configurare almeno una metrica External o Object (ad esempio la profondità della coda) in Horizontal Pod Autoscaler. GKE non può raccogliere metriche relative a CPU o memoria (Resource) quando un workload ha zero pod, pertanto le metriche delle risorse da sole non possono attivare lo scale up da zero.
  • AutoscalingMetric, HorizontalPodAutoscaler e il deployment di destinazione devono risiedere nello stesso spazio dei nomi Kubernetes.

Prima di iniziare

  1. Installa Google Cloud CLI.

  2. Configura gcloud CLI per utilizzare la tua identità federata.

    Per ulteriori informazioni, vedi Accedi a gcloud CLI con la tua identità federata.

  3. Per inizializzare gcloud CLI, esegui questo comando:

    gcloud init
  4. Crea o seleziona un Google Cloud progetto.

    Ruoli richiesti per selezionare o creare un progetto

    • Seleziona un progetto: la selezione di un progetto non richiede un ruolo IAM specifico. Puoi selezionare qualsiasi progetto per il quale ti è stato concesso un ruolo.
    • Crea un progetto: per creare un progetto, devi disporre del ruolo Autore progetto (roles/resourcemanager.projectCreator), che contiene l'autorizzazione resourcemanager.projects.create. Scopri come concedere i ruoli.
    • Creare un progetto Google Cloud :

      gcloud projects create PROJECT_ID

      Sostituisci PROJECT_ID con un nome per il progetto Google Cloud che stai creando.

    • Seleziona il progetto Google Cloud che hai creato:

      gcloud config set project PROJECT_ID

      Sostituisci PROJECT_ID con il nome del progetto Google Cloud .

  5. Verifica che la fatturazione sia attivata per il tuo progetto Google Cloud .

  6. Abilita le API GKE e Pub/Sub:

    Ruoli richiesti per abilitare le API

    Per abilitare le API, devi disporre dell'autorizzazione serviceusage.services.enable. Se hai creato il progetto, probabilmente disponi già di questa autorizzazione tramite il ruolo Proprietario (roles/owner). In caso contrario, puoi ottenere questa autorizzazione tramite il ruolo Amministratore utilizzo dei servizi (roles/serviceusage.serviceUsageAdmin). Scopri come concedere i ruoli.

    gcloud services enable container.googleapis.com pubsub.googleapis.com

Ruoli obbligatori

Per ottenere le autorizzazioni necessarie per completare questo tutorial, chiedi all'amministratore di concederti i seguenti ruoli IAM nel progetto:

Per saperne di più sulla concessione dei ruoli, consulta Gestisci l'accesso a progetti, cartelle e organizzazioni.

Potresti anche riuscire a ottenere le autorizzazioni richieste tramite i ruoli personalizzati o altri ruoli predefiniti.

Configura l'ambiente

Per semplicità, i comandi di questo tutorial creano tutte le risorse (il cluster GKE e l'argomento e la sottoscrizione Pub/Sub) all'interno di un singolo Google Cloud progetto (PROJECT_ID).

Per configurare l'ambiente:

  1. Imposta le variabili di ambiente:

    export PROJECT_ID=PROJECT_ID
    export PROJECT_NUMBER=$(gcloud projects describe $PROJECT_ID --format 'get(projectNumber)')
    export LOCATION=LOCATION
    

    Sostituisci quanto segue:

    • PROJECT_ID: il tuo Google Cloud ID progetto.
    • LOCATION: la regione o zona in cui vuoi creare il cluster GKE, ad esempio us-central1. Per i cluster Autopilot, specifica una regione.
  2. Crea un cluster GKE con la versione 1.37 o successive con Workload Identity Federation for GKE abilitata. Ti consigliamo di utilizzare un cluster Autopilot per un'esperienza Kubernetes completamente gestita e per massimizzare il risparmio sui costi quando i carichi di lavoro vengono scalati a zero. Per scegliere la modalità operativa più adatta ai tuoi workload, consulta Scegliere una modalità operativa GKE:

    Autopilot

    Crea un cluster Autopilot:

    gcloud container clusters create-auto scale-to-zero \
        --project=${PROJECT_ID} \
        --location=${LOCATION}
    

    Workload Identity Federation for GKE è abilitato per impostazione predefinita sui cluster Autopilot.

    Standard

    Crea un cluster Standard con la federazione delle identità per i carichi di lavoro per GKE abilitata:

    gcloud container clusters create scale-to-zero \
        --project=${PROJECT_ID} \
        --location=${LOCATION} \
        --workload-pool=${PROJECT_ID}.
    
  3. Configura kubectl per comunicare con il cluster:

    gcloud container clusters get-credentials scale-to-zero \
        --project=${PROJECT_ID} \
        --location=${LOCATION}
    

Crea risorse Pub/Sub

Questo tutorial utilizza la profondità della coda Pub/Sub come esempio di origine di metrica esterna.

Per creare un argomento e una sottoscrizione Pub/Sub:

  1. Crea un argomento Pub/Sub:

    gcloud pubsub topics create my-worker-topic \
        --project=${PROJECT_ID}
    
  2. Crea una sottoscrizione collegata all'argomento:

    gcloud pubsub subscriptions create my-worker-subscription \
        --topic=my-worker-topic \
        --project=${PROJECT_ID}
    

Configura la federazione delle identità per i workload per GKE

Configura Workload Identity Federation for GKE per consentire all'applicazione worker di autenticarsi con le API Google Cloud e utilizzare i messaggi di Pub/Sub.

GKE gestisce automaticamente l'autenticazione con Cloud Monitoring per le risorse AutoscalingMetric nello stesso progetto. Per scoprire di più sulla definizione delle metriche per la scalabilità automatica, consulta Recuperare metriche personalizzate o esterne da Cloud Monitoring.

Per configurare Workload Identity Federation for GKE per il tuo workload worker, segui questi passaggi:

  1. Crea un account di servizio Kubernetes per l'applicazione worker nello spazio dei nomi default:

    kubectl create serviceaccount async-worker-sa \
        --namespace default
    
  2. Concedi il ruolo roles/pubsub.subscriber al account di servizio Kubernetes in modo che l'applicazione possa ricevere messaggi dalla tua sottoscrizione Pub/Sub:

    gcloud projects add-iam-policy-binding projects/${PROJECT_ID} \
        --role=roles/pubsub.subscriber \
        --member=principal://iam.googleapis.com/projects/${PROJECT_NUMBER}/locations/global/workloadIdentityPools/${PROJECT_ID}./subject/ns/default/sa/async-worker-sa
    

Per saperne di più, consulta Configurare le applicazioni per utilizzare Workload Identity Federation for GKE.

Crea il deployment di esempio

Prima di poter creare un oggetto HPA, devi creare il workload che monitorerà.

Per creare la deployment di esempio, segui questi passaggi:

  1. Salva il seguente manifest come async-worker.yaml:

    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: async-worker
      namespace: default
    spec:
      replicas: 3
      selector:
        matchLabels:
          app: async-worker
      template:
        metadata:
          labels:
            app: async-worker
        spec:
          containers:
          - name: async-worker
            image: nginx:latest
            ports:
            - containerPort: 80
            resources:
              limits:
                memory: 100Mi
              requests:
                cpu: 50m
                memory: 100Mi
    
  2. Applica il deployment async-worker.yaml:

    kubectl apply -f async-worker.yaml
    

Configura un workload per la scalabilità da e verso zero

In questa sezione, configurerai il deployment async-worker in modo che fare lo scale down a zero quando la coda Pub/Sub è vuota e venga aumentato di nuovo man mano che arrivano nuovi messaggi.

Crea la risorsa AutoscalingMetric

Per definire l'indicatore esterno monitorato da GKE, crea la risorsa personalizzata AutoscalingMetric. Nel seguente manifest di esempio, la metrica interroga Cloud Monitoring per il numero di messaggi Pub/Sub non recapitati nella sottoscrizione my-worker-subscription.

Per creare la risorsa AutoscalingMetric:

  1. Salva il seguente manifest come file pubsub-metric.yaml:

    apiVersion: autoscaling.gke.io/v1beta1
    kind: AutoscalingMetric
    metadata:
      name: pubsub-queue-depth
      namespace: default
    spec:
      metrics:
      - promql:
          name: pubsub-undelivered
          query: >
              {
                "pubsub.googleapis.com/subscription/num_undelivered_messages",
                subscription_id="my-worker-subscription"
              }
    
  2. Applica il manifest pubsub-metric.yaml:

    kubectl apply -f pubsub-metric.yaml
    
  3. Verifica lo stato della metrica e recupera l'identificatore della metrica:

    kubectl describe autoscalingmetric pubsub-queue-depth
    

    Nella sezione Status dell'output, verifica che non siano elencati errori e prendi nota del valore Hpa Name nel formato autoscaling.gke.io|CUSTOM_RESOURCE_NAME|METRIC_NAME. Fai riferimento a questo identificatore di metrica esterna quando crei l'oggetto HorizontalPodAutoscaler nella sezione successiva. Se la sezione Status segnala errori di configurazione o le metriche non vengono recuperate come previsto, consulta Risolvere i problemi relativi alle metriche recuperate per lo scaling automatico.

Configura Horizontal Pod Autoscaler

Per configurare il comportamento della scalabilità automatica, crea una risorsa HorizontalPodAutoscaler che abbia come target il deployment.

Per configurare Horizontal Pod Autoscaler:

  1. Salva il seguente manifest come file worker-hpa.yaml:

    apiVersion: autoscaling/v2
    kind: HorizontalPodAutoscaler
    metadata:
      name: async-worker-hpa
      namespace: default
    spec:
      scaleTargetRef:
        apiVersion: apps/v1
        kind: Deployment
        name: async-worker
      minReplicas: 0
      maxReplicas: 20
      metrics:
      - type: External
        external:
          metric:
            name: autoscaling.gke.io|pubsub-queue-depth|pubsub-undelivered
          target:
            type: AverageValue
            averageValue: "10"
    

    Questo manifest configura i seguenti campi chiave:

    • minReplicas: 0: attiva la scalabilità fino a zero consentendo al controller di ridurre lo scale down del deployment a 0 repliche quando la domanda scende a zero.
    • type: External: configura un'origine metrica esterna in modo che HPA possa attivare lo scale up quando il workload ha zero pod.
    • name: autoscaling.gke.io|pubsub-queue-depth|pubsub-undelivered: mappa l'HPA direttamente alla risorsa AutoscalingMetric creata nel passaggio precedente utilizzando il formato dell'identificatore autoscaling.gke.io|CUSTOM_RESOURCE_NAME|METRIC_NAME.
  2. Applica il manifest worker-hpa.yaml:

    kubectl apply -f worker-hpa.yaml
    

Verifica il comportamento e le condizioni di zero-scale

Quando tutti i messaggi nella sottoscrizione Pub/Sub vengono elaborati, il gestore della scalabilità automatica dei pod orizzontale valuta la domanda pari a zero e riduce lo scale down del deployment a 0 repliche.

Per verificare che il gestore della scalabilità automatica orizzontale dei pod abbia attivato lo stato zero, controlla le condizioni di stato della risorsa async-worker-hpa eseguendo il seguente comando:

kubectl describe hpa async-worker-hpa

L'output è simile al seguente:

Name:             async-worker-hpa
Namespace:        default
Reference:        Deployment/async-worker
Metrics:          ( current / target )
  "autoscaling.gke.io|pubsub-queue-depth|pubsub-undelivered" (external metric):  0 / 10
Min replicas:     0
Max replicas:     20
Deployment pods:  0 current / 0 desired
Conditions:
  Type            Status  Reason               Message
  ----            ------  ------               -------
  AbleToScale     True    SucceededGetScale    the HPA controller was able to get the target's current scale
  ScalingActive   True    ValidMetricFound     the HPA was able to successfully calculate a replica count from external metric
  ScaledToZero    True    ScaledToZero         the HPA has scaled the target resource to 0 replicas due to zero metric demand

Informazioni sulla condizione ScaledToZero

La condizione ScaledToZero indica se l'Horizontal Pod Autoscaler ha scalato il workload a zero repliche:

  • ScaledToZero: True (Reason: ScaledToZero): indica che il controller HPA ha scalato correttamente il tuo workload a 0 repliche perché la domanda di metriche esterne è scesa a zero. L'HPA rimane attivo (ScalingActive: True) e interroga continuamente GKE per rilevare quando aumenta la domanda di workload.
  • ScaledToZero: False: indica che il workload è stato scalato a una o più repliche.

Se ridimensioni manualmente un deployment a zero repliche, ad esempio con il comando kubectl scale --replicas=0, l'HPA mette in pausa la scalabilità automatica (ScalingActive: False) per evitare modifiche in conflitto. Per riprendere la scalabilità automatica, ridimensiona il deployment a una o più repliche (kubectl scale deployment async-worker --replicas=1).

Per scenari di risoluzione dei problemi in cui i workload non vengono scalati a zero o non fanno lo scale up da zero, consulta Risolvere i problemi di scalabilità dei carichi di lavoro GKE a zero e da zero utilizzando HPA. Se il gestore della scalabilità automatica orizzontale dei pod segnala metriche esterne mancanti o non valide, consulta Risoluzione dei problemi relativi alle metriche recuperate per la scalabilità automatica.

Esegui la pulizia

Per evitare che al tuo account Google Cloud vengano addebitati costi relativi alle risorse utilizzate in questo tutorial, segui questi passaggi:

  1. Elimina il cluster GKE:

    gcloud container clusters delete scale-to-zero \
        --project=${PROJECT_ID} \
        --location=${LOCATION}
    
  2. Elimina l'argomento e la sottoscrizione Pub/Sub:

    gcloud pubsub subscriptions delete my-worker-subscription \
        --project=${PROJECT_ID}
    gcloud pubsub topics delete my-worker-topic \
        --project=${PROJECT_ID}
    

Passaggi successivi