
La scalabilità è un requisito fondamentale per le applicazioni cloud. Con Kubernetes, scalare un'applicazione è semplice quanto aumentare il numero di repliche per il relativo deployment o ReplicaSet — ma questo è un processo manuale.
Kubernetes consente di scalare automaticamente le applicazioni (cioè i Pod in un deployment o ReplicaSet) in modo dichiarativo utilizzando la specifica Horizontal Pod Autoscaler. Di default, il criterio per la scalabilità automatica sono le metriche di utilizzo della CPU (metriche delle risorse), ma è possibile integrare metriche personalizzate e metriche fornite dall'esterno.
Team ha tradotto un articolo su come utilizzare metriche esterne per la scalabilità automatica delle applicazioni Kubernetes. Per dimostrare come funziona tutto, l'autore utilizza metriche di richieste HTTP, che vengono raccolte tramite Prometheus.
Invece della scalabilità orizzontale dei pod, si utilizza Kubernetes Event Driven Autoscaling (KEDA) - un operatore Kubernetes open source. Si integra inizialmente con l'Horizontal Pod Autoscaler per fornire una scalabilità fluida (inclusa fino/a partire da zero) per i carichi di lavoro basati su eventi. Il codice è disponibile su .
Panoramica breve del funzionamento del sistema

