Autoscaling applicazioni Kubernetes cù Prometheus è KEDA

Autoscaling applicazioni Kubernetes cù Prometheus è KEDABallon Man di Cimuanos

A scalabilità hè un requisitu chjave per l'applicazioni cloud. Cù Kubernetes, scaling una applicazione hè simplice quant'è aumentà u numeru di repliche per a implementazione adatta o ReplicaSet - ma hè un prucessu manuale.

Kubernetes permette à l'applicazioni di esse scalate automaticamente (vale à dì Pods in una implementazione o ReplicaSet) in modu dichjarazione utilizendu a specificazione Horizontal Pod Autoscaler. U criteriu predeterminatu per a scala automatica hè a metrica di l'usu di CPU (metriche di risorse), ma pudete integrà metriche persunalizati è furnite esternamente.

squadra Kubernetes aaS da Mail.ru traduttu un articulu nantu à cumu utilizà metriche esterne per scala automaticamente una applicazione Kubernetes. Per dimustrà cumu tuttu u travagliu, l'autore usa e metriche di dumanda d'accessu HTTP, chì sò cullate cù Prometheus.

Invece di l'autoscaling horizontale di pods, Kubernetes Event Driven Autoscaling (KEDA) hè utilizatu, un operatore Kubernetes open source. Si integra in modu nativu cù Horizontal Pod Autoscaler per furnisce l'autoscaling senza saldatura (cumpresu à / da zero) per carichi di travagliu guidati da eventi. Codice dispunibule à GitHub.

Breve panoramica di u sistema

Autoscaling applicazioni Kubernetes cù Prometheus è KEDA

U diagramma mostra una breve descrizzione di cumu funziona tuttu:

  1. L'applicazione furnisce metriche di u numeru di hit HTTP in u formatu Prometheus.
  2. Prometheus hè cunfiguratu per cullà queste metriche.
  3. U scaler Prometheus in KEDA hè cunfiguratu per scala automaticamente l'applicazione basatu annantu à u numeru di hits HTTP.

Avà vi dicu in detail nantu à ogni elementu.

KEDA è Prometheus

Prometheus hè un sistema di surviglianza open source è toolkit d'alerta, parte Fondazione Cloud Native Computing. Raccoglie metriche da diverse fonti è li guarda cum'è dati di serie temporale. Per visualizà e dati chì pudete aduprà Grafana o altri strumenti di visualizazione chì travaglianu cù l'API Kubernetes.

KEDA sustene u cuncettu di scaler - agisce cum'è un ponte trà KEDA è u sistema esternu. L'implementazione di scaler hè specifica per ogni sistema di destinazione è estrae dati da ellu. KEDA poi li usa per cuntrullà a scala automatica.

Scalers supportanu parechje fonti di dati, per esempiu, Kafka, Redis, Prometheus. Vale à dì, KEDA pò esse usatu per scala automaticamente implementazioni Kubernetes utilizendu metriche Prometheus cum'è criteri.

Applicazione di prova

L'applicazione di teste Golang furnisce accessu via HTTP è eseguisce duie funzioni impurtanti:

  1. Aduprà a biblioteca di u cliente Prometheus Go per instrumentà l'applicazione è furnisce a metrica http_requests, chì cuntene un conte di hit. L'endpoint induve e metriche Prometheus sò dispunibili si trova à l'URI /metrics.
    var httpRequestsCounter = promauto.NewCounter(prometheus.CounterOpts{
           Name: "http_requests",
           Help: "number of http requests",
       })
    
  2. In risposta à una dumanda GET l'applicazione aumenta u valore di a chjave (access_count) in Redis. Questu hè un modu faciule per fà u travagliu cum'è parte di un handler HTTP è ancu verificà e metriche di Prometheus. U valore metricu deve esse uguali à u valore access_count in 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("Unable to increment redis counter", err)
                   os.Exit(1)
               }
               resp := "Accessed on " + time.Now().String() + "nAccess count " + strconv.Itoa(int(count))
               w.Write([]byte(resp))
           })
           http.ListenAndServe(":8080", nil)
       }
    

L'applicazione hè implementata à Kubernetes via Deployment. Un serviziu hè ancu creatu ClusterIP, permette à u servitore Prometheus per ottene metriche di l'applicazione.

quì manifestu di implementazione per l'applicazione.

Prometheus Server

U manifestu di implementazione di Prometheus hè custituitu da:

  • ConfigMap - per trasfiriri a cunfigurazione Prometheus;
  • Deployment - per implementà Prometheus in un cluster Kubernetes;
  • ClusterIP - serviziu per accessu à UI Prometheus;
  • ClusterRole, ClusterRoleBinding и ServiceAccount - per a rilevazione automatica di servizii in Kubernetes (Auto-discovery).

quì manifestu per correre Prometheus.

KEDA Prometheus ScaledObject

