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

Autoscaling af Kubernetes-applikationer ved hjælp af Prometheus og KEDABallonmanden af Cimuanos

Skalérbarhed er et nøglekrav for cloud-applikationer. Med Kubernetes er det lige så nemt at skalere applikationen som at øge antallet af replikaer til den relevante deployment eller ReplicaSet — men det er en manuel proces.

Kubernetes gør det muligt at skalere applikationer automatisk (dvs. Pods i deployment eller ReplicaSet) på deklarativ måde ved hjælp af specifikationen for Horizontal Pod Autoscaler. Som standard er kriteriet for automatisk skalering ressourceforbrugsmetrikkerne, men man kan integrere brugerdefinerede metrikker og metrikker, der leveres udefra.

Kommandoen Kubernetes aaS fra Mail.ru oversatte artiklen om, hvordan man bruger eksterne metrikker til automatisk skalering af Kubernetes-applikationer. For at vise, hvordan det hele fungerer, bruger forfatteren metrikker for HTTP-anmodninger, som indsamles med Prometheus.

I stedet for horisontal autoskalering af pods anvendes Kubernetes Event Driven Autoscaling (KEDA) — en open source Kubernetes-operator. Den integreres oprindeligt med Horizontal Pod Autoscaler for at sikre glat autoskalering (inklusive op/ned til nul) for begivenhedsstyrede arbejdsbelastninger. Koden er tilgængelig på GitHub.

En kort oversigt over systemets funktion

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

Diagrammet viser en kort beskrivelse af, hvordan det hele fungerer:

  1. Applikationen leverer metrikker for antallet af HTTP-anmodninger i Prometheus-format.
  2. Prometheus er konfigureret til at indsamle disse målinger.
  3. Prometheus-skaleren i KEDA er konfigureret til at autoskalere applikationen baseret på antallet af HTTP-anmodninger.

Nu vil jeg fortælle om hver enkelt komponent.

KEDA og Prometheus

Prometheus er et open source sæt af værktøjer til overvågning og alarmering af systemer, en del af Cloud Native Computing Foundation. Den indsamler metrikker fra forskellige kilder og gemmer dem som tidsseriedata. Til visualisering af data kan man bruge Grafana eller andre visualiseringsværktøjer, der arbejder med Kubernetes API.

KEDA understøtter konceptet med en skalerer — den fungerer som en bro mellem KEDA og et eksternt system. Implementeringen af skalerespecifikationen er forskellig for hver målsystem og udtrækker data fra den. Derefter bruger KEDA dem til at styre automatisk skalering.

Skalere understøtter flere datakilder, såsom Kafka, Redis, Prometheus. Det betyder, at KEDA kan anvendes til automatisk skalering af Kubernetes-implementeringer ved at bruge Prometheus-metrics som kriterier.

Testapplikation

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

  1. Den bruger Prometheus Go-klientbiblioteket til at instrumentere applikationen og levere metric http_requests, der indeholder en tæller for anmodninger. Endepunktet, hvor Prometheus-metrics er tilgængelige, findes på URI /metrics.
    var httpRequestsCounter = promauto.NewCounter(prometheus.CounterOpts{
           Name: "http_requests",
           Help: "antal http-anmodninger",
       })
    
  2. Som svar på anmodningen GET øger applikationen værdien af nøglen (access_count) i Redis. Dette er en simpel måde at udføre arbejdet som en del af HTTP-handleren og samtidig kontrollere Prometheus-metrics. Værdien af metrikken 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("Kan ikke inkrementere redis-tælleren", err)
                   os.Exit(1)
               }
               resp := "Adgang på " + time.Now().String() + "nAdgangstælling " + strconv.Itoa(int(count))
               w.Write([]byte(resp))
           })
           http.ListenAndServe(":8080", nil)
       }
    

Applikationen implementeres i Kubernetes via Deployment. En tjeneste oprettes også, ClusterIPden gør det muligt for Prometheus-serveren at modtage applikationens metrics.

Her er manifests for implementering af applikationen.

Prometheus-serveren