Nello schema - una breve descrizione di come funziona tutto:
- L'applicazione fornisce metriche sul numero di accessi HTTP nel formato Prometheus.
- Prometheus è configurato per raccogliere queste metriche.
- Lo scaler Prometheus in KEDA è configurato per scalare automaticamente l'applicazione in base al numero di accessi HTTP.
Ora parlerò in dettaglio di ogni elemento.
KEDA e Prometheus
Prometheus è un insieme di strumenti open source per il monitoraggio e la segnalazione dei sistemi, parte . Raccoglie metriche da diverse fonti e le memorizza come dati temporali. Per la visualizzazione dei dati, è possibile utilizzare o altri strumenti di visualizzazione che lavorano con l'API di Kubernetes.
KEDA supporta il concetto di scaler - agisce come un ponte tra KEDA e un sistema esterno. L'implementazione dello scaler è specifica per ciascun sistema di destinazione ed estrae i dati da esso. Successivamente, KEDA utilizza questi dati per gestire la scalabilità automatica.
Gli scaler supportano più fonti di dati, come Kafka, Redis e Prometheus. Ciò significa che KEDA può essere utilizzato per il ridimensionamento automatico dei deployment di Kubernetes, utilizzando come criteri le metriche di Prometheus.
Applicazione di test
L'applicazione di test in Golang offre accesso tramite HTTP e svolge due funzioni principali:
- Utilizza la libreria client Prometheus Go per strumentare l'applicazione e fornire la metrica http_requests, che contiene un contatore delle richieste. L'endpoint da cui sono accessibili le metriche di Prometheus si trova all'URI
/metrics.var httpRequestsCounter = promauto.NewCounter(prometheus.CounterOpts{ Name: "http_requests", Help: "numero di richieste http", }) - In risposta alla richiesta
e username/password: admin/admin.l'applicazione incrementa il valore della chiave (access_count) in Redis. Questo è un modo semplice per eseguire il lavoro come parte del gestore HTTP e testare anche le metriche di Prometheus. Il valore della metrica deve essere lo stesso del valoreaccess_countin Redis.func main() { http.Handle("/metrics", promhttp.Handler()) http.HandleFunc("/test", func(w http.ResponseWriter, r *http.Request) { defer httpRequestsCounter.Inc() count, err := client.Incr(redisCounterName).Result() if err != nil { fmt.Println("Impossibile incrementare il contatore di redis", err) os.Exit(1) } resp := "Accesso il " + time.Now().String() + " Conteggio accessi " + strconv.Itoa(int(count)) w.Write([]byte(resp)) }) http.ListenAndServe(":8080", nil) }
L'applicazione viene distribuita in Kubernetes tramite Deployment. Viene anche creata un servizio ClusterIP, che consente al server Prometheus di ricevere le metriche dell'applicazione.
Ecco .
Server Prometheus
Il manifesto di deployment di Prometheus è composto da:
ConfigMap— per trasmettere la configurazione di Prometheus;Deployment— per il deployment di Prometheus nel cluster Kubernetes;ClusterIP— servizio per accedere all'UI di Prometheus;ClusterRole,ClusterRoleBindingeServiceAccount— per gestire l'auto-scoperta dei servizi in Kubernetes (Auto-discovery).
Ecco .
KEDA Prometheus ScaledObject
Lo scaler agisce come un ponte tra KEDA e un sistema esterno da cui è necessario ottenere metriche. ScaledObject — una risorsa configurabile, deve essere distribuita per sincronizzare il deployment con la fonte di eventi, in questo caso con Prometheus.
ScaledObject contiene informazioni sul ridimensionamento del deployment, metadati sulla fonte dell'evento (ad esempio, segreti per la connessione, nome della coda), intervallo di polling, periodo di recupero e altri dati. Conduce alla risorsa di autoscaling corrispondente (definizione HPA) per il ridimensionamento del deployment.
Quando l'oggetto ScaledObject viene rimosso, la definizione HPA corrispondente viene svuotata.
Ecco la definizione ScaledObject per il nostro esempio, si utilizza uno scaler Prometheus:
apiVersion: keda.k8s.io/v1alpha1
kind: ScaledObject
metadata:
name: prometheus-scaledobject
namespace: default
labels:
deploymentName: go-prom-app
spec:
scaleTargetRef:
deploymentName: go-prom-app
pollingInterval: 15
cooldownPeriod: 30
minReplicaCount: 1
maxReplicaCount: 10
triggers:
- type: prometheus
metadata:
serverAddress:
http://prometheus-service.default.svc.cluster.local:9090
metricName: access_frequency
threshold: '3'
query: sum(rate(http_requests[2m]))
Considera i seguenti punti:
- Indica
Deploymentcon il nomego-prom-app. - Il tipo di trigger è
Prometheus. L'indirizzo del server Prometheus è menzionato insieme al nome della metrica, al valore soglia e , che verrà utilizzata. La query PromQL èsum(rate(http_requests[2m])). - Secondo
pollingInterval, KEDA interroga l'obiettivo da Prometheus ogni quindici secondi. È supportato un minimo di un pod (minReplicaCount), mentre il numero massimo di pod non superamaxReplicaCount(in questo esempio - dieci).
Può essere impostato minReplicaCount a zero. In questo caso, KEDA attiva il deployment da zero a uno, per poi fornire HPA per ulteriore scalabilità automatica. È possibile anche l'inverso, ovvero scalare da uno a zero. Nell'esempio non abbiamo scelto zero, poiché si tratta di un servizio HTTP e non di un sistema a richiesta.
La magia dentro l'automazione dello scaling
Il valore soglia viene utilizzato come trigger per scalare il deployment. Nel nostro esempio, la query PromQL sum(rate(http_requests[2m])) restituisce il valore aggregato del tasso di richieste HTTP (numero di richieste al secondo), misurato negli ultimi due minuti.
Poiché il valore soglia è tre, ci sarà un pod finché il valore sum(rate(http_requests[2m])) è inferiore a tre. Se invece il valore aumenta, viene aggiunto un ulteriore pod ogni volta che sum(rate(http_requests[2m])) aumenta di tre. Ad esempio, se il valore passa da 12 a 14, il numero di pod sarà quattro.
Ora proviamo a configurare!
Configurazione preliminare
Tutto ciò di cui hai bisogno è un cluster Kubernetes e un'utilità configurata kubectl. In questo esempio utilizziamo un cluster minikube, ma puoi prendere qualsiasi altro. Per installare il cluster, ci sono .
Installa l'ultima versione su Mac:
curl -Lo minikube
https://storage.googleapis.com/minikube/releases/latest/minikube-linux-amd64
&& chmod +x minikube
sudo mkdir -p /usr/local/bin/
sudo install minikube /usr/local/bin/
Installare , per accedere al cluster Kubernetes.
Installare l'ultima versione su Mac:
curl -LO
"https://storage.googleapis.com/kubernetes-release/release/$(curl -s
https://storage.googleapis.com/kubernetes-release/release/stable.txt)/bin/darwin/amd64/kubectl"
chmod +x ./kubectl
sudo mv ./kubectl /usr/local/bin/kubectl
kubectl version
Installazione di KEDA
Puoi distribuire KEDA in diversi modi, elencati in . Utilizzo di un YAML monolitico:
kubectl apply -f
https://raw.githubusercontent.com/kedacore/keda/master/deploy/KedaScaleController.yaml
KEDA e i suoi componenti vengono installati nello spazio dei nomi keda. Comando per controllare:
kubectl get pods -n keda
Aspetta che il pod KEDA Operator parta — passi a Running State. E dopo continua.
Installazione di Redis tramite Helm
Se non hai installato Helm, utilizza questo . Comando per l'installazione su Mac:
brew install kubernetes-helm
helm init --history-max 200
helm init inizializza l'interfaccia della riga di comando locale e installa Tiller nel cluster Kubernetes.
kubectl get pods -n kube-system | grep tiller
Aspetta che il pod Tiller passi allo stato Running.
Nota del traduttore: L'autore utilizza Helm@2, che richiede l'installazione del componente server Tiller. Ora è attuale Helm@3, per il quale non è necessaria la parte server.
Dopo aver installato Helm, per avviare Redis basta un comando:
helm install --name redis-server --set cluster.enabled=false --set
usePassword=false stable/redis
Assicurati che Redis si sia avviato con successo:
kubectl get pods/redis-server-master-0
Aspetta che il pod Redis passi allo stato Esecuzione.
Distribuzione dell'applicazione
Comando per la distribuzione:
kubectl apply -f go-app.yaml
//output
deployment.apps/go-prom-app created
service/go-prom-app-service created
Controlla che tutto sia partito:
kubectl get pods -l=app=go-prom-app
Aspetta che Redis passi allo stato Esecuzione.
Distribuzione del server Prometheus
Il manifesto di Prometheus utilizza . Permette di scoprire dinamicamente i pod dell'applicazione in base all'etichetta del servizio.
kubernetes_sd_configs:
- role: service
relabel_configs:
- source_labels: [__meta_kubernetes_service_label_run]
regex: go-prom-app-service
action: keep
Per la distribuzione:
kubectl apply -f prometheus.yaml
//output
clusterrole.rbac.authorization.k8s.io/prometheus created
serviceaccount/default configured
clusterrolebinding.rbac.authorization.k8s.io/prometheus created
configmap/prom-conf created
deployment.extensions/prometheus-deployment created
service/prometheus-service created
Controlla che tutto sia partito:
kubectl get pods -l=app=prometheus-server
Aspetta che il pod Prometheus passi allo stato Esecuzione.
Usa kubectl port-forward per accedere all'interfaccia utente di Prometheus (o al server API) all'indirizzo .
kubectl port-forward service/prometheus-service 9090
Distribuzione della configurazione per il ridimensionamento automatico KEDA
Comando per creare ScaledObject:
kubectl apply -f keda-prometheus-scaledobject.yaml
Controlla i log dell'operatore KEDA:
KEDA_POD_NAME=$(kubectl get pods -n keda
-o=jsonpath='{.items[0].metadata.name}')
kubectl logs $KEDA_POD_NAME -n keda
Il risultato appare circa così:
time="2019-10-15T09:38:28Z" level=info msg="Watching ScaledObject:
default/prometheus-scaledobject"
time="2019-10-15T09:38:28Z" level=info msg="Created HPA with
namespace default and name keda-hpa-go-prom-app"
Controlla gli pod dell'applicazione. Deve essere in esecuzione una singola istanza poiché minReplicaCount è uguale a 1:
kubectl get pods -l=app=go-prom-app
Verifica che la risorsa HPA sia stata creata con successo:
kubectl get hpa
Dovresti vedere qualcosa del tipo:
NOME RIFERIMENTI TARGETS MINPODS MAXPODS REPLICAS ETÀ
keda-hpa-go-prom-app Deployment/go-prom-app 0/3 (avg) 1 10 1 45s
Verifica della funzionalità: accesso all'applicazione
Per accedere all'endpoint REST della nostra applicazione, esegui:
kubectl port-forward service/go-prom-app-service 8080
Ora puoi accedere all'applicazione Go utilizzando l'indirizzo . Per fare ciò, esegui il comando:
curl http://localhost:8080/test
Il risultato appare circa così:
Accesso effettuato il 2019-10-21 11:29:10.560385986 +0000 UTC
m=+406004.817901246
Contatore accessi 1
In questa fase controlla anche Redis. Vedrai che la chiave access_count è aumentata a 1:
kubectl exec -it redis-server-master-0 -- redis-cli get access_count
//output
"1"
Assicurati che il valore della metrica http_requests sia lo stesso:
curl http://localhost:8080/metrics | grep http_requests
//output
# HELP http_requests numero di http requests
# TYPE http_requests counter
http_requests 1
Creazione del carico
Useremo — un'utilità per generare il carico:
curl -o hey https://storage.googleapis.com/hey-release/hey_darwin_amd64
&& chmod a+x hey
Puoi anche scaricare l'utilità per o .
Eseguila:
./hey http://localhost:8080/test
Per impostazione predefinita, l'utilità invia 200 richieste. Puoi verificarlo usando le metriche di Prometheus e anche Redis.
curl http://localhost:8080/metrics | grep http_requests
//output
# HELP http_requests numero di http requests
# TYPE http_requests counter
http_requests 201
kubectl exec -it redis-server-master-0 -- redis-cli get access_count
//output
201
Conferma il valore della metrica effettiva (ritornata dalla query PromQL):
curl -g
'http://localhost:9090/api/v1/query?query=sum(rate(http_requests[2m]))'
//output
{"status":"success","data":{"resultType":"vector","result":[{"metric":{},"value":[1571734214.228,"1.686057971014493"]}]}}
In questo caso il risultato effettivo è 1,686057971014493 e viene visualizzato nel campo value. Non è sufficiente per il scaling, poiché la soglia impostata è 3.
Più carico!
In un nuovo terminale, monitora il numero di pod dell'applicazione:
kubectl get pods -l=app=go-prom-app -w
Aumentiamo il carico usando il comando:
./hey -n 2000 http://localhost:8080/test
Dopo un po' vedrai che l'HPA scala il deployment e avvia nuovi pod. Controlla HPA per confermarlo:
kubectl get hpa
NOME RIFERIMENTI TARGETS MINPODS MAXPODS REPLICAS ETÀ
keda-hpa-go-prom-app Deployment/go-prom-app 1830m/3 (avg) 1 10 6 4m22s
Se il carico non è costante, il deployment si ridurrà al punto in cui funziona solo un pod. Se desideri controllare la metrica effettiva (restituita dalla query PromQL), utilizza il comando:
curl -g
'http://localhost:9090/api/v1/query?query=sum(rate(http_requests[2m]))'
Pulizia
//Delete KEDA
kubectl delete namespace keda
//Delete the app, Prometheus server and KEDA scaled object
kubectl delete -f .
//Delete Redis
helm del --purge redis-server
Conclusione
KEDA consente di scalare automaticamente i tuoi deployment Kubernetes (fino/a zero) basandosi su dati provenienti da metriche esterne. Ad esempio, basandosi su metriche di Prometheus, sulla lunghezza della coda in Redis, o sulla latenza del consumatore nel topic Kafka.
KEDA esegue l'integrazione con una fonte esterna e fornisce le sue metriche tramite il Metrics Server per l'Horizontal Pod Autoscaler.
Buona fortuna!
Cosa leggere ancora:
- .
- .
- .
Fonte: habr.com
