Scalabilità automatica orizzontale dei pod (HPA)

Questo documento descrive come abilitare la scalabilità automatica orizzontale dei pod (HPA) per Google Cloud Managed Service per Prometheus. Puoi attivare l'HPA eseguendo una delle seguenti operazioni:

Devi scegliere l'uno o l'altro. Non puoi utilizzare entrambi perché la sua le definizioni delle risorse si sovrappongono, come descritto in Risoluzione dei problemi.

Utilizza l'adattatore Stackdriver per metriche personalizzate

Stackdriver Adapter per metriche personalizzate supporta le query sulle metriche Managed Service per Prometheus a partire da versione v0.13.1 dell'adattatore.

Impostazione di una configurazione HPA di esempio utilizzando Stackdriver metriche personalizzate dell'adattatore, procedi nel seguente modo:

  1. Configura la raccolta gestita nel tuo cluster.
  2. Installa l'adattatore Stackdriver per metriche personalizzate nel tuo cluster.

    kubectl apply -f https://raw.githubusercontent.com/GoogleCloudPlatform/k8s-stackdriver/master/custom-metrics-stackdriver-adapter/deploy/production/adapter_new_resource_model.yaml
    
  3. Esegui il deployment di un esportatore di metriche Prometheus di esempio e di una risorsa HPA:

    kubectl apply -f https://raw.githubusercontent.com/GoogleCloudPlatform/k8s-stackdriver/master/custom-metrics-stackdriver-adapter/examples/prometheus-to-sd/custom-metrics-prometheus-sd.yaml
    

    Questo comando esegue il deployment di un'applicazione di esportazione che emette la metrica foo e una risorsa HPA. HPA scala questa applicazione fino a 5 repliche il valore target della metrica foo.

  4. Se utilizzi Workload Identity, devi concedere anche il visualizzatore Monitoring all'account di servizio in cui viene eseguito l'adattatore. Ignora questo passaggio se non hanno Workload Identity abilitato su Kubernetes di un cluster Kubernetes.

    export PROJECT_NUMBER=$(gcloud projects describe PROJECT_ID --format 'get(projectNumber)')
    gcloud projects add-iam-policy-binding projects/PROJECT_ID \
      --role roles/monitoring.viewer \
      --member=principal://iam.googleapis.com/projects/$PROJECT_NUMBER/locations/global/workloadIdentityPools/PROJECT_ID.svc.id.goog/subject/ns/custom-metrics/sa/custom-metrics-stackdriver-adapter
    
  5. Definisci una risorsa PodMonitoring inserendo la seguente configurazione in un file denominato podmonitoring.yaml.

    apiVersion: monitoring.googleapis.com/v1
    kind: PodMonitoring
    metadata:
      name: prom-example
    spec:
      selector:
        matchLabels:
          run: custom-metric-prometheus-sd
      endpoints:
      - port: 8080
        interval: 30s
    
  6. Esegui il deployment della nuova risorsa PodMonitoring:

    kubectl -n default apply -f podmonitoring.yaml
    

    In un paio di minuti, Managed Service per Prometheus elabora di metriche di cui è stato eseguito lo scraping da parte dell'esportatore e le archivia in Cloud Monitoring utilizzando un nome nel formato lungo. Le metriche di Prometheus vengono archiviate secondo le seguenti convenzioni:

    • Il prefisso prometheus.googleapis.com.
    • In genere questo suffisso è uno dei seguenti: gauge, counter, summary o histogram. anche se le metriche non digitate potrebbero avere il suffisso unknown o unknown:counter. Per verificare il suffisso, cerca la metrica in Cloud Monitoring utilizzando Metrics Explorer.
  7. Aggiorna l'HPA di cui è stato eseguito il deployment per eseguire query sulla metrica da Cloud Monitoring. La la metrica foo viene importata come prometheus.googleapis.com/foo/gauge. Per rendere la metrica interrogabile dalla risorsa HorizontalPodAutoscaler di cui è stato eseguito il deployment, utilizza il nome nel formato lungo nell'HPA di cui è stato eseguito il deployment, ma devi modificarlo sostituendo tutte le barre (/) con il carattere barra verticale (|): prometheus.googleapis.com|foo|gauge. Per ulteriori informazioni, consulta Metriche disponibili nella sezione Stackdriver del repository delle metriche personalizzate di Stackdriver Adapter.

    1. Aggiorna l'HPA di cui è stato eseguito il deployment eseguendo questo comando:

      kubectl edit hpa custom-metric-prometheus-sd
      
    2. Modifica il valore del campo pods.metric.name da foo a prometheus.googleapis.com|foo|gauge. La sezione spec deve avere il seguente aspetto le seguenti:

      spec:
         maxReplicas: 5
         metrics:
         - pods:
             metric:
               name: prometheus.googleapis.com|foo|gauge
             target:
               averageValue: "20"
               type: AverageValue
           type: Pods
         minReplicas: 1
      

    In questo esempio, la configurazione HPA cerca il valore medio del la metrica prometheus.googleapis.com/foo/gauge deve essere 20. Poiché Il deployment imposta il valore della metrica 40, il controller HPA aumenta il numero di pod fino al valore del campo maxReplicas (5) per provare a riduci il valore medio della metrica in tutti i pod a 20.

    La query HPA ha come ambito lo spazio dei nomi e il cluster in cui di una risorsa preinstallata, quindi metriche identiche in altri cluster senza influire sulla scalabilità automatica.

  8. Per osservare lo scale up del carico di lavoro, esegui questo comando:

    kubectl get hpa custom-metric-prometheus-sd --watch
    

    Il valore del campo REPLICAS cambia da 1 a 5.

    NAME                          REFERENCE                                TARGETS        MINPODS   MAXPODS   REPLICAS   AGE
    custom-metric-prometheus-sd   Deployment/custom-metric-prometheus-sd   40/20          1         5         5          *
    
  9. Per fare lo scale down del deployment, aggiorna il valore della metrica target superiore al valore della metrica esportata. In questo esempio, il deployment imposta il valore della metrica prometheus.googleapis.com/foo/gauge su 40. Se imposti il valore target su un numero superiore a 40, lo fare lo scale down del deployment.

    Ad esempio, utilizza kubectl edit per modificare il valore dell'attributo pods.target.averageValue della configurazione HPA da 20 a 100.

    kubectl edit hpa custom-metric-prometheus-sd
    

    Modifica la sezione delle specifiche in modo che corrisponda a quanto segue:

    spec:
      maxReplicas: 5
      metrics:
      - pods:
          metric:
            name: prometheus.googleapis.com|foo|gauge
          target:
            averageValue: "100"
            type: AverageValue
      type: Pods
      minReplicas: 1
    
  10. Per osservare lo fare lo scale down del carico di lavoro, esegui questo comando:

    kubectl get hpa custom-metric-prometheus-sd --watch
    

    Il valore del campo REPLICAS cambia da 5 a 1. Per impostazione predefinita, questo avviene più lentamente rispetto allo scale up del numero di pod:

    NAME                          REFERENCE                                TARGETS        MINPODS   MAXPODS   REPLICAS   AGE
    custom-metric-prometheus-sd   Deployment/custom-metric-prometheus-sd   40/100          1         5         1          *
    
  11. Per eseguire la pulizia dell'esempio di cui è stato eseguito il deployment, esegui questi comandi:

    kubectl delete -f https://raw.githubusercontent.com/GoogleCloudPlatform/k8s-stackdriver/master/custom-metrics-stackdriver-adapter/deploy/production/adapter_new_resource_model.yaml
    kubectl delete -f https://raw.githubusercontent.com/GoogleCloudPlatform/k8s-stackdriver/master/custom-metrics-stackdriver-adapter/examples/prometheus-to-sd/custom-metrics-prometheus-sd.yaml
    kubectl delete podmonitoring/prom-example
    

