Autoscaling Kubernetes Uwendungen mat Prometheus a KEDA

Autoscaling Kubernetes Uwendungen mat Prometheus a KEDABalloon Man vum Cimuanos

Skalierbarkeet ass e Schlësselfuerderung fir Cloud Uwendungen. Mat Kubernetes ass d'Skaléierung vun enger Applikatioun sou einfach wéi d'Erhéijung vun der Unzuel vun de Repliken fir de passenden Deployment oder ReplicaSet - awer et ass e manuelle Prozess.

Kubernetes erlaabt Uwendungen automatesch skaléiert ze ginn (dh Pods an enger Deployment oder ReplicaSet) op eng deklarativ Manéier mat der Horizontal Pod Autoscaler Spezifikatioun. De Standardcritère fir automatesch Skaléierung ass CPU Benotzungsmetriken (Ressource Metriken), awer Dir kënnt personaliséiert an extern geliwwert Metriken integréieren.

Equipe Kubernetes aaS vun Mail.ru en Artikel iwwersat iwwer wéi extern Metriken benotzt ginn fir eng Kubernetes Applikatioun automatesch ze skaléieren. Fir ze weisen wéi alles funktionnéiert, benotzt den Auteur HTTP Zougang Ufro Metriken, déi mat Prometheus gesammelt ginn.

Amplaz vun der horizontaler Autoskaléierung vu Pods gëtt Kubernetes Event Driven Autoscaling (KEDA) benotzt, en Open Source Kubernetes Bedreiwer. Et integréiert natiirlech mam Horizontal Pod Autoscaler fir eng nahtlos Autoskaléierung ze bidden (inklusiv bis / vun Null) fir Event-driven Aarbechtslaaschten. Code verfügbar um GitHub.

Kuerz Iwwerbléck vum System

Autoscaling Kubernetes Uwendungen mat Prometheus a KEDA

Den Diagramm weist eng kuerz Beschreiwung wéi alles funktionnéiert:

  1. D'Applikatioun liwwert HTTP Hit Count Metriken am Prometheus Format.
  2. Prometheus ass konfiguréiert fir dës Metriken ze sammelen.
  3. De Prometheus Skaler an KEDA ass konfiguréiert fir automatesch d'Applikatioun ze skaléieren baséiert op der Unzuel vun HTTP Hits.

Elo wäert ech Iech am Detail iwwer all Element soen.

KEDA und Prometheus

Prometheus ass en Open Source System Iwwerwachung an Alarm Toolkit, Deel Cloud Native Computing Foundation. Sammelt Metriken aus verschiddene Quellen a späichert se als Zäitreidaten. Fir Donnéeën ze visualiséieren, kënnt Dir benotzen grafana oder aner Visualiséierungsinstrumenter déi mat der Kubernetes API funktionnéieren.

KEDA ënnerstëtzt d'Konzept vun engem Skaler - et handelt als Bréck tëscht KEDA an dem externe System. D'Skaler Implementatioun ass spezifesch fir all Zilsystem an extrahéiert Daten dovun. KEDA benotzt se dann fir automatesch Skala ze kontrolléieren.

Scalers ënnerstëtzen verschidde Datenquellen, zum Beispill Kafka, Redis, Prometheus. Dat ass, KEDA ka benotzt ginn fir automatesch Kubernetes-Deployementer mat Prometheus Metriken als Critèren ze skaléieren.

Test Applikatioun

D'Golang Testapplikatioun bitt Zougang iwwer HTTP a mécht zwou wichteg Funktiounen:

  1. Benotzt d'Prometheus Go Clientbibliothéik fir d'Applikatioun ze instrumentéieren an d'http_requests Metrik ze bidden, déi eng Hitzuel enthält. Den Endpunkt wou Prometheus Metriken verfügbar sinn ass um URI /metrics.
    var httpRequestsCounter = promauto.NewCounter(prometheus.CounterOpts{
           Name: "http_requests",
           Help: "number of http requests",
       })
    
  2. Als Äntwert op eng Demande GET d'Applikatioun erhéicht de Wäert vum Schlëssel (access_count) zu Redis. Dëst ass en einfache Wee fir d'Aarbecht als Deel vun engem HTTP-Handler ze maachen an och Prometheus Metriken ze kontrolléieren. De metresche Wäert muss d'selwecht sinn wéi de Wäert access_count zu 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)
       }
    

D'Applikatioun gëtt op Kubernetes iwwer Deployment. E Service gëtt och erstallt ClusterIP, et erlaabt de Prometheus-Server Applikatiounsmetriken ze kréien.

hei Deployment Manifest fir d'Applikatioun.

