
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 un deployment corespunzător sau ReplicaSet — dar este un proces manual.
Kubernetes permite scalarea automată a aplicațiilor (adică a Pod-urilor dintr-un deployment sau ReplicaSet) într-un mod declarativ utilizând specificația Horizontal Pod Autoscaler. În mod implicit, criteriile pentru scalarea automată sunt metricile de utilizare a CPU-ului (metricile resurselor), dar se pot integra metrici personalizate și metrici furnizate din externe.
Comanda a tradus un articol despre cum să utilizezi metricile externe pentru scalarea automată a aplicației Kubernetes. Pentru a ilustra cum funcționează totul, autorul folosește metricile de cereri pentru accesul HTTP, care sunt colectate cu ajutorul Prometheus.
În loc de scalarea automată orizontală a Pod-urilor, se aplică Kubernetes Event Driven Autoscaling (KEDA) — un operator Kubernetes cu sursă deschisă. Acesta se integrează inițial cu Horizontal Pod Autoscaler pentru a asigura scalarea automată fluidă (inclusiv până la/de la zero) pentru sarcinile de lucru bazate pe evenimente. Codul este disponibil pe .
O prezentare generală a funcționării sistemului

În diagramă — o descriere succintă a modului în care funcționează totul:
- Aplicația oferă metrici privind numărul de cereri HTTP în format Prometheus.
- Prometheus este configurat pentru a colecta aceste date.
- Scalatorul Prometheus în KEDA este configurat pentru a scala automat aplicația pe baza numărului de cereri HTTP.
Acum voi detalia fiecare element.
KEDA și Prometheus
Prometheus este un set de instrumente pentru monitorizare și alertare a sistemelor cu sursă deschisă, parte din . Colectează metrici din diferite surse și le stochează sub formă de date de tip time series. Pentru vizualizarea datelor, se pot folosi sau alte instrumente de vizualizare care funcționează cu API-ul Kubernetes.
KEDA sprijină conceptul de scalator — acesta acționează ca un pod între KEDA și un sistem extern. Implementarea scalatorului este specifică fiecărui sistem țintă și extrage date din acesta. Apoi, KEDA le utilizează pentru a gestiona scalarea automată.
Scalerii suportă mai multe surse de date, cum ar fi Kafka, Redis, Prometheus. Asta înseamnă că KEDA poate fi utilizat pentru scalarea automată a desfășurărilor Kubernetes, folosind ca criterii metricile Prometheus.
Aplicație de testare
Aplicația de testare Golang oferă acces prin HTTP și îndeplinește două funcții importante:
- Folosește biblioteca clientului Prometheus Go pentru a instrumenta aplicația și a oferi metrică http_requests, care conține un contor al accesărilor. Endpointul prin care sunt disponibile metricile Prometheus se află la URI
/metrics.var httpRequestsCounter = promauto.NewCounter(prometheus.CounterOpts{ Name: "http_requests", Help: "numărul cererilor http", }) - Ca răspuns la cerere
metoda GET.aplicația crește valoarea cheii (access_count) în Redis. Aceasta este o modalitate simplă de a realiza această acțiune ca parte a handlerului HTTP și de asemenea de a verifica metricile Prometheus. Valoarea metricii ar trebui să fie aceeași cu valoareaaccess_countdin 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("Imposibil de incrementat contorul redis", err) os.Exit(1) } resp := "Accesat pe " + time.Now().String() + "nNumărul de accesări " + strconv.Itoa(int(count)) w.Write([]byte(resp)) }) http.ListenAndServe(":8080", nil) }
Aplicația este desfășurată în Kubernetes prin Deployment. De asemenea, se creează un serviciu ClusterIP, care permite serverului Prometheus să primească metricile aplicației.
Iată .
Serverul Prometheus
Manifestul de desfășurare Prometheus constă din:
ConfigMap— pentru transmiterea configurației Prometheus;Deployment— pentru desfășurarea Prometheus în clusterul Kubernetes;ClusterIP— serviciu pentru accesarea interfeței UI Prometheus;ClusterRole,ClusterRoleBindingșiServiceAccount— pentru funcționarea auto-descoperirii serviciilor în Kubernetes (Auto-discovery).
Iată .
KEDA Prometheus ScaledObject
Scalerul acționează ca un pod între KEDA și un sistem extern, din care trebuie să se obțină metricile. ScaledObject — un resursă configurabilă, care trebuie desfășurată pentru a sincroniza desfășurarea cu sursa de evenimente, în acest caz cu Prometheus.
ScaledObject conține informații despre scalarea desfășurării, metadate despre sursa evenimentului (de exemplu, secrete pentru conectare, nume coadă), intervalul de polling, perioada de recuperare și alte date. Acesta conduce la resursa corespunzătoare de scalare automată (definiția HPA) pentru scalarea desfășurării.
Când obiectul ScaledObject se șterge, definiția HPA corespunzătoare este eliberată.
Iată definiția ScaledObject pentru exemplul nostru, în care este utilizat 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]))
Rețineți următoarele aspecte:
- Acesta indică către
Deploymentcu numelego-prom-app. - Tipul trigger-ului este
Prometheus. Adresa serverului Prometheus este menționată împreună cu numele metrcii, valoarea de prag și , care va fi utilizată. Interogarea PromQL estesum(rate(http_requests[2m])). - Conform
pollingInterval, KEDA interoghează obiectivul de la Prometheus la fiecare cincisprezece secunde. Se acceptă un minim de un pod (minReplicaCount), iar numărul maxim de pod-uri nu depășeștemaxReplicaCountîn acest exemplu — zece.
Se poate seta minReplicaCount la zero. În acest caz, KEDA activează desfășurarea de la zero la unu și apoi oferă HPA pentru scalarea automată ulterioară. Este posibilă și inversarea ordinii, adică scalarea de la unu la zero. În exemplul nostru nu am ales zero, deoarece acest lucru este un serviciu HTTP, nu un sistem pe cerere.
Magia din interiorul auto-scalării
Valoarea de prag este utilizată ca trigger pentru scalarea desfășurării. În exemplul nostru, interogarea PromQL sum(rate (http_requests [2m])) returnează valoarea agregată a vitezei solicitărilor HTTP (numărul de solicitări pe secundă), măsurată în ultimele două minute.
Deoarece valoarea de prag este trei, va exista un pod atât timp cât valoarea sum(rate (http_requests [2m])) este mai mică decât trei. Dacă valoarea crește, se adaugă un pod suplimentar de fiecare dată când sum(rate (http_requests [2m])) crește cu trei. De exemplu, dacă valoarea variază de la 12 la 14, numărul de pod-uri va fi patru.
Acum să încercăm să configurăm!
Configurare preliminară
Tot ce aveți nevoie este un cluster Kubernetes și un utilitar configurat kubectl. În acest exemplu se utilizează un cluster minikube, dar puteți lua orice altul. Pentru instalarea cluster-ului există .
Instalare 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/
Instalați , pentru a accesa cluster-ul Kubernetes.
Instalare 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
Instalarea KEDA
Puteți desfășura KEDA în mai multe moduri, acestea sunt enumerate în . Folosesc YAML monolit:
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 pentru verificare:
kubectl get pods -n keda
Așteptați ca pod-ul KEDA Operator să pornească — să treacă în Starea de rulare. Și apoi continuați.
Instalarea Redis folosind Helm
Dacă nu aveți Helm instalat, utilizați acest . Comanda pentru instalare pe Mac:
brew install kubernetes-helm
helm init --history-max 200
helm init inițializează interfața de linie de comandă locală și, de asemenea, instalează Tiller în clusterul Kubernetes.
kubectl get pods -n kube-system | grep tiller
Așteptați ca pod-ul Tiller să treacă în starea de rulare.
Nota traducătorului: Autorul folosește Helm@2, care necesită instalarea componentei server Tiller. Acum este relevant Helm@3, pentru care partea de server nu este necesară.
După instalarea Helm, pentru a lansa Redis, este suficientă o singură comandă:
helm install --name redis-server --set cluster.enabled=false --set
usePassword=false stable/redis
Asigurați-vă că Redis s-a lansat cu succes:
kubectl get pods/redis-server-master-0
Așteptați ca pod-ul Redis să treacă în starea de Running.
Desfășurarea aplicației
Comanda pentru desfășurare:
kubectl apply -f go-app.yaml
//output
deployment.apps/go-prom-app created
service/go-prom-app-service created
Verificați că totul a fost lansat:
kubectl get pods -l=app=go-prom-app
Așteptați ca Redis să treacă în starea Running.
Desfășurarea serverului Prometheus
Manifestul Prometheus folosește . Acesta permite descoperirea dinamică a pod-urilor de aplicație pe baza etichetei serviciului.
kubernetes_sd_configs:
- role: service
relabel_configs:
- source_labels: [__meta_kubernetes_service_label_run]
regex: go-prom-app-service
action: keep
Pentru desfășurare:
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 că totul a fost lansat:
kubectl get pods -l=app=prometheus-server
Așteptați ca pod-ul Prometheus să treacă în starea Running.
Windows VPS pentru lucru la distanță kubectl port-forward pentru accesarea interfeței de utilizator Prometheus (sau a serverului API) la adresa .
kubectl port-forward service/prometheus-service 9090
Desfășurarea configurației de scalare automată KEDA
Comanda pentru crearea 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ă aproximativ 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 pod-ul aplicației. Ar trebui să fie activ un singur exemplar, 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ă vedeți 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 funcționalitate: acces la aplicație
Pentru a accesa endpoint-ul 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 . Pentru aceasta, executați comanda:
curl http://localhost:8080/test
Rezultatul arată aproximativ așa:
Accesat pe 2019-10-21 11:29:10.560385986 +0000 UTC
m=+406004.817901246
Număr de acces 1
În această etapă, verificați și Redis. Veți observa că cheia access_count a fost crescută la 1:
kubectl exec -it redis-server-master-0 -- redis-cli get access_count
//output
"1"
Asigurați-vă că valoarea metricii http_requests este 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
Generarea de sarcină
Vom folosi — o utilitară pentru generarea de sarcini:
curl -o hey https://storage.googleapis.com/hey-release/hey_darwin_amd64
&& chmod a+x hey
De asemenea, puteți descărca utilitarul pentru sau .
Rulați-l:
./hey http://localhost:8080/test
Implicit, utilitarul trimite 200 de cereri. Puteți verifica acest lucru folosind metricile 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
Confirmați valoarea metricii 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âmpul valoare. Acesta nu este suficient pentru scalare, deoarece pragul stabilit de noi este de 3.
Mai multă sarcină!
Într-un nou terminal, urmăriți numărul de poduri ale aplicației:
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 observa că HPA scalează desfășurarea și pornește noi poduri. Verificați HPA pentru a vă asigura de acest lucru:
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ă sarcina este variabilă, desfășurarea se va reduce la un punct în care funcționează doar un singur pod. Dacă doriți să verificați metrica reală (returnată de interogarea PromQL), utilizați comanda:
curl -g
'http://localhost:9090/api/v1/query?query=sum(rate(http_requests[2m]))'
Curățare
//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 permite scalarea automată a desfășurărilor Kubernetes (de la/să) în funcție de datele din metrici externe. De exemplu, pe baza metricilor Prometheus, lungimea cozii în Redis, întârzierile consumatorului în topicul Kafka.
KEDA integrează o sursă externă și, de asemenea, furnizează metricile sale prin Metrics Server pentru Horizontal Pod Autoscaler.
Good luck!
Ce altceva să citești:
- .
- .
- .
Sursa: habr.com
