Scalare automată a aplicațiilor Kubernetes folosind Prometheus și KEDA

Scalare automată a aplicațiilor Kubernetes folosind Prometheus și KEDAOmul cu balon de Cimuanos

Scalabilitatea este o cerință cheie pentru aplicațiile cloud. Cu Kubernetes, scalarea unei aplicații este la fel de simplă ca și creșterea numărului de replici pentru implementarea corespunzătoare sau ReplicaSet — dar este un proces manual.

Kubernetes permite scalarea automată a aplicațiilor (de exemplu, poduri într-o implementare sau ReplicaSet) într-o manieră declarativă utilizând specificația Horizontal Pod Autoscaler. Criteriul implicit pentru scalarea automată este valorile de utilizare a procesorului (valori de resurse), dar puteți integra valori personalizate și furnizate extern.

Echipă Kubernetes aaS de la Mail.ru a tradus un articol despre cum să utilizați valorile externe pentru a scala automat o aplicație Kubernetes. Pentru a arăta cum funcționează totul, autorul folosește valorile de solicitare de acces HTTP, care sunt colectate folosind Prometheus.

În loc de scalarea automată orizontală a podurilor, se utilizează Kubernetes Event Driven Autoscaling (KEDA), un operator Kubernetes cu sursă deschisă. Se integrează nativ cu Horizontal Pod Autoscaler pentru a oferi o scalare automată fără întreruperi (inclusiv la/de la zero) pentru sarcinile de lucru bazate pe evenimente. Cod disponibil la GitHub.

Scurtă prezentare generală a sistemului

Scalare automată a aplicațiilor Kubernetes folosind Prometheus și KEDA

Diagrama prezintă o scurtă descriere a modului în care funcționează totul:

  1. Aplicația oferă valori HTTP pentru numărul de accesări în format Prometheus.
  2. Prometheus este configurat să colecteze aceste valori.
  3. Scalerul Prometheus din KEDA este configurat pentru a scala automat aplicația în funcție de numărul de accesări HTTP.

Acum vă voi spune în detaliu despre fiecare element.

KEDA și Prometeu

Prometheus este un set de instrumente de monitorizare și alertă a sistemului open source, parte Fundația Cloud Native Computing. Colectează valori din diverse surse și le stochează ca date de serie cronologică. Pentru a vizualiza datele pe care le puteți folosi grafana sau alte instrumente de vizualizare care funcționează cu API-ul Kubernetes.

KEDA susține conceptul de scaler - acţionează ca o punte între KEDA și sistemul extern. Implementarea scalerului este specifică fiecărui sistem țintă și extrage date din acesta. KEDA le folosește apoi pentru a controla scalarea automată.

Scalerele acceptă mai multe surse de date, de exemplu, Kafka, Redis, Prometheus. Adică, KEDA poate fi folosit pentru a scala automat implementările Kubernetes folosind metricile Prometheus ca criterii.

Aplicația de testare

Aplicația de testare Golang oferă acces prin HTTP și îndeplinește două funcții importante:

  1. Utilizează biblioteca client Prometheus Go pentru a instrumenta aplicația și pentru a furniza valoarea http_requests, care conține un număr de accesări. Punctul final în care sunt disponibile valorile Prometheus se află la URI /metrics.
    var httpRequestsCounter = promauto.NewCounter(prometheus.CounterOpts{
           Name: "http_requests",
           Help: "number of http requests",
       })
    
  2. Ca răspuns la o cerere GET aplicația crește valoarea cheii (access_count) în Redis. Aceasta este o modalitate ușoară de a face munca ca parte a unui handler HTTP și de a verifica, de asemenea, valorile Prometheus. Valoarea valorii trebuie să fie aceeași cu valoarea access_count în 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)
       }
    

Aplicația este implementată în Kubernetes prin Deployment. Se creează și un serviciu ClusterIP, permite serverului Prometheus să obțină valori ale aplicației.

Aici manifest de implementare pentru aplicație.

Serverul Prometheus

