Configura buffer di capacità

I buffer di capacità migliorano la reattività e l'affidabilità dei carichi di lavoro critici gestendo in modo proattivo la capacità di riserva del cluster e gli stati sospesi della capacità pre-provisioning e preconfigurata utilizzando una definizione di risorsa personalizzata (CRD) CapacityBuffer di Kubernetes. L'utilizzo dei buffer di capacità consente di definire in modo esplicito una quantità specifica di capacità dei nodi inutilizzata all'interno del cluster. Questa capacità riservata contribuisce a ridurre il tempo di pianificazione dei pod.

Quando un carico di lavoro ad alta priorità deve eseguire rapidamente lo scale up, il nuovo carico di lavoro può utilizzare immediatamente la capacità vuota senza attendere il provisioning dei nodi. Questo approccio riduce al minimo la latenza ed evita la contesa delle risorse durante i picchi improvvisi della domanda.

Questa pagina fornisce i metodi per configurare i buffer di capacità: un buffer di repliche fisse, un buffer di limiti delle risorse e un buffer basato sulla percentuale.

Prima di iniziare

Prima di iniziare, assicurati di aver eseguito le seguenti attività:

  • Abilita l'API Google Kubernetes Engine.
  • Abilita l'API Google Kubernetes Engine
  • Se vuoi utilizzare Google Cloud CLI per questa attività, installala e poi inizializza gcloud CLI. Se hai già installato gcloud CLI, scarica l'ultima versione eseguendo il gcloud components update comando. Le versioni precedenti di gcloud CLI potrebbero non supportare l'esecuzione dei comandi in questo documento.
  • Crea un cluster GKE o accedi a un cluster GKE con la versione 1.35.2-gke.1842000 per i buffer attivi e la versione 1.36.0-gke.2253000 o successive per i buffer di standby.
  • Abilita il provisioning automatico dei nodi nei tuoi cluster Standard. Nei cluster Autopilot, il provisioning automatico dei nodi è già abilitato. Il provisioning automatico dei nodi è facoltativo ma consigliato per i buffer attivi e obbligatorio per i buffer di standby.

Crea oggetti Kubernetes prerequisiti

Per configurare un CapacityBuffer, devi disporre di uno spazio dei nomi che contenga tutti gli oggetti richiesti (il CapacityBuffer stesso e risorse aggiuntive come un PodTemplate o un carico di lavoro). PodTemplate e CapacityBuffer devono trovarsi nello stesso spazio dei nomi. Puoi creare uno spazio dei nomi o utilizzare uno spazio dei nomi esistente, incluso lo spazio dei nomi default.

A seconda del tipo di CapacityBuffer che stai configurando, è necessario anche uno dei seguenti elementi:

  • PodTemplate: definisce i requisiti delle risorse per una singola unità di capacità del buffer. La configurazione specificata nell'oggetto CapacityBuffer fa riferimento al modello di pod.
  • Carico di lavoro: un carico di lavoro esistente a cui fai riferimento nell'oggetto CapacityBuffer. Questa guida utilizza un oggetto Deployment come carico di lavoro di esempio, ma i buffer di capacità supportano uno dei seguenti tipi di risorse:

    • Deployment
    • ReplicaSet
    • StatefulSet
    • ReplicationController
    • Job
    • Definizioni di risorse personalizzate (CRD) che implementano la sottorisorsa scale.

Questa sezione fornisce esempi di questi oggetti. Se hai già un carico di lavoro che vuoi configurare con un buffer di capacità, vai a Applicare un buffer di capacità.