Per ulteriori informazioni, consulta Esempio di Prometheus nel repository delle metriche personalizzate di Stackdriver Adapter oppure consulta Scalabilità di un'applicazione.

Utilizzare l'adattatore Prometheus

Le configurazioni dell'adattatore Prometheus esistenti possono essere usate per la scalabilità automatica con modifiche. Configurazione dell'adattatore Prometheus per la scalabilità utilizzando Managed Service per Prometheus prevede due limitazioni aggiuntive rispetto alla scalabilità con l'utilizzo di Prometheus upstream:

Poiché potrebbe essere necessario più tempo prima che i dati siano disponibili entro Managed Service per Prometheus a confronto con Prometheus upstream, configurando una logica di scalabilità automatica eccessivamente esaustiva potrebbe causare comportamenti indesiderati. Sebbene esistano Nessuna garanzia sull'aggiornamento dei dati, in genere i dati sono disponibili per le query 3-7 secondi dopo essere stato inviato a Managed Service per Prometheus, esclusa qualsiasi rete una latenza di pochi millisecondi.

Tutte le query eseguite dall'adattatore Prometheus hanno un ambito globale. Ciò significa che se hai applicazioni in due spazi dei nomi che emettono metriche con nomi identici, una configurazione HPA che utilizza questa metrica scala utilizzando i dati diverse applicazioni. Ti consigliamo di utilizzare sempre i filtri namespace o cluster in il tuo PromQL per evitare di scalare utilizzando dati errati.