Manifestet for implementering af Prometheus består af:

  • ConfigMap — til viderebefordring af Prometheus-konfigurationen;
  • Deployment — til implementering af Prometheus i Kubernetes-klyngen;
  • ClusterIP — en tjeneste til adgang til Prometheus UI;
  • ClusterRole, ClusterRoleBinding og ServiceAccount — til at understøtte autoopdagelse af tjenester i Kubernetes (Auto-discovery).

Her er manifest til at køre Prometheus.

KEDA Prometheus ScaledObject

Skalereren fungerer som en bro mellem KEDA og det eksterne system, hvor metrics skal hentes fra. ScaledObject — en konfigurerbar ressource, der skal implementeres for at synkronisere implementeringen med begivenhedskilden, i dette tilfælde Prometheus.

ScaledObject indeholder information om skaleringen af implementeringen, metadata om begivenhedskilden (f.eks. hemmeligheder til forbindelse, køens navn), forespørgselsinterval, gendannelsesperiode og andre data. Den fører til den relevante autoskalering ressource (HPA-definition) for at skalere implementeringen.

Når objektet ScaledObject fjernes, den tilsvarende HPA-definitionen renses.

Her er definitionen ScaledObject for vores eksempel, hvor en scaler bruges 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]))

Tag venligst følgende punkter i betragtning:

  1. Det henviser til Deployment med navnet go-prom-app.
  2. Trigger type — Prometheus. Prometheus-serverens adresse nævnes sammen med metriknavnet, tærskelværdien og PromQL-forespørgslen, som vil blive brugt. PromQL-forespørgslen er sum(rate(http_requests[2m])).
  3. Ifølge pollingInterval, KEDA spørger målet hos Prometheus hver femten sekunder. Minimum én pod understøttes (minReplicaCount), mens det maksimale antal pods ikke overstiger maxReplicaCount (i dette eksempel — ti).

Det kan sættes minReplicaCount til nul. I dette tilfælde aktiverer KEDA deploymentet fra nul til én, og derefter giver HPA til videre automatisk skalering. Den omvendte rækkefølge er også mulig, altså skalering fra én til nul. I eksemplet har vi ikke valgt nul, da dette er en HTTP-tjeneste, ikke en forespørgsel-system.

Magien bag autoskalering

Tærskelværdien bruges som en trigger til at skalere deploymentet. I vores eksempel returnerer PromQL-forespørgslen sum(rate(http_requests[2m])) en aggregeret værdi af hastigheden for HTTP-anmodninger (antal anmodninger per sekund), målt over de seneste to minutter.

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

Lad os nu prøve at konfigurere!

Forudkonfiguration

Alt, hvad du behøver, er et Kubernetes-klynge og et konfigureret værktøj kubectl. I dette eksempel bruges en klynge minikube, men du kan tage en hvilken som helst anden. For at installere klyngen er der vejledning.

Installer den nyeste 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/

Installer kubectl, for at få adgang til Kubernetes-klyngen.

Installer den nyeste 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

Installation af KEDA

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

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

KEDA og dens komponenter installeres i navnerummet keda. Kommandoen til at kontrollere:

kubectl get pods -n keda

Vent på, at KEDA Operator-poden starter — går ind i Running State. Og fortsæt derefter.

Installation af Redis ved hjælp af Helm

Hvis du ikke har installeret Helm, kan du bruge denne vejledning. Kommandoen til installation på Mac:

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

helm init initialiserer det lokale kommandolinjeinterface og installerer også Tiller i Kubernetes-klusteret.

kubectl get pods -n kube-system | grep tiller

Vent på, at Tiller-poden går ind i tilstanden Running.

Oversætterens note: Forfatteren bruger Helm@2, som kræver installation af serverkomponenten Tiller. Helm@3 er nu aktuel, hvor serverkomponenten ikke er nødvendig.

Efter installationen af Helm kræves kun én kommando for at køre Redis:

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

Sørg for, at Redis er startet korrekt:

kubectl get pods/redis-server-master-0

Vent på, at Redis-poden går ind i tilstanden Kørende.

Implementering af applikationen

Kommandoen til implementering:

kubectl apply -f go-app.yaml

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

Kontroller, at alt er startet:

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

Vent på, at Redis går ind i tilstanden Kørende.

Implementering af Prometheus-serveren