U scaler agisce cum'è un ponte trà KEDA è u sistema esternu da quale metrica deve esse ottenuta. ScaledObject hè una risorsa persunalizata chì deve esse implementata per sincronizà a implementazione cù a fonte di l'avvenimentu, in questu casu Prometheus.

ScaledObject cuntene infurmazione di scala di implementazione, metadati di fonte di l'avvenimentu (cum'è secreti di cunnessione, nome di fila), intervallu di votazione, periodu di ricuperazione è altre dati. Risulta in a risorsa autoscaling currispundente (definizione HPA) per scala a implementazione.

Quandu un oggettu ScaledObject hè eliminata, a definizione HPA currispundente hè sguassata.

Eccu a definizione ScaledObject per u nostru esempiu, usa un 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]))

Cunsiderate i seguenti punti:

  1. Ellu indica Deployment Cù nome go-prom-app.
  2. tipu di trigger - Prometheus. L'indirizzu di u servitore Prometheus hè mintuatu cù u nome metricu, u sogliu è Query PromQL, chì serà utilizatu. Query PromQL - sum(rate(http_requests[2m])).
  3. Sicondu pollingInterval,KEDA dumanda una mira da Prometheus ogni quindici seconde. Almenu unu sottu (minReplicaCount), è u numeru massimu di pods ùn supera micca maxReplicaCount (in questu esempiu - deci).

Pò stallà minReplicaCount uguali à zero. In questu casu, KEDA attiva l'implementazione zero-to-one è poi espone l'HPA per più scala automatica. L'ordine inversu hè ancu pussibule, vale à dì, scala da unu à zero. In l'esempiu, ùn avemu micca sceltu zero perchè questu hè un serviziu HTTP è micca un sistema à dumanda.

A magia in l'autoscaling

U sogliu hè utilizatu cum'è un trigger per scala l'implementazione. In u nostru esempiu, a query PromQL sum(rate (http_requests [2m])) Ritorna a tarifa di dumanda HTTP aggregata (richiesta per seconda), misurata annantu à l'ultimi dui minuti.

Siccomu u valore di u limitu hè trè, significa chì ci sarà unu sottu mentre u valore sum(rate (http_requests [2m])) menu di trè. Se u valore aumenta, un sottu supplementu hè aghjuntu ogni volta sum(rate (http_requests [2m])) aumenta di trè. Per esempiu, se u valore hè da 12 à 14, u numeru di pods hè quattru.

Avà pruvemu à stallà!

Préréglage

Tuttu ciò chì avete bisognu hè un cluster Kubernetes è una utilità cunfigurata kubectl. Questu esempiu usa un cluster minikube, ma pudete piglià qualsiasi altru. Per installà un cluster ci hè dirigenza.

Installa l'ultima versione in 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/

Installa kubectlper accede à u cluster Kubernetes.

Installa l'ultima versione in 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

Pudete implementà KEDA in parechje manere, sò listati in ducumentazione. Aghju utilizatu YAML monoliticu:

kubectl apply -f
https://raw.githubusercontent.com/kedacore/keda/master/deploy/KedaScaleController.yaml

KEDA è i so cumpunenti sò stallati in u namespace keda. Cumanda per verificà:

kubectl get pods -n keda

Aspettate chì l'operatore KEDA principia è andate à Running State. E dopu, cuntinuà.

Installazione di Redis cù Helm

Se ùn avete micca Helm installatu, utilizate questu dirigenza. Cumanda per installà in Mac:

brew install kubernetes-helm
helm init --history-max 200

helm init inizializza l'interfaccia di a linea di cummanda lucale è ancu installà Tiller à u cluster Kubernetes.

kubectl get pods -n kube-system | grep tiller

Aspettate chì u tiller pod entre in u statu di corsa.

Nota di u traduttore: L'autore usa Helm@2, chì deve esse installatu u cumpunente di u servitore Tiller. Avà Helm@3 hè pertinente, ùn hè micca bisognu di una parte di u servitore.

Dopu avè installatu Helm, un cumandamentu hè abbastanza per inizià Redis:

helm install --name redis-server --set cluster.enabled=false --set 
usePassword=false stable/redis

Verificate chì Redis hà iniziatu cù successu:

kubectl get pods/redis-server-master-0

Aspettate chì Redis entre in u statu Running.

Implementazione di l'applicazioni

Cumandamentu di implementazione:

kubectl apply -f go-app.yaml

//output
deployment.apps/go-prom-app created
service/go-prom-app-service created

Verificate chì tuttu hè cuminciatu:

kubectl get pods -l=app=go-prom-app

Aspettate chì Redis entre in u statu Running.

Implementazione di un Servitore Prometheus

U manifestu Prometheus usa Kubernetes Service Discovery per Prometheus. Permette a scuperta dinamica di pods d'applicazione basatu annantu à l'etichetta di serviziu.

kubernetes_sd_configs:
   - role: service
   relabel_configs:
   - source_labels: [__meta_kubernetes_service_label_run]
     regex: go-prom-app-service
     action: keep

