Autoscaling Kubernetes-applikaasjes mei Prometheus en KEDA

Autoscaling Kubernetes-applikaasjes mei Prometheus en KEDABalloon Man troch Cimuanos

Skalberens is in wichtige eask foar wolkapplikaasjes. Mei Kubernetes is it skaalfergrutting fan in applikaasje sa ienfâldich as it fergrutsjen fan it oantal replika's foar de passende ynset of ReplicaSet - mar it is in hânmjittich proses.

Kubernetes lit applikaasjes automatysk skaal wurde (d.w.s. Pods yn in ynset of ReplicaSet) op in deklarative manier mei de Horizontale Pod Autoscaler-spesifikaasje. It standertkritearium foar automatyske skaalfergrutting is CPU-gebrûksmetriken (boarnemetriken), mar jo kinne oanpaste en ekstern levere metriken yntegrearje.

team Kubernetes aaS fan Mail.ru in artikel oerset oer hoe't jo eksterne metriken kinne brûke om in Kubernetes-applikaasje automatysk te skaaljen. Om sjen te litten hoe't alles wurket, brûkt de auteur HTTP-tagongsfersykmetriken, dy't wurde sammele mei Prometheus.

Yn stee fan horizontale autoscaling fan pods, Kubernetes Event Driven Autoscaling (KEDA) wurdt brûkt, in iepen boarne Kubernetes operator. It yntegreart natuerlik mei Horizontal Pod Autoscaler om naadleaze autoscaling te leverjen (ynklusyf nei / fan nul) foar evenemint-oandreaune workloads. Koade beskikber by GitHub.

Koarte oersjoch fan it systeem

Autoscaling Kubernetes-applikaasjes mei Prometheus en KEDA

It diagram lit in koarte beskriuwing sjen fan hoe't alles wurket:

  1. De applikaasje leveret HTTP-hittellingmetriken yn Prometheus-formaat.
  2. Prometheus is konfigurearre om dizze metriken te sammeljen.
  3. De Prometheus-skaler yn KEDA is konfigureare om de applikaasje automatysk te skaaljen op basis fan it oantal HTTP-hits.

No sil ik jo yn detail fertelle oer elk elemint.

KEDA en Prometheus

Prometheus is in iepen boarne systeem tafersjoch en warskôging toolkit, diel Stichting Cloud Native Computing. Sammelt metriken út ferskate boarnen en slacht se op as tiidrige gegevens. Om gegevens te visualisearjen kinne jo brûke grafana of oare fisualisaasje-ark dy't wurkje mei de Kubernetes API.

KEDA stipet it konsept fan in scaler - it fungearret as in brêge tusken KEDA en it eksterne systeem. De scaler-ymplemintaasje is spesifyk foar elk doelsysteem en ekstrakt gegevens derút. KEDA brûkt se dan om automatyske skaalfergrutting te kontrolearjen.

Scalers stypje meardere gegevens boarnen, Bygelyks, Kafka, Redis, Prometheus. Dat is, KEDA kin brûkt wurde om Kubernetes-ynset automatysk te skaaljen mei Prometheus-metriken as kritearia.

Test applikaasje

De Golang-testapplikaasje biedt tagong fia HTTP en fiert twa wichtige funksjes út:

  1. Brûkt de Prometheus Go-kliïntbibleteek om de applikaasje te ynstrumintearjen en de http_requests-metrik te leverjen, dy't in hittelling befettet. It einpunt wêr't Prometheus-metriken beskikber binne, leit by de URI /metrics.
    var httpRequestsCounter = promauto.NewCounter(prometheus.CounterOpts{
           Name: "http_requests",
           Help: "number of http requests",
       })
    
  2. As antwurd op in fersyk GET de applikaasje fergruttet de wearde fan 'e kaai (access_count) yn Redis. Dit is in maklike manier om it wurk te dwaan as ûnderdiel fan in HTTP-handler en ek Prometheus-metriken te kontrolearjen. De metrike wearde moat itselde wêze as de wearde access_count yn 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)
       }
    

De applikaasje wurdt ynset nei Kubernetes fia Deployment. In tsjinst wurdt ek makke ClusterIP, It lit de Prometheus-tsjinner tapassingsmetriken krije.

hjir ynset manifest foar de applikaasje.

Prometheus tsjinner