Per creare un carico di lavoro Kubernetes di esempio, completa i seguenti passaggi:

  1. Salva il seguente manifest come namespace.yaml:

    apiVersion: v1
    kind: Namespace
    metadata:
      name: capacity-buffer-example
      labels:
        name: capacity-buffer-example
    

    Questo manifest crea uno spazio dei nomi denominato capacity-buffer-example.

  2. (Facoltativo) Per utilizzare i buffer di capacità con una ComputeClass personalizzata, salva il seguente manifest come custom-compute-class.yaml:

    apiVersion: cloud.google.com/v1
    kind: ComputeClass
    metadata:
      name: ccc-example
      namespace: capacity-buffer-example
    spec:
      # Buffers are also created according to these priorities
      priorities:
      - machineFamily: n4
      - machineFamily: n4d
      - machineFamily: c4
      - machineFamily: c4d
      nodePoolAutoCreation:
        enabled: true
    

    Questo manifest crea una ComputeClass personalizzata che definisce e controlla le priorità di calcolo per i nodi di cui GKE esegue il provisioning. Per saperne di più, consulta ComputeClass personalizzate.

  3. Salva il seguente manifest come buffer-pod-template.yaml:

    apiVersion: v1
    kind: PodTemplate
    metadata:
      name: buffer-unit-template
      namespace: capacity-buffer-example # the namespace must be the same namespace as the CapacityBuffer
    template:
      spec:
        terminationGracePeriodSeconds: 0
        containers:
        - name: buffer-container
          image: registry.k8s.io/pause:3.9
          resources:
            requests:
              cpu: "1"
              memory: "1Gi"
            limits:
              cpu: "1"
              memory: "1Gi"
        # Optional: Using buffers with a custom ComputeClass /
        # controls the properties of the provisioned nodes.
        nodeSelector:
          cloud.google.com/compute-class: ccc-example
    

    Questo manifest crea un PodTemplate che definisce i requisiti delle risorse per una singola unità di capacità del buffer (1 CPU e 1Gi di memoria). Questa configurazione specifica le dimensioni delle unità di capacità di cui GKE esegue il provisioning per il buffer. Ad esempio, con questo PodTemplate, GKE non considera i nodi con meno di 1 CPU e 1 Gi di risorse disponibili come parte del buffer, se il cluster esegue lo scale up.

  4. Salva il seguente manifest come sample-workload-deployment.yaml:

    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: critical-workload-ref
      namespace: capacity-buffer-example # the namespace must be the same namespace as the CapacityBuffer
    spec:
      replicas: 10
      selector:
        matchLabels:
          app: critical-workload
      template:
        metadata:
          labels:
            app: critical-workload
        spec:
          containers:
          - name: busybox
            image: busybox
            command: ["sleep", "3600"]
            resources:
              requests:
                cpu: 100m
          # Optional: Using buffers with a custom ComputeClass /
          # controls the properties of the provisioned nodes.
          nodeSelector:
            cloud.google.com/compute-class: ccc-example
    

    Questo manifest crea un deployment di esempio con 10 repliche, che è l'oggetto di riferimento per l'esempio di buffer basato sulla percentuale nella sezione successiva.

  5. Applica i manifest al cluster:

    kubectl apply -f namespace.yaml -f custom-compute-class.yaml -f buffer-pod-template.yaml -f sample-workload-deployment.yaml
    
  6. Verifica che GKE abbia creato gli oggetti:

    kubectl get podtemplate -n capacity-buffer-example
    kubectl get deployment critical-workload-ref -n capacity-buffer-example
    

    L'output è simile al seguente:

    NAME                   AGE
    buffer-unit-template   1m
    
    NAME                    READY   UP-TO-DATE   AVAILABLE   AGE
    critical-workload-ref   10/10   10           10          1m
    

Applica un buffer di capacità

Questa sezione fornisce esempi dei diversi tipi di buffer di capacità che puoi applicare ai tuoi carichi di lavoro.

Configura un buffer di repliche fisse

La configurazione di un CapacityBuffer con repliche fisse specifica il numero esatto di unità di buffer che vuoi in base a un PodTemplate.

Per creare un buffer con repliche fisse, completa i seguenti passaggi:

  1. Salva il seguente manifest come cb-fixed-replicas.yaml:

    apiVersion: autoscaling.x-k8s.io/v1beta1
    kind: CapacityBuffer
    metadata:
      name: fixed-replica-buffer
      namespace: NAMESPACE
    spec:
      podTemplateRef:
        name: POD_TEMPLATE
      replicas: 3
      provisioningStrategy: "STRATEGY"
    

    Sostituisci quanto segue:

    • NAMESPACE: il nome dello spazio dei nomi, ad esempio capacity-buffer-example.
    • POD_TEMPLATE: il PodTemplate che definisce i requisiti delle risorse, ad esempio buffer-unit-template.
    • STRATEGY: la strategia di provisioning, "buffer.x-k8s.io/active-capacity" (impostazione predefinita) o "buffer.gke.io/standby-capacity".

    Questo manifest crea una risorsa CapacityBuffer che fa riferimento a un PodTemplate per richiedere un numero specifico di unità di buffer.

  2. Applica il manifest:

    kubectl apply -f cb-fixed-replicas.yaml
    
  3. Verifica che GKE abbia applicato il buffer di capacità:

    kubectl get capacitybuffer fixed-replica-buffer -n NAMESPACE
    

    Il campo replicas nello stato deve mostrare 3, che riflette il numero di repliche che hai definito nel manifest. Il campo STATUS deve mostrare ReadyForProvisioning.

