Questo documento descrive come abilitare Horizontal Pod Autoscaler (HPA) per Google Cloud Managed Service per Prometheus. Puoi abilitare HPA in uno dei seguenti modi:
- Utilizzando KEDA (Kubernetes Event-driven Autoscaling), una soluzione open source che ha ottenuto la laurea dalla Cloud Native Computing Foundation.
- Utilizzando la libreria Custom Metrics Stackdriver Adapter, sviluppata e supportata da Google Cloud.
- Utilizzando la libreria Prometheus Adapter di terze parti.
Non puoi utilizzare l'adattatore Stackdriver e l'adattatore Prometheus insieme nello stesso cluster perché le definizioni delle risorse si sovrappongono, come descritto in Risoluzione dei problemi. Ti consigliamo di scegliere una sola soluzione per HPA.
Utilizzare KEDA
KEDA (Kubernetes Event-driven Autoscaling) è il gestore della scalabilità automatica rilasciato più di recente che utilizza le metriche di Prometheus e sta diventando una soluzione preferita nella community di Prometheus.
Per iniziare, consulta la documentazione di KEDA per l'integrazione con Google Cloud Managed Service per Prometheus.
Utilizzare l'adattatore Stackdriver per le metriche personalizzate
L'adattatore Stackdriver per le metriche personalizzate supporta l'esecuzione di query sulle metriche di Managed Service per Prometheus a partire dalla versione v0.13.1 dell'adattatore.
Per configurare un esempio di configurazione HPA utilizzando l'adattatore Stackdriver per le metriche personalizzate:
- Configura la raccolta gestita nel cluster.
Installa l'adattatore Stackdriver per le metriche personalizzate nel cluster.
kubectl apply -f https://raw.githubusercontent.com/GoogleCloudPlatform/k8s-stackdriver/master/custom-metrics-stackdriver-adapter/deploy/production/adapter_new_resource_model.yamlEsegui 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.yamlQuesto comando esegue il deployment di un'applicazione di esportazione che emette la metrica
fooe una risorsa HPA. HPA scala questa applicazione fino a 5 repliche per raggiungere il valore target della metricafoo.Se utilizzi Workload Identity Federation for GKE, devi anche concedere il ruolo Monitoring Viewer al account di servizio con cui viene eseguito l'adattatore. Salta questo passaggio se non hai abilitato Workload Identity Federation for GKE sul tuo 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-adapterDefinisci 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: 30sEsegui il deployment della nuova risorsa PodMonitoring:
kubectl -n default apply -f podmonitoring.yamlNel giro di un paio di minuti, Managed Service per Prometheus elabora le metriche recuperate dall'esportatore e le archivia in Cloud Monitoring utilizzando un nome in formato lungo. Le metriche di Prometheus vengono archiviate con le seguenti convenzioni:
- Il prefisso
prometheus.googleapis.com. - Questo suffisso è in genere uno tra
gauge,counter,summary, ohistogram, anche se le metriche senza tipo potrebbero avere il suffissounknownounknown:counter. Per verificare il suffisso, cerca la metrica in Cloud Monitoring utilizzando Metrics Explorer.
- Il prefisso
Aggiorna l'HPA di cui hai eseguito il deployment per eseguire query sulla metrica da Cloud Monitoring. La metrica
fooviene importata comeprometheus.googleapis.com/foo/gauge. Per rendere la metrica interrogabile dalla risorsa HorizontalPodAutoscaler di cui hai eseguito il deployment, utilizza il nome in formato lungo nell'HPA di cui hai eseguito il deployment, ma devi modificarlo sostituendo tutti gli slash (/) con il carattere pipe (|):prometheus.googleapis.com|foo|gauge. Per ulteriori informazioni, consulta la sezione Metriche disponibili da Stackdriver del repository dell'adattatore Stackdriver per le metriche personalizzate.Aggiorna l'HPA di cui hai eseguito il deployment eseguendo il seguente comando:
kubectl edit hpa custom-metric-prometheus-sdModifica il valore del campo
pods.metric.namedafooaprometheus.googleapis.com|foo|gauge. La sezionespecdovrebbe essere simile alla seguente: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 della metrica
prometheus.googleapis.com/foo/gaugepari a20. Poiché il deployment imposta il valore della metrica su40, il controller HPA aumenta il numero di pod fino al valore del campomaxReplicas(5) per cercare di ridurre il valore medio della metrica in tutti i pod a20.La query HPA è limitata allo spazio dei nomi e al cluster in cui è installata la risorsa HPA, quindi le metriche identiche in altri cluster e spazi dei nomi non influiscono sulla scalabilità automatica.
Per osservare il fare lo scale up del carico di lavoro, esegui il seguente comando:
kubectl get hpa custom-metric-prometheus-sd --watchIl valore del campo
REPLICAScambia da1a5.NAME REFERENCE TARGETS MINPODS MAXPODS REPLICAS AGE custom-metric-prometheus-sd Deployment/custom-metric-prometheus-sd 40/20 1 5 5 *
Per fare lo scale down del deployment, aggiorna il valore della metrica target in modo che sia superiore al valore della metrica esportata. In questo esempio, il deployment imposta il valore della metrica
prometheus.googleapis.com/foo/gaugesu40. Se imposti il valore target su un numero maggiore di40, il deployment verrà fare lo scale down.Ad esempio, utilizza
kubectl editper modificare il valore del campopods.target.averageValuenella configurazione HPA da20a100.kubectl edit hpa custom-metric-prometheus-sdModifica la sezione delle specifiche in modo che corrisponda alla seguente:
spec: maxReplicas: 5 metrics: - pods: metric: name: prometheus.googleapis.com|foo|gauge target: averageValue: "100" type: AverageValue type: Pods minReplicas: 1Per osservare lo fare lo scale down del carico di lavoro, esegui il seguente comando:
kubectl get hpa custom-metric-prometheus-sd --watchIl valore del campo
REPLICAScambia da5a1. Per impostazione predefinita, questa operazione avviene più lentamente rispetto alla scalabilità 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 *
Per liberare spazio dall'esempio di cui hai eseguito il deployment, esegui i seguenti 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 l'esempio di Prometheus nel repository dell'adattatore Stackdriver per le metriche personalizzate o consulta Scalare un'applicazione.
Utilizzare l'adattatore Prometheus
Le configurazioni esistenti di prometheus-adapter possono essere utilizzate per la scalabilità automatica con poche modifiche. La configurazione di prometheus-adapter per la scalabilità utilizzando Managed Service per Prometheus presenta due limitazioni aggiuntive rispetto alla scalabilità utilizzando Prometheus upstream:
Le query devono essere instradate tramite il proxy dell'UI frontend di Prometheus, proprio come quando esegui query su Managed Service per Prometheus utilizzando l'API o l'UI. Per prometheus-adapter, devi modificare il
prometheus-adapterdeployment per modificare ilprometheus-urlvalore come segue:--prometheus-url=http://frontend.NAMESPACE_NAME.svc:9090/
dove NAMESPACE_NAME è lo spazio dei nomi in cui è stato eseguito il deployment del frontend.
Non puoi utilizzare un matcher di espressioni regolari (
=~o!~) su un nome di metrica nel campo.seriesQuerydella configurazione delle regole. Devi invece specificare completamente i nomi delle metriche. Per alcune soluzioni alternative, consulta Compatibilità con PromQL.
Poiché i dati potrebbero impiegare un po' più di tempo per essere disponibili in Managed Service per Prometheus rispetto a Prometheus upstream, la configurazione di una logica di scalabilità automatica eccessivamente rapida potrebbe causare un comportamento indesiderato. Sebbene non vi sia alcuna garanzia sull'aggiornamento dei dati, in genere i dati sono disponibili per le query 3-7 secondi dopo l'invio a Managed Service per Prometheus, escluse eventuali latenze di rete.
Tutte le query emesse da prometheus-adapter hanno portata globale. Ciò significa che se hai applicazioni in due spazi dei nomi che emettono metriche con lo stesso nome, una configurazione HPA che utilizza questa metrica viene scalata utilizzando i dati di entrambe le applicazioni. Ti consigliamo di utilizzare sempre i filtri namespace o cluster in PromQL per evitare la scalabilità utilizzando dati errati.
Per configurare un esempio di configurazione HPA utilizzando prometheus-adapter e la raccolta gestita, segui questi passaggi:
- Configura la raccolta gestita nel cluster.
- Esegui il deployment del proxy dell'UI frontend di Prometheus nel tuo cluster. Se utilizzi Workload Identity Federation for GKE, devi anche configurare e autorizzare un service account.
- Esegui il deployment dei manifest nella directory
examples/hpa/all'interno del repository prometheus-engine:example-app.yaml: un esempio di deployment e servizio che emette metriche.pod-monitoring.yaml: una risorsa che configura il recupero delle metriche di esempio.hpa.yaml: la risorsa HPA che configura la scalabilità per il carico di lavoro.
Assicurati che
prometheus-adaptersia installato nel cluster. Per farlo, puoi eseguire il deployment del manifest di installazione di esempio nel cluster. Questo manifest è configurato per:- Eseguire query su un proxy frontend di cui è stato eseguito il deployment nello spazio dei nomi
default. - Emettere PromQL per calcolare e restituire la metrica
http_requests_per_seconddal deployment di esempio.
- Eseguire query su un proxy frontend di cui è stato eseguito il deployment nello spazio dei nomi
Esegui i seguenti comandi, ognuno in una sessione del terminale separata:
- 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" - Osserva Horizontal Pod Autoscaler:
kubectl get hpa prometheus-example-app --watch - Osserva il carico di lavoro fare lo scale up:
kubectl get po -lapp.kubernetes.io/name=prometheus-example-app --watch
- Genera carico HTTP sul servizio
Interrompi la generazione del carico HTTP utilizzando Ctrl+C e osserva la riduzione del carico di lavoro.
Risoluzione dei problemi
L'adattatore Stackdriver per le metriche personalizzate utilizza definizioni di risorse con gli stessi nomi di quelli dell'adattatore Prometheus, prometheus-adapter. Questa sovrapposizione di nomi significa che l'esecuzione di più di un adattatore nello stesso cluster causa errori.
L'installazione dell'adattatore Prometheus in un cluster in cui era stato installato in precedenza l'adattatore Stackdriver per le metriche personalizzate potrebbe generare errori come FailedGetObjectMetric a causa di nomi in conflitto. Per risolvere il problema, potrebbe essere necessario eliminare gli apiservice v1beta1.external.metrics.k8s.io, v1beta1.custom.metrics.k8s.io e v1beta2.custom.metrics.k8s.io registrati in precedenza dall'adattatore delle metriche personalizzate.
Suggerimenti per la risoluzione dei problemi:
Alcune metriche di sistema di Cloud Monitoring, come le metriche di Pub/Sub metrics, vengono ritardate di 60 secondi o più. Poiché l'adattatore Prometheus esegue le query utilizzando il timestamp corrente, l'esecuzione di query su queste metriche utilizzando l'adattatore Prometheus potrebbe restituire erroneamente nessun dato. Per eseguire query sulle metrico ritardate, utilizza il modificatore
offsetin PromQL per modificare l'offset temporale della query della quantità necessaria.Per verificare che il proxy dell'UI frontend funzioni come previsto e che non ci siano problemi con le autorizzazioni, esegui il seguente comando in un terminale:
kubectl -n NAMESPACE_NAME port-forward svc/frontend 9090
Apri un altro terminale ed esegui il seguente comando:
curl --silent 'localhost:9090/api/v1/series?match%5B%5D=up'
Quando il proxy dell'UI frontend funziona correttamente, la risposta nel secondo terminale è simile alla seguente:
curl --silent 'localhost:9090/api/v1/series?match%5B%5D=up' | jq . { "status": "success", "data": [ ... ] }Se ricevi un errore 403, significa che il proxy dell'UI frontend non è configurato correttamente. Per informazioni su come risolvere un errore 403, consulta la guida Configurare e autorizzare un service account.
Per verificare che l'apiserver delle metriche personalizzate sia disponibile, esegui il seguente 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 HPA funzioni come previsto, esegui il seguente 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, significa che HPA non funziona. Di seguito è riportata una risposta alla chiamatadescribequando 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 Quando HPA non funziona, assicurati di generare metriche con
load-generator. Puoi controllare direttamente l'API delle metriche personalizzate con il comando:kubectl get --raw "/apis/custom.metrics.k8s.io/v1beta1/" | jq .
Un output riuscito è 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 saranno presenti dati in
"resources"nell' output, ad esempio:kubectl get --raw "/apis/custom.metrics.k8s.io/v1beta1/" | jq . { "kind": "APIResourceList", "apiVersion": "v1", "groupVersion": "custom.metrics.k8s.io/v1beta1", "resources": [] }