It Prometheus-ynsetmanifest bestiet út:

  • ConfigMap - om de Prometheus-konfiguraasje oer te bringen;
  • Deployment - foar it ynsetten fan Prometheus yn in Kubernetes-kluster;
  • ClusterIP - tsjinst foar tagong ta UI Prometheus;
  • ClusterRole, ClusterRoleBinding и ServiceAccount - foar automatyske deteksje fan tsjinsten yn Kubernetes (Auto-ûntdekking).

hjir manifest foar it útfieren fan Prometheus.

KEDA Prometheus ScaledObject

De scaler fungearret as in brêge tusken KEDA en it eksterne systeem wêrfan metriken moatte wurde krigen. ScaledObject is in oanpaste boarne dy't ynset wurde moat om de ynset te syngronisearjen mei it barren boarne, yn dit gefal Prometheus.

ScaledObject befettet skaalfergrutting fan ynset, metadata fan eveneminteboarne (lykas ferbiningsgeheimen, wachtrige namme), polling-ynterval, hersteltiid en oare gegevens. It resulteart yn 'e korrespondearjende autoskalearjende boarne (HPA-definysje) om de ynset te skaaljen.

Wannear't in foarwerp ScaledObject wurdt wiske, wurdt de oerienkommende HPA-definysje wiske.

Hjir is de definysje ScaledObject foar ús foarbyld, it brûkt in 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]))

Let op de folgjende punten:

  1. Hy wiist nei Deployment Mei namme go-prom-app.
  2. Trigger type - Prometheus. It Prometheus-tsjinneradres wurdt neamd tegearre mei de metrike namme, drompel en PromQL query, dy't brûkt wurde sil. PromQL Query - sum(rate(http_requests[2m])).
  3. Neffens pollingInterval,KEDA freget elke fyftjin sekonden in doel fan Prometheus. Op syn minst ien ûnder (minReplicaCount), en it maksimum oantal pods giet net boppe maxReplicaCount (yn dit foarbyld - tsien).

Kin wurde ynstallearre minReplicaCount gelyk oan nul. Yn dit gefal aktivearret KEDA de nul-op-ien ynset en bleatret dan de HPA foar fierdere automatyske skaalfergrutting. De omkearde folchoarder is ek mooglik, dat is, skaalfergrutting fan ien nei nul. Yn it foarbyld hawwe wy gjin nul selektearre, om't dit in HTTP-tsjinst is en net in systeem op oanfraach.

De magy binnen autoscaling

De drompel wurdt brûkt as trigger om de ynset te skaaljen. Yn ús foarbyld is de PromQL-query sum(rate (http_requests [2m])) jout it aggregearre HTTP-fersyktaryf werom (fersiken per sekonde), mjitten oer de lêste twa minuten.

Sûnt de drompel wearde is trije, it betsjut dat der sil wêze ien ûnder wylst de wearde sum(rate (http_requests [2m])) minder as trije. As de wearde ferheget, wurdt elke kear in ekstra sub tafoege sum(rate (http_requests [2m])) nimt ta mei trije. Bygelyks, as de wearde fan 12 oant 14 is, dan is it oantal pods fjouwer.

Litte wy no besykje it yn te stellen!

foarôf ynstelle

Alles wat jo nedich binne is in Kubernetes-kluster en in konfigureare hulpprogramma kubectl. Dit foarbyld brûkt in kluster minikube, mar jo kinne nimme in oare. Om in kluster te ynstallearjen is d'r liederskip.

Ynstallearje de lêste ferzje op 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/

Ynstallearje kubectlom tagong te krijen ta it Kubernetes-kluster.

Ynstallearje de lêste ferzje op 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 ynstallaasje

Jo kinne KEDA op ferskate manieren ynsette, se wurde fermeld yn dokumintaasje. Ik brûk monolityske YAML:

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

KEDA en syn komponinten wurde ynstalleare yn 'e nammeromte keda. Kommando om te kontrolearjen:

kubectl get pods -n keda

Wachtsje oant KEDA Operator begjint en gean nei Running State. En dêrnei, trochgean.

Redis ynstallearje mei Helm

As jo ​​Helm net ynstalleare hawwe, brûk dan dit liederskip. Kommando om te ynstallearjen op Mac:

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

helm init inisjalisearret de lokale kommandorigelynterface en ynstallearret ek Tiller nei it Kubernetes-kluster.

kubectl get pods -n kube-system | grep tiller

Wachtsje foar de Tiller-pod om de Running-status yn te gean.