Impostare una configurazione HPA di esempio utilizzando l'adattatore Prometheus e segui questi passaggi:

  1. Configura la raccolta gestita nel tuo cluster.
  2. Esegui il deployment del proxy della UI frontend di Prometheus nel tuo in un cluster Kubernetes. Se utilizzi Workload Identity, devi anche configurare e autorizzare un account di servizio.
  3. Esegui il deployment dei manifest nella directory examples/hpa/ all'interno della repository prometheus-engine:
    • example-app.yaml: un deployment e un servizio di esempio che invia metriche.
    • pod-monitoring.yaml: una risorsa che configura lo scraping dell'esempio metrics.
    • hpa.yaml: la risorsa HPA che configura la scalabilità per il carico di lavoro.
  4. Assicurati che prometheus-adapter sia installato nel cluster. A questo scopo, puoi eseguire il deployment il manifest di installazione di esempio per il cluster. Questo manifest è configurato per:

    • Esegui una query su un proxy frontend di cui è stato eseguito il deployment nello spazio dei nomi default.
    • Emetti PromQL per calcolare e restituire la metrica http_requests_per_second del deployment di esempio.
  5. Esegui questi comandi, ciascuno in una sessione di terminale separata:

    1. Genera carico HTTP sul servizio prometheus-example-app:
      kubectl run -i --tty load-generator --rm --image=busybox:1.28 --restart=Never -- /bin/sh -c "while sleep 0.01; do wget -q -O- http://prometheus-example-app; done"
    2. Guarda Horizontal Pod Autoscaler:
      kubectl get hpa prometheus-example-app --watch
    3. Osserva lo scale up del carico di lavoro:
      kubectl get po -lapp.kubernetes.io/name=prometheus-example-app --watch
  6. Interrompi la generazione del carico HTTP utilizzando Ctrl+C e controlla che il carico di lavoro venga ridimensionato verso il basso.

Risoluzione dei problemi

Metriche personalizzate Stackdriver Adapter utilizza definizioni di risorse con gli stessi nomi di quelle dell'adattatore Prometheus, prometheus-adapter. Questa sovrapposizione di nomi significa che l'esecuzione di più adattatori nello stesso cluster causa errori.

Installazione dell'adattatore Prometheus in un cluster che in precedenza aveva il modello Le metriche che Stackdriver Adapter installato potrebbe generare errori come FailedGetObjectMetric a causa di nomi in conflitto. Per risolvere il problema, potresti dover per eliminare v1beta1.external.metrics.k8s.io, v1beta1.custom.metrics.k8s.io e v1beta2.custom.metrics.k8s.io apiservices precedentemente registrato da Custom Metrics Adapter.

