Questo documento descrive come abilitare l'autoscaling orizzontale dei pod (HPA) per Google Cloud Managed Service per Prometheus. Per attivare l'HPA, puoi eseguire una delle seguenti operazioni:
- Utilizzo della libreria Custom Metrics Stackdriver Adapter, sviluppata e supportata da Google Cloud.
- Utilizzo della libreria Prometheus Adapter di terze parti.
Devi scegliere un approccio o l'altro. Non puoi utilizzarli entrambi perché le loro definizioni delle risorse si sovrappongono, come descritto nella sezione Risoluzione dei problemi.
Utilizzare l'adattatore Stackdriver delle metriche personalizzate
L'adattatore Stackdriver per le metriche personalizzate supporta le query sulle metriche del servizio gestito per Prometheus a partire dalla versione 0.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 delle 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
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. L'HPA esegue il ridimensionamento di questa applicazione fino a 5 repliche per raggiungere il valore target per la metricafoo
.Se utilizzi la federazione delle identità per i carichi di lavoro per GKE, devi concedere anche il ruolo Visualizzatore monitoraggio all'account di servizio in cui viene eseguito l'adattatore. Salta questo passaggio se non hai attivato Workload Identity Federation for GKE nel 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-adapter
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
Esegui il deployment della nuova risorsa PodMonitoring:
kubectl -n default apply -f podmonitoring.yaml
Entro un paio di minuti, Managed Service per Prometheus elabora le metriche tratte dall'esportatore e le memorizza in Cloud Monitoring utilizzando un nome lungo. Le metriche Prometheus vengono archiviate con le seguenti convenzioni:
- Il prefisso
prometheus.googleapis.com
. - In genere, questo suffisso è
gauge
,counter
,summary
ohistogram
, anche se le metriche non scritte potrebbero avere il suffissounknown
ounknown:counter
. Per verificare il suffisso, cerca la metrica in Cloud Monitoring utilizzando Metrics Explorer.
- Il prefisso
Aggiorna l'HPA di cui è stato eseguito il deployment per eseguire query sulla metrica da Cloud Monitoring. La metrica
foo
viene importata comeprometheus.googleapis.com/foo/gauge
. Per consentire di eseguire query sulla metrica dalla risorsa HorizontalPodAutoscaler di cui è stato eseguito il deployment, devi utilizzare 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 la sezione Metriche disponibili in Stackdriver del repository dell'adattatore Stackdriver per le metriche personalizzate.Aggiorna l'HPA di cui è stato eseguito il deployment eseguendo il seguente comando:
kubectl edit hpa custom-metric-prometheus-sd
Modifica il valore del campo
pods.metric.name
dafoo
aprometheus.googleapis.com|foo|gauge
. La sezionespec
dovrebbe avere il seguente aspetto: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/gauge
pari 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 provare a ridurre il valore medio della metrica su tutti i pod a20
.L'ambito della query HPA è limitato allo spazio dei nomi e al cluster in cui è installata la risorsa HPA, pertanto le metriche identiche in altri cluster e spazi dei nomi non influiscono sulla scalabilità automatica.
Per monitorare l'aumento del carico di lavoro, esegui il seguente comando:
kubectl get hpa custom-metric-prometheus-sd --watch
Il valore del campo
REPLICAS
cambia da1
a5
.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 la scalabilità dell'implementazione, 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/gauge
su40
. Se imposti il valore target su un numero superiore a40
, il deployment verrà fare lo scale down.Ad esempio, utilizza
kubectl edit
per modificare il valore del campopods.target.averageValue
nella configurazione HPA da20
a100
.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
Per monitorare la fare lo scale down del carico di lavoro, esegui il seguente comando:
kubectl get hpa custom-metric-prometheus-sd --watch
Il valore del campo
REPLICAS
cambia da5
a1
. Per impostazione predefinita, 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 *
Per ripulire l'esempio di cui è stato 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 Prometheus nel repository dell'adattatore Stackdriver per le metriche personalizzate o consulta la sezione Eseguire il ridimensionamento di un'applicazione.
Utilizzare l'adattatore Prometheus
Le configurazioni esistenti di prometheus-adapter possono essere utilizzate per la scalabilità automatica con solo alcune modifiche. La configurazione di prometheus-adapter per la scalabilità utilizzando Managed Service per Prometheus ha due limitazioni aggiuntive rispetto alla scalabilità utilizzando Prometheus a monte:
Le query devono essere inoltrate tramite il proxy dell'interfaccia utente frontend di Prometheus, proprio come accade quando esegui query su Managed Service per Prometheus utilizzando l'API o l'interfaccia utente di Prometheus. Per prometheus-adapter, devi modificare il deployment
prometheus-adapter
per modificare il valoreprometheus-url
come segue:--prometheus-url=http://frontend.NAMESPACE_NAME.svc:9090/
dove NAMESPACE_NAME è lo spazio dei nomi in cui è dipiegato il frontend.
Non puoi utilizzare una corrispondenza regex per un nome di metrica nel campo
.seriesQuery
della configurazione delle regole. Devi invece specificare completamente i nomi delle metriche.
Poiché i dati possono richiedere un po' più di tempo per essere disponibili in Managed Service per Prometheus rispetto a Prometheus a monte, la configurazione di una logica di scalabilità automatica eccessivamente anticipata potrebbe causare comportamenti indesiderati. Anche se non c'è alcuna garanzia sull'aggiornamento dei dati, in genere è possibile eseguire query sui dati 3-7 secondi dopo che sono stati inviati a Managed Service per Prometheus, esclusa la latenza della rete.
Tutte le query emesse da prometheus-adapter hanno ambito 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 esegue il ridimensionamento utilizzando i dati di entrambe le applicazioni. Ti consigliamo di utilizzare sempre i filtri namespace
o cluster
nel
tuo PromQL per evitare di eseguire il ridimensionamento 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'interfaccia utente del frontend Prometheus nel cluster. Se utilizzi la federazione delle identità per i carichi di lavoro per GKE, devi anche configurare e autorizzare un account di servizio.
- Esegui il deployment dei manifest nella directory
examples/hpa/
all'interno del repo prometheus-engine:example-app.yaml
: un esempio di implementazione e servizio che emette metriche.pod-monitoring.yaml
: una risorsa che configura lo scraping delle metriche di esempio.hpa.yaml
: la risorsa HPA che configura il ridimensionamento per il tuo carico di lavoro.
Assicurati che
prometheus-adapter
sia installato nel cluster. Per farlo, puoi eseguire il deployment del manifest di installazione di esempio nel cluster. Questo manifest è configurato per:- Esegui una query su un proxy frontend di cui è stato eseguito il deployment nello spazio dei nomi
default
. - Esegui una query PromQL per calcolare e restituire la metrica
http_requests_per_second
dall'implementazione di esempio.
- Esegui una query su un proxy frontend di cui è stato eseguito il deployment nello spazio dei nomi
Esegui i seguenti comandi, ciascuno in una sessione del terminale separata:
- Genera un 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"
- Monitora il gestore della scalabilità automatica orizzontale dei pod:
kubectl get hpa prometheus-example-app --watch
- Guarda come viene scalato il carico di lavoro:
kubectl get po -lapp.kubernetes.io/name=prometheus-example-app --watch
- Genera un 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 delle risorse con gli stessi nomi di quelle nell'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 precedentemente installato l'adattatore Stackdriver per le metriche personalizzate potrebbe generare errori comeFailedGetObjectMetric
a causa di nomi in conflitto. Per risolvere il problema, potresti dover eliminare gli apiservice v1beta1.external.metrics.k8s.io
, v1beta1.custom.metrics.k8s.io
e v1beta2.custom.metrics.k8s.io
precedentemente registrati dall'adattatore delle metriche personalizzate.
Suggerimenti per la risoluzione dei problemi:
Alcune metriche di sistema di Cloud Monitoring, come le metriche Pub/Sub, sono in ritardo di almeno 60 secondi. Poiché Prometheus Adapter esegue query utilizzando il timestamp corrente, eseguire query su queste metriche utilizzando Prometheus Adapter potrebbe non restituire dati in modo errato. Per eseguire query sulle metriche ritardate, utilizza il modificatore
offset
in PromQL per modificare l'offset temporale della query dell'importo necessario.Per verificare che il proxy dell'interfaccia utente 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
Quindi, apri un altro terminale ed esegui il seguente comando:
curl --silent 'localhost:9090/api/v1/series?match%5B%5D=up'
Quando il proxy dell'interfaccia utente frontend funziona correttamente, la risposta nel secondo terminal è 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'interfaccia utente frontend non è configurato correttamente. Per informazioni su come risolvere un errore 403, consulta la guida su come configurare e autorizzare un account di servizio.
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 l'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 l'HPA non funziona. Di seguito è riportata una risposta alla chiamatadescribe
quando l'HPA non va a buon fine:$ 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 l'HPA non funziona, assicurati di generare le 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 corretto dovrebbe avere il seguente aspetto:
$ 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": [] }