Oersetter syn notysje: De skriuwer brûkt Helm@2, dy't fereasket dat de Tiller tsjinner komponint ynstallearre wurdt. No is Helm@3 relevant, it fereasket gjin serverdiel.

Nei it ynstallearjen fan Helm is ien kommando genôch om Redis te starten:

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

Ferifiearje dat Redis mei súkses begon is:

kubectl get pods/redis-server-master-0

Wachtsje op Redis om yn steat te gean Running.

Applikaasje ynset

Ynset kommando:

kubectl apply -f go-app.yaml

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

Kontrolearje dat alles begon is:

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

Wachtsje foar Redis om steat yn te gean Running.

It ynsetten fan in Prometheus-tsjinner

It Prometheus-manifest brûkt Kubernetes Service Discovery foar Prometheus. It makket dynamyske ûntdekking fan applikaasjepods mooglik op basis fan it tsjinstlabel.

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

Ynsette:

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

Kontrolearje dat alles begon is:

kubectl get pods -l=app=prometheus-server

Wachtsje oant Prometheus yn steat giet Running.

Gebrûk kubectl port-forward om tagong te krijen ta de brûkersynterface fan Prometheus (as API-tsjinner) by http://localhost:9090.

kubectl port-forward service/prometheus-service 9090

Ynsette KEDA Autoscaling konfiguraasje

Kommando om te meitsjen ScaledObject:

kubectl apply -f keda-prometheus-scaledobject.yaml

Kontrolearje de KEDA operator logs:

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

It resultaat sjocht der sa út:

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"

Kontrolearje ûnder applikaasjes. Ien eksimplaar moat rinne omdat minReplicaCount lyk 1:

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

Ferifiearje dat de HPA-boarne mei súkses makke is:

kubectl get hpa

Jo moatte wat sjen as:

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

Health check: applikaasje tagong

Om tagong te krijen ta it REST-einpunt fan ús applikaasje, útfiere:

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

Jo kinne no tagong krije ta jo Go-app mei it adres http://localhost:8080. Om dit te dwaan, fier it kommando út:

curl http://localhost:8080/test

It resultaat sjocht der sa út:

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

Kontrolearje op dit punt ek Redis. Jo sille sjen dat de kaai access_count ferhege nei 1:

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

Soargje derfoar dat de metrike wearde is http_requests itselde:

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

Load Creation

Wy sille brûke Hey - hulpprogramma foar it generearjen fan lading:

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

Jo kinne ek download it hulpprogramma foar linux of Windows.

Run it:

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

Standert stjoert it hulpprogramma 200 oanfragen. Jo kinne dit ferifiearje mei Prometheus-metriken lykas 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

Validearje de wearde fan 'e eigentlike metrik (werjûn troch de PromQL-query):

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

Yn dit gefal is it eigentlike resultaat 1,686057971014493 en wurdt werjûn yn it fjild value. Dit is net genôch foar skaalfergrutting, om't de drompel dy't wy ynstelle is 3.

Mear lading!

Kontrolearje yn 'e nije terminal it oantal applikaasjepods:

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

Litte wy de lading ferheegje mei it kommando:

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

Nei in skoft sille jo HPA sjen skaaljen fan de ynset en nije pods lansearje. Kontrolearje jo HPA om te soargjen dat:

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

As de lading inkonsekwint is, sil de ynset wurde fermindere oant it punt dêr't mar ien pod rint. As jo ​​​​de eigentlike metrike wolle kontrolearje (werjûn troch de PromQL-query), brûk dan it kommando:

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

Reiniging

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

konklúzje

KEDA lit jo jo Kubernetes-ynset automatysk skaalje (nei/fan nul) basearre op gegevens fan eksterne metriken. Bygelyks, basearre op Prometheus metrics, wachtrige lingte yn Redis, konsumint latency yn Kafka ûnderwerp.

KEDA yntegreart mei in eksterne boarne en leveret ek syn metriken fia Metrics Server nei Horizontal Pod Autoscaler.

Súkses!

Wat oars te lêzen:

  1. Best Practices en Best Practices foar it útfieren fan konteners en Kubernetes yn produksjeomjouwings.
  2. 90+ Nuttige ark foar Kubernetes: ynset, behear, tafersjoch, feiligens en mear.
  3. Us kanaal Around Kubernetes yn Telegram.

Boarne: www.habr.com

Add a comment