Configura un buffer di limiti delle risorse

Puoi utilizzare il campo limits per definire una quantità massima di risorse che il buffer deve consumare, calcolata in base alle dimensioni del PodTemplate.

Per creare un buffer di limiti delle risorse, completa i seguenti passaggi:

  1. Salva il seguente manifest come cb-resource-limits.yaml:

    apiVersion: autoscaling.x-k8s.io/v1beta1
    kind: CapacityBuffer
    metadata:
      name: resource-limit-buffer
      namespace: NAMESPACE
    spec:
      podTemplateRef:
        name: POD_TEMPLATE
      limits:
        cpu: "5"
        memory: "5Gi"
      provisioningStrategy: "STRATEGY"
    

    Sostituisci quanto segue:

    • NAMESPACE: il nome dello spazio dei nomi, ad esempio capacity-buffer-example.
    • POD_TEMPLATE: il PodTemplate che definisce i requisiti delle risorse, ad esempio buffer-unit-template.
    • STRATEGY: la strategia di provisioning, "buffer.x-k8s.io/active-capacity" (impostazione predefinita) o "buffer.gke.io/standby-capacity".

    Questo manifest crea una risorsa CapacityBuffer con un limite totale di 5 CPU e 5 Gi di memoria. Se utilizzi l'esempio di PodTemplate del passaggio precedente, definisci ogni unità come 1 CPU e 1Gi di memoria, il che dovrebbe generare 5 unità di buffer.

  2. Applica il manifest:

    kubectl apply -f cb-resource-limits.yaml
    
  3. Verifica che GKE abbia applicato il buffer di capacità:

    kubectl get capacitybuffer resource-limit-buffer -n NAMESPACE
    

    Controlla lo stato di CapacityBuffer. Il campo replicas deve mostrare un valore derivato dai limiti che hai definito. Se utilizzi l'esempio di PodTemplate della sezione precedente, dovresti visualizzare 5 unità di buffer perché questo è il numero massimo di unità che rientrano nei limiti definiti.

Configura un buffer basato sulla percentuale

La configurazione di un buffer basato sulla percentuale ridimensiona dinamicamente il buffer in base a una percentuale di un carico di lavoro scalabile esistente. I buffer di capacità basati sulla percentuale sono supportati solo per gli oggetti scalabili di Kubernetes che implementano la sottorisorsa scale, come Deployment, StatefulSet, ReplicaSet o Job. Non puoi definire un buffer basato sulla percentuale per i modelli di pod perché non hanno un campo replicas.

In genere, ti consigliamo di iniziare con strategie di repliche fisse o di limiti delle risorse, anziché con buffer basati sulla percentuale. I buffer basati sulla percentuale sono meno reattivi agli scale up improvvisi se il carico di lavoro viene scalato a numeri bassi o zero, perché il margine di sicurezza viene scalato in proporzione ai pod attivi. Sono utili principalmente per i deployment di grandi dimensioni che non vengono mai scalati a un numero di repliche molto basso.