Manifestet for Prometheus bruger Kubernetes Service Discovery for Prometheus. Det gør det muligt dynamisk at opdage applikationspoder baseret på tjenestemærket.

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

Til implementering:

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

Kontroller, at alt er startet:

kubectl get pods -l=app=prometheus-server

Vent på, at Prometheus-poden går ind i tilstanden Kørende.

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

kubectl port-forward service/prometheus-service 9090

Implementering af autoskalering konfiguration for KEDA

Kommandoen til at oprette ScaledObject:

kubectl apply -f keda-prometheus-scaledobject.yaml

Tjek KEDA-operatorens logs:

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

Resultatet ser omtrent slik ut:

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"

Kontroller podene for applikasjonen. Det skal være en instans kjørende, siden minReplicaCount er lik 1:

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

Kontroller at HPA-ressursen er opprettet:

kubectl get hpa

Du bør se noe slik:

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

Helsekontroll: tilgang til applikasjonen

For å få tilgang til REST-endepunktet til applikasjonen vår, kjør:

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

Nå kan du få tilgang til Go-applikasjonen ved å bruke adressen http://localhost:8080. For å gjøre dette, kjør kommandoen:

curl http://localhost:8080/test

Resultatet ser omtrent slik ut:

Tilgang registrert 2019-10-21 11:29:10.560385986 +0000 UTC 
m=+406004.817901246
Tilgangsantall 1

På dette stadiet bør du også sjekke Redis. Du vil se at nøkkelen access_count økes til 1:

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

Sørg for at metrikken http_requests er den samme:

curl http://localhost:8080/metrics | grep http_requests
//output
# HELP http_requests antall http forespørsel
# TYPE http_requests counter
http_requests 1

Generere belastning

Vi vil bruke hey — verktøyet for å generere belastning:

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

Du kan også laste ned verktøyet for Linux eller Windows.

Kjør det:

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

Som standard sender verktøyet 200 forespørsel. Du kan bekrefte dette ved å bruke Prometheus-metrikker og Redis.

curl http://localhost:8080/metrics | grep http_requests
//output
# HELP http_requests antall http forespørsel
# TYPE http_requests counter
http_requests 201
kubectl exec -it redis-server-master-0 -- redis-cli get access_count
//output
201

Bekreft verdien av den faktiske metrikken (tilbakeført ved PromQL-spørring):

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 tilfellet er det faktiske resultatet lik 1,686057971014493 og vises i feltet value. Dette er ikke tilstrekkelig for skalering, siden terskelen vi har satt er 3.

Mer belastning!

I et nytt terminalvindu, følg med på antallet applikasjonspods:

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

La oss øke belastningen med kommandoen:

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

Etter en stund vil du se at HPA skalerer distribusjonen og starter nye pods. Sjekk HPA for å bekrefte dette:

kubectl get hpa
NAVN                   REFERENCER                MÅL         MINPODS   MAXPODS   REPLIKER   ALDER
keda-hpa-go-prom-app   Deployment/go-prom-app   1830m/3 (gennemsnit)   1         10        6          4m22s

Hvis belastningen er uregelmæssig, vil deploymentet falde til det punkt, hvor kun én pod kører. Hvis du vil tjekke den faktiske metrisk (returneret af PromQL-forespørgslen), skal du bruge kommandoen:

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

Rydning

//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 gør det muligt automatisk at skalere dine Kubernetes-deploymenter (op/ned fra nul) baseret på data fra eksterne metrikker. For eksempel baseret på Prometheus-metrik, kølængde i Redis, eller forbrugers ventetid i Kafka-emnet.

KEDA udfører integration med en ekstern kilde og leverer også dens metrikker via Metrics Server til Horizontal Pod Autoscaler.

Held og lykke!

Yderligere læsning:

  1. Bedste praksis og anbefalinger til implementering af containere og Kubernetes i produktionsmiljøer.
  2. 90+ nyttige værktøjer til Kubernetes: implementering, administration, overvågning, sikkerhed og mere.
  3. Vores kanal Omkring Kubernetes på Telegram.

Kilde: habr.com

Køb pålidelig webhosting med DDoS-beskyttelse, VPS VDS-servere 🔥 Køb pålidelig webhosting med DDoS-beskyttelse, VPS VDS-servere | ProHoster