Autoskalning av Kubernetes-applikationer med Prometheus och KEDA

Autoskalning av Kubernetes-applikationer med Prometheus och KEDABalloon Man av Cimuanos

Skalbarhet är ett nyckelkrav för molnapplikationer. Med Kubernetes är det lika enkelt att skala ett program som att öka antalet repliker för lämplig distribution eller ReplicaSet – men det är en manuell process.

Kubernetes tillåter att applikationer skalas automatiskt (d.v.s. Pods i en distribution eller ReplicaSet) på ett deklarativt sätt med hjälp av Horizontal Pod Autoscaler-specifikationen. Standardkriteriet för automatisk skalning är CPU-användningsmått (resursmått), men du kan integrera anpassade och externt tillhandahållna mätvärden.

Team Kubernetes aaS från Mail.ru översatt en artikel om hur man använder externa mätvärden för att automatiskt skala en Kubernetes-applikation. För att visa hur allt fungerar använder författaren HTTP-åtkomstbegäranmätningar, som samlas in med Prometheus.

Istället för horisontell autoskalning av poddar används Kubernetes Event Driven Autoscaling (KEDA), en Kubernetes-operatör med öppen källkod. Den integreras naturligt med Horizontal Pod Autoscaler för att ge sömlös autoskalning (inklusive till/från noll) för händelsedrivna arbetsbelastningar. Koden finns på GitHub.

Kort översikt över systemet

Autoskalning av Kubernetes-applikationer med Prometheus och KEDA

Diagrammet visar en kort beskrivning av hur allt fungerar:

  1. Applikationen tillhandahåller HTTP-träffräkningsstatistik i Prometheus-format.
  2. Prometheus är konfigurerad att samla in dessa mätvärden.
  3. Prometheus scaler i KEDA är konfigurerad att automatiskt skala applikationen baserat på antalet HTTP-träffar.

Nu kommer jag att berätta i detalj om varje element.

KEDA och Prometheus

Prometheus är ett verktyg för övervakning och varning av öppen källkod, del Cloud Native Computing Foundation. Samlar in mätvärden från olika källor och lagrar dem som tidsseriedata. För att visualisera data kan du använda grafana eller andra visualiseringsverktyg som fungerar med Kubernetes API.

KEDA stöder konceptet med en skalare - den fungerar som en brygga mellan KEDA och det externa systemet. Implementeringen av skalare är specifik för varje målsystem och extraherar data från det. KEDA använder dem sedan för att styra automatisk skalning.

Skalare stöder flera datakällor, till exempel Kafka, Redis, Prometheus. Det vill säga, KEDA kan användas för att automatiskt skala Kubernetes-distributioner med hjälp av Prometheus-mått som kriterier.

Testapplikation

Golang-testapplikationen ger åtkomst via HTTP och utför två viktiga funktioner:

  1. Använder Prometheus Go-klientbiblioteket för att instrumentera applikationen och tillhandahålla http_requests-måttet, som innehåller ett antal träffar. Slutpunkten där Prometheus-mätvärden är tillgänglig finns på URI:n /metrics.
    var httpRequestsCounter = promauto.NewCounter(prometheus.CounterOpts{
           Name: "http_requests",
           Help: "number of http requests",
       })
    
  2. Som svar på en förfrågan GET applikationen ökar värdet på nyckeln (access_count) i Redis. Det här är ett enkelt sätt att utföra arbetet som en del av en HTTP-hanterare och även kontrollera Prometheus-mått. Det metriska värdet måste vara detsamma som värdet 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 distribueras till Kubernetes via Deployment. En tjänst skapas också ClusterIP, gör det att Prometheus-servern kan få applikationsstatistik.

Här implementeringsmanifest för applikationen.

Prometheus server

Prometheus-implementeringsmanifestet består av:

  • ConfigMap — att överföra Prometheus-konfigurationen;
  • Deployment — för att distribuera Prometheus i ett Kubernetes-kluster;
  • ClusterIP — tjänst för åtkomst till UI Prometheus;
  • ClusterRole, ClusterRoleBinding и ServiceAccount — för automatisk upptäckt av tjänster i Kubernetes (Auto-discovery).

Här manifest för att köra Prometheus.

KEDA Prometheus ScaledObject

Skalaren fungerar som en brygga mellan KEDA och det externa systemet från vilket mätvärden måste erhållas. ScaledObject är en anpassad resurs som måste distribueras för att synkronisera distributionen med händelsekällan, i det här fallet Prometheus.

ScaledObject innehåller distributionsskalningsinformation, metadata för händelsekälla (som anslutningshemligheter, könamn), pollingintervall, återställningsperiod och annan data. Det resulterar i motsvarande autoskalningsresurs (HPA-definition) för att skala distributionen.

När ett föremål ScaledObject tas bort, raderas motsvarande HPA-definition.

Här är definitionen ScaledObject för vårt exempel använder den en skalare 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]))

Observera följande punkter:

  1. Han pekar på Deployment Med namn go-prom-app.
  2. Triggertyp - Prometheus. Prometheus-serveradressen nämns tillsammans med metriskt namn, tröskelvärde och PromQL-fråga, som kommer att användas. PromQL-fråga - sum(rate(http_requests[2m])).
  3. Enligt pollingInterval,KEDA begär ett mål från Prometheus var femtonde sekund. Minst en under (minReplicaCount), och det maximala antalet kapslar inte överstiger maxReplicaCount (i detta exempel - tio).

Kan installeras minReplicaCount lika med noll. I det här fallet aktiverar KEDA noll-till-ett-distributionen och exponerar sedan HPA för ytterligare automatisk skalning. Den omvända ordningen är också möjlig, det vill säga skalning från ett till noll. I exemplet valde vi inte noll eftersom detta är en HTTP-tjänst och inte ett on-demand-system.

