Autoskalering af Kubernetes-applikationer ved hjælp af Prometheus og KEDA

Autoskalering af Kubernetes-applikationer ved hjælp af Prometheus og KEDABalloon Man fra Cimuanos

Skalerbarhed er et nøglekrav for cloud-applikationer. Med Kubernetes er det lige så enkelt at skalere en applikation som at øge antallet af replikaer til den relevante implementering eller ReplicaSet - men det er en manuel proces.

Kubernetes tillader, at applikationer automatisk skaleres (dvs. Pods i en implementering eller ReplicaSet) på en deklarativ måde ved hjælp af Horizontal Pod Autoscaler-specifikationen. Standardkriteriet for automatisk skalering er CPU-forbrugsmålinger (ressourcemålinger), men du kan integrere brugerdefinerede og eksternt leverede metrics.

Team Kubernetes aaS fra Mail.ru oversat en artikel om, hvordan man bruger eksterne målinger til automatisk at skalere en Kubernetes-applikation. For at vise, hvordan alt fungerer, bruger forfatteren HTTP-adgangsanmodningsmålinger, som indsamles ved hjælp af Prometheus.

I stedet for horisontal autoskalering af pods, bruges Kubernetes Event Driven Autoscaling (KEDA), en open source Kubernetes-operatør. Den integreres naturligt med Horizontal Pod Autoscaler for at give problemfri autoskalering (inklusive til/fra nul) til hændelsesdrevne arbejdsbelastninger. Kode tilgængelig på GitHub.

Kort oversigt over systemet

Autoskalering af Kubernetes-applikationer ved hjælp af Prometheus og KEDA

Diagrammet viser en kort beskrivelse af, hvordan alt fungerer:

  1. Applikationen giver HTTP-hitantal-metrics i Prometheus-format.
  2. Prometheus er konfigureret til at indsamle disse metrics.
  3. Prometheus scaler i KEDA er konfigureret til automatisk at skalere applikationen baseret på antallet af HTTP-hits.

Nu vil jeg fortælle dig i detaljer om hvert element.

KEDA og Prometheus

Prometheus er et open source-system, overvågnings- og alarmeringsværktøj, del Cloud Native Computing Foundation. Indsamler metrics fra forskellige kilder og gemmer dem som tidsseriedata. For at visualisere data kan du bruge grafana eller andre visualiseringsværktøjer, der fungerer med Kubernetes API.

KEDA understøtter konceptet med en scaler - den fungerer som en bro mellem KEDA og det eksterne system. Skalerimplementeringen er specifik for hvert målsystem og udtrækker data fra det. KEDA bruger dem derefter til at styre automatisk skalering.

Skalere understøtter flere datakilder, for eksempel Kafka, Redis, Prometheus. Det vil sige, at KEDA kan bruges til automatisk at skalere Kubernetes-implementeringer ved hjælp af Prometheus-metrics som kriterier.

Test applikation

Golang-testapplikationen giver adgang via HTTP og udfører to vigtige funktioner:

  1. Bruger Prometheus Go-klientbiblioteket til at instrumentere applikationen og levere http_requests-metrikken, som indeholder et hitantal. Slutpunktet, hvor Prometheus-metrics er tilgængelige, er placeret på URI'en /metrics.
    var httpRequestsCounter = promauto.NewCounter(prometheus.CounterOpts{
           Name: "http_requests",
           Help: "number of http requests",
       })
    
  2. Som svar på en anmodning GET applikationen øger værdien af ​​nøglen (access_count) i Redis. Dette er en nem måde at udføre arbejdet som en del af en HTTP-handler og også kontrollere Prometheus-metrics. Den metriske værdi skal være den samme som værdien access_count i 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)
       }
    

Applikationen implementeres til Kubernetes via Deployment. Der oprettes også en service ClusterIP, giver det Prometheus-serveren mulighed for at hente applikationsmetrics.

her implementeringsmanifest for applikationen.

Prometheus server