Per creare un buffer basato sulla percentuale, completa i seguenti passaggi:

  1. Salva il seguente manifest come cb-percentage-based.yaml:

    apiVersion: autoscaling.x-k8s.io/v1beta1
    kind: CapacityBuffer
    metadata:
      name: percentage-buffer
      namespace: NAMESPACE
    spec:
      scalableRef:
        apiGroup: apps
        kind: Deployment
        name: SCALABLE_RESOURCE_NAME
      percentage: 20
      provisioningStrategy: "STRATEGY"
    

    Sostituisci quanto segue:

    • NAMESPACE: il nome dello spazio dei nomi.
    • SCALABLE_RESOURCE_NAME: il nome della risorsa scalabile, ad esempio critical-workload-ref.
    • STRATEGY: la strategia di provisioning, "buffer.x-k8s.io/active-capacity" (impostazione predefinita) o "buffer.gke.io/standby-capacity".

    Questo manifest crea una risorsa CapacityBuffer che richiede una dimensione del buffer equivalente al 20% delle repliche della risorsa a cui viene fatto riferimento. Se utilizzi l'esempio di Deployment della sezione precedente, il valore della replica è impostato su 10.

  2. Applica il manifest:

    kubectl apply -f cb-percentage-based.yaml
    
  3. Verifica che GKE abbia applicato il buffer di capacità:

    kubectl get capacitybuffer percentage-buffer -n NAMESPACE
    

    Controlla lo stato di CapacityBuffer. Il campo replicas deve mostrare un valore derivato dal calcolo della percentuale. Se utilizzi l'esempio di Deployment della sezione precedente, dovresti visualizzare 2 unità di buffer, ovvero il 20% delle 10 repliche definite nel deployment.

  4. Testa la scalabilità dinamica eseguendo manualmente lo scale up del deployment a 20 repliche:

    kubectl scale deployment critical-workload-ref -n NAMESPACE --replicas=20
    

    Il controller CapacityBuffer reagisce ed esegue automaticamente lo scale up del buffer a 4 repliche.

Personalizza il comportamento del buffer di standby

Puoi utilizzare le annotazioni per personalizzare l'avvio e l'aggiornamento dei buffer di standby. Aggiungi queste annotazioni al campo metadata.annotations della risorsa CapacityBuffer:

  • buffer.gke.io/standby-capacity-init-time: la quantità di tempo in cui un nodo rimane attivo dopo la creazione prima di essere sospeso. Il formato è una stringa di durata (ad esempio, 5m o 1h). Il valore predefinito è 5m.
  • buffer.gke.io/standby-capacity-refresh-frequency: la frequenza con cui vengono aggiornati i nodi sospesi. Il valore predefinito è 24h.

L'esempio seguente mostra un manifest con questi campi facoltativi per personalizzare il comportamento dei buffer di standby:

apiVersion: autoscaling.x-k8s.io/v1beta1
kind: CapacityBuffer
metadata:
  name: customized-standby-buffer
  namespace: my-namespace
  annotations:
    buffer.gke.io/standby-capacity-init-time: "15m"
    buffer.gke.io/standby-capacity-refresh-frequency: "12h"
spec:
  podTemplateRef:
    name: buffer-unit-template
  replicas: 3
  provisioningStrategy: "buffer.gke.io/standby-capacity"

Precarica le immagini sui buffer di standby

Per velocizzare i tempi di avvio del carico di lavoro quando un nodo di standby viene riattivato, puoi precaricare le immagini container utilizzando un DaemonSet. Il DaemonSet viene eseguito durante il periodo di avvio prima che il nodo venga sospeso.

Per precaricare le immagini utilizzando il DaemonSet, completa i seguenti passaggi:

  1. Salva il seguente manifest come image-puller-daemonset.yaml:

    apiVersion: apps/v1
    kind: DaemonSet
    metadata:
      name: image-prefetch-daemonset
      namespace: NAMESPACE
    spec:
      selector:
        matchLabels:
          name: image-prefetch
      template:
        metadata:
          labels:
            name: image-prefetch
        spec:
          tolerations:
          - key: "buffer.gke.io/standby-node-suspended"
            operator: "Exists"
          initContainers:
          - name: image-puller
            image: IMAGE_NAME
            command: ["sh", "-c", "true"]
          containers:
          - name: pause
            image: registry.k8s.io/pause:3.9
    

    Sostituisci quanto segue:

    • NAMESPACE: lo spazio dei nomi per il DaemonSet, ad esempio capacity-buffer-example.
    • IMAGE_NAME: il nome dell'immagine da precaricare, ad esempio your-app-image:latest.
  2. Applica il manifest DaemonSet al cluster:

    kubectl apply -f image-puller-daemonset.yaml
    
  3. Verifica che il DaemonSet sia stato creato:

    kubectl get daemonset image-prefetch-daemonset -n NAMESPACE
    
  4. Verifica che il buffer di capacità sia stato creato e sia pronto per il provisioning:

    kubectl get capacitybuffer CAPACITY_BUFFER_NAME -n NAMESPACE
    

    Controlla lo stato. Il campo STATUS deve mostrare ReadyForProvisioning.