Manifestul de implementare Prometheus constă din:

  • ConfigMap — pentru a transfera configurația Prometheus;
  • Deployment — pentru implementarea Prometheus într-un cluster Kubernetes;
  • ClusterIP — serviciu de acces la UI Prometheus;
  • ClusterRole, ClusterRoleBinding и ServiceAccount — pentru detectarea automată a serviciilor în Kubernetes (descoperire automată).

Aici manifest pentru rularea lui Prometeu.

KEDA Prometheus ScaledObject

Scalerul acționează ca o punte între KEDA și sistemul extern de la care trebuie obținute valorile. ScaledObject este o resursă personalizată care trebuie implementată pentru a sincroniza implementarea cu sursa evenimentului, în acest caz Prometheus.

ScaledObject conține informații de scalare a implementării, metadatele sursei evenimentului (cum ar fi secretele conexiunii, numele cozii), intervalul de interogare, perioada de recuperare și alte date. Rezultă resursa de autoscaling corespunzătoare (definiție HPA) pentru scalarea implementării.

Când un obiect ScaledObject este ștearsă, definiția HPA corespunzătoare este ștearsă.

Iată definiția ScaledObject pentru exemplul nostru, folosește 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]))

Luați în considerare următoarele puncte:

  1. El arată spre Deployment Cu nume go-prom-app.
  2. Tip de declanșare - Prometheus. Adresa serverului Prometheus este menționată împreună cu numele metricii, pragul și Interogare PromQL, care va fi folosit. Interogare PromQL - sum(rate(http_requests[2m])).
  3. În conformitate cu pollingInterval,KEDA solicită o țintă de la Prometheus la fiecare cincisprezece secunde. Cel puțin unul sub (minReplicaCount), iar numărul maxim de păstăi nu depășește maxReplicaCount (în acest exemplu - zece).

Se poate instala minReplicaCount egal cu zero. În acest caz, KEDA activează implementarea zero-la-unu și apoi expune HPA pentru scalare automată ulterioară. Este posibilă și ordinea inversă, adică scalarea de la unu la zero. În exemplu, nu am selectat zero, deoarece acesta este un serviciu HTTP și nu un sistem la cerere.

Magia din interiorul autoscalingului

Pragul este folosit ca declanșator pentru a scala implementarea. În exemplul nostru, interogarea PromQL sum(rate (http_requests [2m])) returnează rata de solicitare HTTP agregată (cereri pe secundă), măsurată în ultimele două minute.

Având în vedere că valoarea pragului este de trei, înseamnă că va fi o valoare sub while sum(rate (http_requests [2m])) mai putin de trei. Dacă valoarea crește, se adaugă de fiecare dată un subcontract suplimentar sum(rate (http_requests [2m])) crește cu trei. De exemplu, dacă valoarea este de la 12 la 14, atunci numărul de păstăi este de patru.

Acum hai să încercăm să-l setăm!

presetare

Tot ce aveți nevoie este un cluster Kubernetes și un utilitar configurat kubectl. Acest exemplu folosește un cluster minikube, dar poți lua oricare altul. Pentru a instala un cluster există conducere.

Instalați cea mai recentă versiune pe 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/

Set kubectlpentru a accesa clusterul Kubernetes.

Instalați cea mai recentă versiune pe 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

Instalare KEDA

Puteți implementa KEDA în mai multe moduri, acestea sunt enumerate în documentație. Folosesc YAML monolitic:

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

KEDA și componentele sale sunt instalate în spațiul de nume keda. Comanda de verificare:

kubectl get pods -n keda

Așteptați ca KEDA Operator să pornească și accesați Running State. Și după aceea, continuă.

Instalarea Redis folosind Helm

Dacă nu ai instalat Helm, folosește-l conducere. Comanda de instalare pe Mac:

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

helm init inițializează interfața locală a liniei de comandă și, de asemenea, instalează Tiller către clusterul Kubernetes.

kubectl get pods -n kube-system | grep tiller

Așteptați ca tiller pod să intre în starea de funcționare.