Prometheus-implementeringsmanifestet består af:

  • ConfigMap — at overføre Prometheus-konfigurationen;
  • Deployment — til at implementere Prometheus i en Kubernetes-klynge;
  • ClusterIP — tjeneste for adgang til UI Prometheus;
  • ClusterRole, ClusterRoleBinding и ServiceAccount — til automatisk registrering af tjenester i Kubernetes (Auto-discovery).

her manifest til at køre Prometheus.

KEDA Prometheus ScaledObject

Skaleren fungerer som en bro mellem KEDA og det eksterne system, hvorfra målinger skal hentes. ScaledObject er en tilpasset ressource, der skal implementeres for at synkronisere implementeringen med hændelseskilden, i dette tilfælde Prometheus.

ScaledObject indeholder installationsskaleringsoplysninger, hændelseskildemetadata (såsom forbindelseshemmeligheder, kønavn), polling-interval, gendannelsesperiode og andre data. Det resulterer i den tilsvarende autoskaleringsressource (HPA-definition) for at skalere implementeringen.

Når en genstand ScaledObject slettes, slettes den tilsvarende HPA-definition.

Her er definitionen ScaledObject for vores eksempel bruger den en 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]))

Bemærk venligst følgende punkter:

  1. Han peger på Deployment Med navn go-prom-app.
  2. Trigger type - Prometheus. Prometheus-serveradressen er nævnt sammen med metrisk navn, tærskel og PromQL forespørgsel, som vil blive brugt. PromQL-forespørgsel - sum(rate(http_requests[2m])).
  3. Ifølge pollingInterval,KEDA anmoder om et mål fra Prometheus hvert femtende sekund. Mindst én under (minReplicaCount), og det maksimale antal bælg overstiger ikke maxReplicaCount (i dette eksempel - ti).

Kan installeres minReplicaCount lig med nul. I dette tilfælde aktiverer KEDA nul-til-en-implementeringen og afslører derefter HPA'en for yderligere automatisk skalering. Den omvendte rækkefølge er også mulig, det vil sige skalering fra en til nul. I eksemplet valgte vi ikke nul, fordi dette er en HTTP-tjeneste og ikke et on-demand-system.

Magien i autoskalering

Tærsklen bruges som en trigger til at skalere implementeringen. I vores eksempel er PromQL-forespørgslen sum(rate (http_requests [2m])) returnerer den aggregerede HTTP-anmodningshastighed (anmodninger pr. sekund), målt over de sidste to minutter.

Da tærskelværdien er tre, betyder det, at der vil være én under, mens værdien sum(rate (http_requests [2m])) mindre end tre. Hvis værdien stiger, tilføjes en ekstra sub hver gang sum(rate (http_requests [2m])) stiger med tre. For eksempel, hvis værdien er fra 12 til 14, så er antallet af pods fire.

Lad os nu prøve at sætte det op!

forudindstilling

Alt du behøver er en Kubernetes-klynge og et konfigureret hjælpeprogram kubectl. Dette eksempel bruger en klynge minikube, men du kan tage en hvilken som helst anden. For at installere en klynge er der lederskab.

Installer den seneste version på 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/

Indstil kubectlfor at få adgang til Kubernetes-klyngen.

Installer den seneste version på 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

KEDA installation

Du kan implementere KEDA på flere måder, de er angivet i dokumentation. Jeg bruger monolitisk YAML:

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

KEDA og dets komponenter er installeret i navneområdet keda. Kommando til at kontrollere:

kubectl get pods -n keda

Vent på, at KEDA-operatøren starter og går til Running State. Og fortsæt derefter.

Installation af Redis ved hjælp af Helm

Hvis du ikke har Helm installeret, så brug denne ledelse. Kommando til at installere på Mac:

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

helm init initialiserer den lokale kommandolinjegrænseflade og installerer også Tiller til Kubernetes-klyngen.

kubectl get pods -n kube-system | grep tiller

Vent på, at Tiller-pod'en går ind i køretilstand.

