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
Diagrama prezintă o scurtă descriere a modului în care funcționează totul:
Aplicația oferă valori HTTP pentru numărul de accesări în format Prometheus.
Prometheus este configurat să colecteze aceste valori.
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:
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",
})
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.
Aplicația este implementată în Kubernetes prin Deployment. Se creează și un serviciu ClusterIP, permite serverului Prometheus să obțină valori ale aplicației.
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:
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])).
Î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.
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:
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.
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:
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:
Î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:
//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.