Monitora lo stato e il rendimento del buffer di capacità

Puoi monitorare lo stato e l'integrità dei buffer di capacità utilizzando i comandi kubectl e le metriche di Cloud Monitoring.

Verifica lo stato della risorsa CapacityBuffer

Per controllare l'integrità dei buffer di capacità e verificare che siano pronti a ricevere i carichi di lavoro, completa i seguenti passaggi:

  1. Ottieni lo stato di tutti i buffer di capacità nel cluster:

    kubectl get capacitybuffer -A
    
  2. Esamina lo stato dettagliato, le condizioni e i log degli eventi di un buffer specifico:

    kubectl describe capacitybuffer CAPACITY_BUFFER_NAME -n NAMESPACE
    

Identifica i nodi del buffer di standby sospesi

Le VM del buffer di standby sono sottoposte a pre-provisioning, ma vengono mantenute in uno stato sospeso per ridurre i costi. Puoi riconoscere questi nodi sospesi perché hanno una condizione personalizzata. Per controllare le istanze dei nodi sospesi, esegui il comando seguente:

kubectl get nodes -o custom-columns='NAME:.metadata.name,SUSPENDED:.status.conditions[?(@.type=="Suspended")].status'

Uno stato True indica che una VM di standby è sospesa. Uno stato False o <none> indica un nodo attivo in esecuzione.

Monitora il rendimento con Cloud Monitoring

Per monitorare il rendimento dei buffer di capacità, monitora le seguenti risorse in Cloud Monitoring:

  • Latenza di reazione (cluster_autoscaler/reaction_time_milliseconds): monitora la durata necessaria al gestore della scalabilità automatica del cluster per prendere una decisione di scalabilità in base alla domanda in attesa di CapacityBuffer.
  • Log del gestore della scalabilità automatica del cluster: cerca voci di log come "Capacity pod processor injecting ..." per osservare gli eventi di sostituzione dei pod del buffer attivo.

Rimuovi i buffer di capacità

Se non hai più bisogno di un buffer di capacità per i tuoi carichi di lavoro, elimina l'oggetto CapacityBuffer. In questo modo vengono rimossi i pod segnaposto e il gestore della scalabilità automatica del cluster può eseguire fare lo scale down dei nodi.

kubectl delete capacitybuffer CAPACITY_BUFFER_NAME -n NAMESPACE

Sostituisci CAPACITY_BUFFER_NAME con il nome del CapacityBuffer che vuoi eliminare.

Risoluzione dei problemi

La sezione seguente contiene informazioni sulla risoluzione dei problemi comuni relativi ai buffer di capacità.

Il buffer di capacità non è pronto a causa del modello di fatturazione

Se crei un CapacityBuffer per un carico di lavoro che utilizza il modello di fatturazione basato sui pod (pagamento in base all'utilizzo dei pod), il buffer di capacità non sarà pronto per il provisioning.

Per identificare questo problema, controlla lo stato di CapacityBuffer:

kubectl describe capacitybuffer BUFFER_NAME -n NAMESPACE

Cerca una condizione di tipo ReadyForProvisioning con uno stato False.

Per risolvere questo problema, assicurati che CapacityBuffer faccia riferimento a un carico di lavoro o a un PodTemplate compatibile con la fatturazione basata sui nodi.

Errori di autorizzazione per le risorse scalabili personalizzate

Se configuri un CapacityBuffer per funzionare con oggetti scalabili personalizzati (utilizzando il campo scalableRef), il gestore della scalabilità automatica del cluster potrebbe non riuscire a scalare il buffer se non dispone delle autorizzazioni necessarie.

Per risolvere questo problema, concedi manualmente le autorizzazioni richieste creando un ClusterRole e un ClusterRoleBinding, come nell'esempio seguente:

apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
  name: custom-scale-getter
rules:
- apiGroups: ["api.example.com"]
  resources: ["customreplicatedresources/scale"]
  verbs: ["get"]
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
  name: ca-custom-scale-getter
subjects:
- kind: User
  name: "system:cluster-autoscaler"
  namespace: kube-system
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: ClusterRole
  name: custom-scale-getter

Per ulteriori informazioni sulla configurazione di RBAC, consulta la documentazione di RBAC di Kubernetes.

Passaggi successivi