Oversætterens bemærkning: Forfatteren bruger Helm@2, som kræver, at Tiller-serverkomponenten er installeret. Nu er Helm@3 relevant, det kræver ikke en serverdel.

Efter installation af Helm er en kommando nok til at starte Redis:

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

Bekræft, at Redis er startet med succes:

kubectl get pods/redis-server-master-0

Vent på, at Redis går i tilstand Running.

Applikationsimplementering

Implementeringskommando:

kubectl apply -f go-app.yaml

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

Tjek at alt er startet:

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

Vent på, at Redis går ind i tilstanden Running.

Implementering af en Prometheus-server

Prometheus-manifestet bruger Kubernetes Service Discovery for Prometheus. Det giver mulighed for dynamisk opdagelse af applikationspods baseret på serviceetiketten.

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

Sådan implementeres:

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

Tjek at alt er startet:

kubectl get pods -l=app=prometheus-server

Vent på, at Prometheus går i tilstand Running.

brug kubectl port-forward for at få adgang til Prometheus-brugergrænsefladen (eller API-serveren) på http://localhost:9090.

kubectl port-forward service/prometheus-service 9090

Implementering af KEDA Autoscaling Configuration

Kommando til at oprette ScaledObject:

kubectl apply -f keda-prometheus-scaledobject.yaml

Tjek KEDA-operatørloggene:

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

Resultatet ser nogenlunde således ud:

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"

Tjek under ansøgninger. Én instans skal køre pga minReplicaCount er lig med 1:

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

Bekræft, at HPA-ressourcen blev oprettet:

kubectl get hpa

Du bør se noget som:

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

Sundhedstjek: applikationsadgang

For at få adgang til vores applikations REST-slutpunkt skal du køre:

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

Du kan nu få adgang til din Go-app ved hjælp af adressen http://localhost:8080. For at gøre dette skal du køre kommandoen:

curl http://localhost:8080/test

Resultatet ser nogenlunde således ud:

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

På dette tidspunkt skal du også tjekke Redis. Du vil se, at nøglen access_count øget til 1:

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

Sørg for, at den metriske værdi er http_requests det samme:

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

Oprettelse af belastning

Vi vil bruge hey — værktøj til generering af belastning:

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

Du kan også downloade værktøjet til Linux eller Windows.

Kør det:

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

Som standard sender værktøjet 200 anmodninger. Du kan verificere dette ved hjælp af Prometheus-metrics såvel som 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

Valider værdien af ​​den faktiske metric (returneret af PromQL-forespørgslen):

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"]}]}}

I dette tilfælde er det faktiske resultat 1,686057971014493 og vises i feltet value. Dette er ikke nok til skalering, da den tærskel, vi sætter, er 3.

Mere belastning!

I den nye terminal skal du overvåge antallet af applikationspuder:

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

Lad os øge belastningen ved hjælp af kommandoen:

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

Efter et stykke tid vil du se HPA skalere implementeringen og lancere nye pods. Tjek din HPA for at sikre dig:

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

Hvis belastningen er inkonsekvent, vil implementeringen blive reduceret til det punkt, hvor kun én pod kører. Hvis du vil kontrollere den faktiske metrik (returneret af PromQL-forespørgslen), skal du bruge kommandoen:

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

Очистка

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

Konklusion

KEDA giver dig mulighed for automatisk at skalere dine Kubernetes-implementeringer (til/fra nul) baseret på data fra eksterne metrics. For eksempel baseret på Prometheus-metrics, kølængde i Redis, forbrugerforsinkelse i Kafka-emnet.

KEDA integrerer med en ekstern kilde og leverer også sine metrics gennem Metrics Server til Horizontal Pod Autoscaler.

Held og lykke!

Hvad skal man ellers læse:

  1. Best Practices og Best Practices for at køre containere og Kubernetes i produktionsmiljøer.
  2. 90+ nyttige værktøjer til Kubernetes: Implementering, administration, overvågning, sikkerhed og mere.
  3. Vores kanal Around Kubernetes i Telegram.

Kilde: www.habr.com

Tilføj en kommentar