Per implementà:

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

Verificate chì tuttu hè cuminciatu:

kubectl get pods -l=app=prometheus-server

Aspetta chì Prometheus entre in u statu Running.

Usu kubectl port-forward per accede à l'interfaccia d'utilizatore Prometheus (o servitore API) à http://localhost:9090.

kubectl port-forward service/prometheus-service 9090

Implementazione di KEDA Autoscaling Configuration

Cumanda per creà ScaledObject:

kubectl apply -f keda-prometheus-scaledobject.yaml

Verificate i logs di l'operatore KEDA:

KEDA_POD_NAME=$(kubectl get pods -n keda 
-o=jsonpath='{.items[0].metadata.name}')
kubectl logs $KEDA_POD_NAME -n keda

U risultatu pare qualcosa cum'è questu:

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"

Verificate sottu à l'applicazioni. Una istanza deve esse in esecuzione perchè minReplicaCount pari à 1:

kubectl get pods -l=app=go-prom-app

Verificate chì a risorsa HPA hè stata creata bè:

kubectl get hpa

Duvete vede qualcosa cum'è:

NAME                   REFERENCE                TARGETS     MINPODS   MAXPODS   REPLICAS   AGE
keda-hpa-go-prom-app   Deployment/go-prom-app   0/3 (avg)   1         10        1          45s

Verificazione di salute: accessu à l'applicazione

Per accede à l'endpoint REST di a nostra applicazione, eseguite:

kubectl port-forward service/go-prom-app-service 8080

Pudete avà accede à a vostra app Go utilizendu l'indirizzu http://localhost:8080. Per fà questu, eseguite u cumandimu:

curl http://localhost:8080/test

U risultatu pare qualcosa cum'è questu:

Accessed on 2019-10-21 11:29:10.560385986 +0000 UTC 
m=+406004.817901246
Access count 1

À questu puntu ancu verificate Redis. Vi vede chì a chjave access_count aumentatu à 1:

kubectl exec -it redis-server-master-0 -- redis-cli get access_count
//output
"1"

Assicuratevi chì u valore metricu hè http_requests u listessu:

curl http://localhost:8080/metrics | grep http_requests
//output
# HELP http_requests number of http requests
# TYPE http_requests counter
http_requests 1

Creazione di carica

Avemu da aduprà ehi - utilità per a generazione di carica:

curl -o hey https://storage.googleapis.com/hey-release/hey_darwin_amd64 
&& chmod a+x hey

Pudete ancu scaricà l'utilità per Linux o Windows.

Eseguite:

./hey http://localhost:8080/test

Per automaticamente, l'utilità manda 200 dumande. Pudete verificà questu utilizendu e metriche Prometheus è Redis.

curl http://localhost:8080/metrics | grep http_requests
//output
# HELP http_requests number of http requests
# TYPE http_requests counter
http_requests 201
kubectl exec -it redis-server-master-0 -- redis-cli get access_count
//output
201

Validate u valore di a metrica attuale (turnita da a 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 questu casu, u risultatu propiu hè 1,686057971014493 è hè visualizatu in u campu value. Questu ùn hè micca abbastanza per a scala, postu chì u limitu chì avemu stabilitu hè 3.

Più carica!

In u novu terminal, monitorate u numeru di pods d'applicazione:

kubectl get pods -l=app=go-prom-app -w

Aumentemu a carica cù u cumandimu:

./hey -n 2000 http://localhost:8080/test

Dopu qualchì tempu, vi vede HPA scaling the deployment and launching new pods. Verificate u vostru HPA per assicurà:

kubectl get hpa
NAME                   REFERENCE                TARGETS         MINPODS   MAXPODS   REPLICAS   AGE
keda-hpa-go-prom-app   Deployment/go-prom-app   1830m/3 (avg)   1         10        6          4m22s

Se a carica hè inconsistente, a implementazione serà ridutta à u puntu induve solu un pod hè in esecuzione. Se vulete verificà a metrica attuale (ritornata da a query PromQL), allora utilizate u cumandimu:

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

cunchiusioni

KEDA vi permette di scala automaticamente e vostre implementazioni Kubernetes (à / da zero) basatu nantu à dati da metriche esterne. Per esempiu, basatu annantu à e metriche di Prometheus, a lunghezza di a fila in Redis, a latenza di u cunsumadore in u tema Kafka.

KEDA si integra cù una fonte esterna è furnisce ancu e so metriche per mezu di Metrics Server à Horizontal Pod Autoscaler.

Bona furtuna!

Cosa altru à leghje:

  1. Best Practices è Best Practices per Running Containers and Kubernetes in Production Environments.
  2. 90+ Strumenti utili per Kubernetes: implementazione, gestione, monitoraghju, sicurezza è più.
  3. U nostru canale Intornu à Kubernetes in Telegram.

Source: www.habr.com

Add a comment