Suggerimenti per la risoluzione dei problemi:

  • Alcune metriche di sistema di Cloud Monitoring, come Pub/Sub metriche presentano un ritardo di almeno 60 secondi. Come Prometheus L'adattatore esegue le query utilizzando il timestamp corrente, eseguendo query su queste metriche quando si utilizza l'adattatore Prometheus potrebbe non restituire dati in modo corretto. Per eseguire una query le metriche ritardate, usa il modificatore offset in PromQL per modifica lo offset temporale della query in base alla quantità necessaria.

  • Per verificare che il proxy della UI frontend funzioni come previsto e non ci sono problemi con le autorizzazioni, esegui questo comando in un terminale:

    kubectl -n NAMESPACE_NAME port-forward svc/frontend 9090
    

    Quindi, apri un altro terminale ed esegui questo comando:

    curl --silent 'localhost:9090/api/v1/series?match%5B%5D=up'
    

    Quando il proxy UI frontend funziona correttamente, la risposta nel secondo è simile al seguente:

    curl --silent 'localhost:9090/api/v1/series?match%5B%5D=up' | jq .
    {
      "status": "success",
      "data": [
         ...
      ]
    }
    

    Se ricevi un errore 403, il proxy UI frontend non è correttamente configurato. Per informazioni su come risolvere l'errore 403, consulta la sezione configurazione e autorizzare un account di servizio.

  • Per verificare che la metrica personalizzata apiserver sia disponibile, esegui questo comando: :

    kubectl get apiservices.apiregistration.k8s.io v1beta1.custom.metrics.k8s.io
    

    Quando l'apiserver è disponibile, la risposta è simile alla seguente:

    $ kubectl get apiservices.apiregistration.k8s.io v1beta1.custom.metrics.k8s.io
    NAME                            SERVICE                         AVAILABLE   AGE
    v1beta1.custom.metrics.k8s.io   monitoring/prometheus-adapter   True        33m
    
  • Per verificare che l'HPA funzioni come previsto, esegui questo comando:

    $ kubectl describe hpa prometheus-example-app
    Name:                                  prometheus-example-app
    Namespace:                             default
    Labels:                                
    Annotations:                           
    Reference:                             Deployment/prometheus-example-app
    Metrics:                               ( current / target )
    "http_requests_per_second" on pods:  11500m / 10
    Min replicas:                          1
    Max replicas:                          10
    Deployment pods:                       2 current / 2 desired
    Conditions:
    Type            Status  Reason              Message
    ----            ------  ------              -------
    AbleToScale     True    ReadyForNewScale    recommended size matches current size
    ScalingActive   True    ValidMetricFound    the HPA was able to successfully calculate a replica count from pods metric http_requests_per_second
    ScalingLimited  False   DesiredWithinRange  the desired count is within the acceptable range
    Events:
    Type     Reason               Age                   From                       Message
    ----     ------               ----                  ----                       -------
    Normal   SuccessfulRescale    47s                   horizontal-pod-autoscaler  New size: 2; reason: pods metric http_requests_per_second above target
    

    Quando la risposta contiene un'istruzione come FailedGetPodsMetric, la macro Errore HPA. Di seguito viene illustrata una risposta alla chiamata describe quando l'HPA non funziona:

    $ kubectl describe hpa prometheus-example-app
    Name:                                  prometheus-example-app
    Namespace:                             default
    Reference:                             Deployment/prometheus-example-app
    Metrics:                               ( current / target )
      "http_requests_per_second" on pods:   / 10
    Min replicas:                          1
    Max replicas:                          10
    Deployment pods:                       1 current / 1 desired
    Conditions:
      Type            Status  Reason               Message
      ----            ------  ------               -------
      AbleToScale     True    ReadyForNewScale     recommended size matches current size
      ScalingActive   False   FailedGetPodsMetric  the HPA was unable to compute the replica count: unable to get metric http_requests_per_second: unable to fetch metrics from custom metrics API: the server could not find the metric http_requests_per_second for pods
      ScalingLimited  False   DesiredWithinRange   the desired count is within the acceptable range
    Events:
      Type     Reason               Age                   From                       Message
      ----     ------               ----                  ----                       -------
      Warning  FailedGetPodsMetric  104s (x11 over 16m)   horizontal-pod-autoscaler  unable to get metric http_requests_per_second: unable to fetch metrics from custom metrics API: the server could not find the metric http_requests_per_second for pods
    

    Se l'HPA non funziona, assicurati di generare metriche con load-generator. Puoi controllare direttamente l'API delle metriche personalizzate, con :

    kubectl get --raw "/apis/custom.metrics.k8s.io/v1beta1/" | jq .
    

    Un output riuscito dovrebbe essere simile al seguente:

    $ kubectl get --raw "/apis/custom.metrics.k8s.io/v1beta1/" | jq .
      {
      "kind": "APIResourceList",
      "apiVersion": "v1",
      "groupVersion": "custom.metrics.k8s.io/v1beta1",
      "resources": [
         {
            "name": "namespaces/http_requests_per_second",
            "singularName": "",
            "namespaced": false,
            "kind": "MetricValueList",
            "verbs": [
            "get"
            ]
         },
         {
            "name": "pods/http_requests_per_second",
            "singularName": "",
            "namespaced": true,
            "kind": "MetricValueList",
            "verbs": [
            "get"
            ]
         }
      ]
      }
    

    Se non sono presenti metriche, non ci saranno dati in "resources" nella come output, ad esempio:

    kubectl get --raw "/apis/custom.metrics.k8s.io/v1beta1/" | jq .
    {
    "kind": "APIResourceList",
    "apiVersion": "v1",
    "groupVersion": "custom.metrics.k8s.io/v1beta1",
    "resources": []
    }