Magin inuti autoskalning

Tröskeln används som en utlösare för att skala distributionen. I vårt exempel är PromQL-frågan sum(rate (http_requests [2m])) returnerar den aggregerade HTTP-förfrågningsfrekvensen (förfrågningar per sekund), mätt under de senaste två minuterna.

Eftersom tröskelvärdet är tre betyder det att det kommer att vara en under medan värdet sum(rate (http_requests [2m])) mindre än tre. Om värdet ökar läggs ytterligare en sub till varje gång sum(rate (http_requests [2m])) ökar med tre. Till exempel, om värdet är från 12 till 14, då är antalet pods fyra.

Nu ska vi försöka ställa in det!

förinställning

Allt du behöver är ett Kubernetes-kluster och ett konfigurerat verktyg kubectl. Det här exemplet använder ett kluster minikube, men du kan ta vilken annan som helst. För att installera ett kluster finns det ledning.

Installera den senaste versionen 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/

Ställ kubectlför att komma åt Kubernetes-klustret.

Installera den senaste versionen 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 distribuera KEDA på flera sätt, de är listade i dokumentation. Jag använder monolitisk YAML:

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

KEDA och dess komponenter installeras i namnutrymmet keda. Kommando för att kontrollera:

kubectl get pods -n keda

Vänta på att KEDA-operatören startar och går till Running State. Och efter det, fortsätt.

Installera Redis med hjälp av Helm

Om du inte har Helm installerat, använd detta ledarskap. Kommando för att installera på Mac:

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

helm init initierar det lokala kommandoradsgränssnittet och installerar även Tiller till Kubernetes-klustret.

kubectl get pods -n kube-system | grep tiller

Vänta tills Tiller-podden går in i körläge.

Översättarens anteckning: Författaren använder Helm@2, vilket kräver att Tiller-serverkomponenten är installerad. Nu är Helm@3 aktuellt, det kräver ingen serverdel.

Efter installation av Helm räcker ett kommando för att starta Redis:

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

Verifiera att Redis har startat framgångsrikt:

kubectl get pods/redis-server-master-0

Vänta tills Redis går in i staten Running.

Applikationsdistribution

Implementeringskommando:

kubectl apply -f go-app.yaml

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

Kontrollera att allt har börjat:

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

Vänta tills Redis går in i tillståndet Running.

Installera en Prometheus-server

Prometheus manifest använder Kubernetes Service Discovery för Prometheus. Det möjliggör dynamisk upptäckt av applikationsmoduler baserat på tjänsteetiketten.

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

Så här distribuerar du:

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

Kontrollera att allt har börjat:

kubectl get pods -l=app=prometheus-server

Vänta tills Prometheus går in i staten Running.

användning kubectl port-forward för att komma åt Prometheus användargränssnitt (eller API-server) på http://localhost:9090.

kubectl port-forward service/prometheus-service 9090

Installera KEDA Autoscaling Configuration

Kommando för att skapa ScaledObject:

kubectl apply -f keda-prometheus-scaledobject.yaml

Kontrollera KEDA-operatörsloggarna:

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

Resultatet ser ut ungefär så här:

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"

Kolla under ansökningar. En instans måste vara igång pga minReplicaCount är lika med 1:

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

Verifiera att HPA-resursen skapades framgångsrikt:

kubectl get hpa

Du borde se något i stil med:

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

Hälsokontroll: applikationsåtkomst

För att komma åt vår applikations REST-slutpunkt, kör:

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

Du kan nu komma åt din Go-app med adressen http://localhost:8080. För att göra detta, kör kommandot:

curl http://localhost:8080/test

Resultatet ser ut ungefär så här:

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

Vid denna tidpunkt kontrollera även Redis. Du kommer att se att nyckeln access_count ökat till 1:

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

Se till att det metriska värdet är http_requests det samma:

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

Lastskapande

Vi kommer använda hallå — verktyg för att generera last:

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

Du kan också ladda ner verktyget för Linux eller Windows.

Kör det:

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

Som standard skickar verktyget 200 förfrågningar. Du kan verifiera detta med hjälp av Prometheus-mått såväl 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

Validera värdet på det faktiska måttet (returneras av PromQL-frågan):

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 detta fall är det faktiska resultatet 1,686057971014493 och visas i fältet value. Detta räcker inte för skalning, eftersom tröskeln vi anger är 3.

Mer belastning!

I den nya terminalen, övervaka antalet applikationsenheter:

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

Låt oss öka belastningen med kommandot:

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

Efter ett tag kommer du att se HPA skala driftsättningen och lansera nya poddar. Kontrollera din HPA för att säkerställa att:

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

Om belastningen är inkonsekvent kommer driftsättningen att reduceras till den punkt där endast en pod körs. Om du vill kontrollera det faktiska måttet (returneras av PromQL-frågan), använd sedan kommandot:

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

rengöring

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

Slutsats

Med KEDA kan du automatiskt skala dina Kubernetes-distributioner (till/från noll) baserat på data från externa mätvärden. Till exempel baserat på Prometheus-mått, kölängd i Redis, konsumentlatens i Kafka-ämnet.

KEDA integreras med en extern källa och tillhandahåller även dess mätvärden via Metrics Server till Horizontal Pod Autoscaler.

Lycka!

Vad mer att läsa:

  1. Bästa praxis och bästa praxis för att köra containrar och Kubernetes i produktionsmiljöer.
  2. Över 90 användbara verktyg för Kubernetes: distribution, hantering, övervakning, säkerhet och mer.
  3. Vår kanal Around Kubernetes i Telegram.

Källa: will.com

Lägg en kommentar