Prometheus Server

De Prometheus Deployment Manifest besteet aus:

  • ConfigMap - d'Prometheus Configuratioun ze transferéieren;
  • Deployment - fir Prometheus an engem Kubernetes Cluster z'installéieren;
  • ClusterIP - Service fir Zougang zu UI Prometheus;
  • ClusterRole, ClusterRoleBinding и ServiceAccount - fir automatesch Detektioun vu Servicer zu Kubernetes (Auto-Discovery).

hei manifestéiert fir Prometheus ze lafen.

KEDA Prometheus ScaledObject

De Scaler wierkt als Bréck tëscht KEDA an dem externe System, aus deem Metriken musse kritt ginn. ScaledObject ass eng personaliséiert Ressource déi agesat muss ginn fir den Deployment mat der Eventquell ze synchroniséieren, an dësem Fall Prometheus.

ScaledObject enthält Deployment-Skaléierungsinformatioun, Eventquell Metadaten (wéi Verbindungsgeheimnisser, Schlaangnumm), Pollingintervall, Erhuelungsperiod an aner Donnéeën. Et resultéiert an der entspriechender Autoscaling Ressource (HPA Definitioun) fir d'Deployment ze skaléieren.

Wann en Objet ScaledObject geläscht gëtt, gëtt déi entspriechend HPA Definitioun geläscht.

Hei ass d'Definitioun ScaledObject fir eist Beispill, et benotzt engem 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]))

Notéiert w.e.g. déi folgend Punkten:

  1. Hie weist op Deployment Mam Numm go-prom-app.
  2. Ausléiser Typ - Prometheus. D'Prometheus Server Adress gëtt zesumme mam metresche Numm, Schwell an PromQL Ufro, déi benotzt gëtt. PromQL Query - sum(rate(http_requests[2m])).
  3. Nëmmen pollingInterval,KEDA freet all fofzéng Sekonnen en Zil vum Prometheus. Op d'mannst een ënner (minReplicaCount), an d'maximal Unzuel u Pods ass net méi wéi maxReplicaCount (an dësem Beispill - zéng).

Kann installéiert ginn minReplicaCount gläich op null. An dësem Fall aktivéiert KEDA den Null-zu-een Deployment an exponéiert dann den HPA fir weider automatesch Skala. Déi ëmgedréint Uerdnung ass och méiglech, dat heescht d'Skaléierung vun engem op Null. Am Beispill hu mir net Null gewielt well dëst en HTTP-Service ass an net en On-Demand-System.

D'Magie bannen Autoscaling

D'Schwell gëtt als Ausléiser benotzt fir den Ofbau ze skaléieren. An eisem Beispill ass d'PromQL Ufro sum(rate (http_requests [2m])) gëtt den aggregéierten HTTP-Ufro Taux (Ufroen pro Sekonn) zréck, gemooss an de leschten zwou Minutten.

Well de Schwellwäert dräi ass, heescht et datt et een ënner gëtt wärend de Wäert sum(rate (http_requests [2m])) manner wéi dräi. Wann de Wäert eropgeet, gëtt all Kéier en zousätzleche Sub bäigefüügt sum(rate (http_requests [2m])) klëmmt ëm dräi. Zum Beispill, wann de Wäert vun 12 bis 14 ass, dann ass d'Zuel vun de Pods véier.

Loosst eis elo probéieren et opzestellen!

virzestellen

Alles wat Dir braucht ass e Kubernetes Cluster an e konfiguréiert Utility kubectl. Dëst Beispill benotzt e Cluster minikube, mee du kanns all aner huelen. Fir e Cluster z'installéieren gëtt et Leadership.

Installéiert déi lescht Versioun 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/

Installéieren kubectlZougang zum Kubernetes Cluster.

Installéiert déi lescht Versioun 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 Installatioun

Dir kënnt KEDA op verschidde Manéieren ofsetzen, si sinn opgelëscht Dokumentatioun. Ech benotzen monolithesch YAML:

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

KEDA a seng Komponenten ginn an den Nummraum installéiert keda. Kommando fir ze kontrolléieren:

kubectl get pods -n keda

Waart op de KEDA Bedreiwer fir unzefänken an ze goen Running State. An duerno weider.

Redis installéieren mat Helm

Wann Dir den Helm net installéiert hutt, benotzt dëst Féierung. Kommando fir op Mac z'installéieren:

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

helm init initialiséiert d'lokal Kommandozeil-Interface an installéiert och Tiller zum Kubernetes-Cluster.

kubectl get pods -n kube-system | grep tiller

Waart bis den Tiller Pod an de Running Staat erakënnt.