Nota traducătorului: Autorul folosește Helm@2, care necesită instalarea componentei server Tiller. Acum Helm@3 este relevant, nu necesită o parte server.

După instalarea Helm, este suficientă o comandă pentru a porni Redis:

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

Verificați dacă Redis a pornit cu succes:

kubectl get pods/redis-server-master-0

Așteptați ca Redis să intre în stare Running.

Implementarea aplicației

Comanda de implementare:

kubectl apply -f go-app.yaml

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

Verificați dacă totul a început:

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

Așteptați ca Redis să intre în stare Running.

Implementarea unui server Prometheus

Manifestul Prometeu folosește Kubernetes Service Discovery pentru Prometheus. Permite descoperirea dinamică a podurilor de aplicații pe baza etichetei de serviciu.

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

A desfasura:

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

Verificați dacă totul a început:

kubectl get pods -l=app=prometheus-server

Așteptați ca Prometeu să intre în stare Running.

utilizare kubectl port-forward pentru a accesa interfața de utilizator Prometheus (sau serverul API) la http://localhost:9090.

kubectl port-forward service/prometheus-service 9090

Implementarea configurației KEDA Autoscaling

Comanda de a crea ScaledObject:

kubectl apply -f keda-prometheus-scaledobject.yaml

Verificați jurnalele operatorului KEDA:

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

Rezultatul arată cam așa:

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"

Verificați sub aplicații. O instanță trebuie să ruleze deoarece minReplicaCount este egal cu 1:

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

Verificați dacă resursa HPA a fost creată cu succes:

kubectl get hpa

Ar trebui să vezi ceva de genul:

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

Verificare de sănătate: acces la aplicație

Pentru a accesa punctul final REST al aplicației noastre, rulați:

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

Acum puteți accesa aplicația Go folosind adresa http://localhost:8080. Pentru a face acest lucru, rulați comanda:

curl http://localhost:8080/test

Rezultatul arată cam așa:

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

În acest moment, verificați și Redis. Vei vedea că cheia access_count crescut la 1:

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

Asigurați-vă că valoarea valorii este http_requests aceeași:

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

Crearea încărcării

Noi vom folosi hei — utilitate pentru generarea sarcinii:

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

De asemenea, puteți descărca utilitarul pentru Linux sau ferestre din.

Rulați-l:

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

Implicit, utilitarul trimite 200 de cereri. Puteți verifica acest lucru folosind valorile Prometheus, precum și 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

Validați valoarea valorii reale (returnată de interogarea 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"]}]}}

În acest caz, rezultatul real este 1,686057971014493 și este afișat în câmp value. Acest lucru nu este suficient pentru scalare, deoarece pragul stabilit este 3.

Mai multă sarcină!

În noul terminal, monitorizați numărul de aplicații:

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

Să creștem sarcina folosind comanda:

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

După un timp, veți vedea HPA scalând implementarea și lansând noi poduri. Verificați HPA pentru a vă asigura că:

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

Dacă încărcarea este inconsecventă, implementarea va fi redusă până la punctul în care rulează un singur pod. Dacă doriți să verificați valoarea reală (returnată de interogarea PromQL), atunci utilizați comanda:

curl -g 
'http://localhost:9090/api/v1/query?query=sum(rate(http_requests[2m]))'

curățenie

//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

Concluzie

KEDA vă permite să scalați automat implementările Kubernetes (la/de la zero) pe baza datelor din valori externe. De exemplu, pe baza valorilor Prometheus, lungimea cozii în Redis, latența consumatorului în subiectul Kafka.

KEDA se integrează cu o sursă externă și oferă, de asemenea, valorile sale prin Metrics Server către Horizontal Pod Autoscaler.

Succes!

Ce altceva de citit:

  1. Cele mai bune practici și cele mai bune practici pentru rularea containerelor și Kubernetes în mediile de producție.
  2. Peste 90 de instrumente utile pentru Kubernetes: implementare, management, monitorizare, securitate și multe altele.
  3. Canalul nostru Around Kubernetes în Telegram.

Sursa: www.habr.com

Adauga un comentariu