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

Köp pĂ„litlig hosting för webbplatser med DDoS-skydd, VPS VDS-servrar đŸ”„ Köp pĂ„litlig webbhotell med DDoS-skydd, VPS VDS-servrar | ProHoster