Iwwersetzer Notiz: Den Auteur benotzt Helm@2, wat erfuerdert datt den Tiller Server Komponent installéiert ass. Elo ass Helm@3 relevant, et erfuerdert keen Serverdeel.

Nodeems Dir Helm installéiert hutt, ass ee Kommando genuch fir Redis ze starten:

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

Vergewëssert Iech datt Redis erfollegräich ugefaang huet:

kubectl get pods/redis-server-master-0

Waart bis Redis an de Staat geet Running.

Applikatioun Deployment

Deployment Kommando:

kubectl apply -f go-app.yaml

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

Kontrolléiert datt alles ugefaang huet:

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

Waart op Redis fir an de Staat ze kommen Running.

Deploy e Prometheus Server

De Prometheus Manifest benotzt Kubernetes Service Discovery fir Prometheus. Et erlaabt dynamesch Entdeckung vun Applikatioun Pods baséiert op de Service Label.

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

Fir z'installéieren:

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

Kontrolléiert datt alles ugefaang huet:

kubectl get pods -l=app=prometheus-server

Waart bis de Prometheus an de Staat geet Running.

Benotzt kubectl port-forward Zougang zum Prometheus User Interface (oder API Server) op http://localhost:9090.

kubectl port-forward service/prometheus-service 9090

Deploy KEDA Autoscaling Configuration

Kommando ze schafen ScaledObject:

kubectl apply -f keda-prometheus-scaledobject.yaml

Kuckt d'KEDA Bedreiwer Logbicher:

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

D'Resultat gesäit sou eppes aus:

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"

Check ënnert Uwendungen. Eng Instanz muss lafen well minReplicaCount entsprécht 1:

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

Vergewëssert Iech datt d'HPA Ressource erfollegräich erstallt gouf:

kubectl get hpa

Dir sollt eppes gesinn wéi:

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

Gesondheet Check: Applikatioun Zougang

Fir Zougang zum REST Endpunkt vun eiser Applikatioun ze kréien, lafen:

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

Dir kënnt elo Zougang zu Ärer Go App mat der Adress benotzen http://localhost:8080. Fir dëst ze maachen, lafen de Kommando:

curl http://localhost:8080/test

D'Resultat gesäit sou eppes aus:

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

Op dësem Punkt och Redis kontrolléieren. Dir wäert gesinn, datt de Schlëssel access_count eropgaang op 1:

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

Vergewëssert Iech datt de metresche Wäert ass http_requests datselwecht:

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

Lueden Créatioun

Mir wäerte benotzen hey - Utility fir Belaaschtung ze generéieren:

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

Dir kënnt och den Utility eroflueden fir Linux oder Windows.

Run et:

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

Par défaut schéckt d'Utility 200 Ufroen. Dir kënnt dëst verifizéieren mat Prometheus Metriken souwé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

Validéiert de Wäert vun der aktueller Metrik (zréckkomm vun der PromQL Ufro):

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

An dësem Fall ass dat richtegt Resultat 1,686057971014493 a gëtt am Feld ugewisen value. Dëst ass net genuch fir ze skaléieren, well d'Schwell déi mir setzen ass 3.

Méi Laascht!

Am neie Terminal, iwwerwaacht d'Zuel vun den Applikatioun Pods:

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

Loosst eis d'Laascht erhéijen mam Kommando:

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

No enger Zäit gesitt Dir HPA d'Deployment skaléieren an nei Pods lancéieren. Kuckt Ären HPA fir sécher ze sinn:

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

Wann d'Laascht inkonsistent ass, gëtt d'Deployment reduzéiert op de Punkt wou nëmmen ee Pod leeft. Wann Dir déi aktuell Metrik wëllt iwwerpréiwen (zréckkomm vun der PromQL Ufro), da benotzt de Kommando:

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

Botzen

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

Konklusioun

KEDA erlaabt Iech automatesch Är Kubernetes-Deployementer (op / vun Null) op Basis vun Daten aus externe Metriken ze skaléieren. Zum Beispill, baséiert op Prometheus Metriken, Schlaanglängt am Redis, Konsumentelatenz am Kafka Thema.

KEDA integréiert mat enger externer Quell a liwwert och seng Metriken duerch Metrics Server op Horizontal Pod Autoscaler.

Vill Gléck!

Wat soss ze liesen:

  1. Best Practices and Best Practices for Running Containers and Kubernetes in Production Environments.
  2. 90+ Nëtzlech Tools fir Kubernetes: Deployment, Management, Monitoring, Security and More.
  3. Eise Kanal Around Kubernetes am Telegram.

Source: will.com

Setzt e Commentaire