Autoskalerade Kubernetes-appar med hjÀlp av Prometheus och KEDA

Autoskalerade Kubernetes-appar med hjÀlp av Prometheus och KEDABalloon Man av Cimuanos

Skalbarhet Ă€r ett centralt krav för molnapplikationer. Med Kubernetes Ă€r det lika enkelt att skala upp en applikation som att öka antalet repliker för en specifik distribution eller ReplicaSet — men det Ă€r en manuell process.

Kubernetes gör det möjligt att automatiskt skala applikationer (det vill sÀga Pod i distribution eller ReplicaSet) pÄ ett deklarativt sÀtt med hjÀlp av specifikationen för Horizontal Pod Autoscaler. Som standard Àr kriteriet för automatisk skalning resursanvÀndningens CPU-metrik (resursmetrik), men det gÄr att integrera anpassade metrikvÀrden och metrikvÀrden som tillhandahÄlls extern.

Team Kubernetes aaS frÄn Mail.ru översatte en artikel om hur man anvÀnder externa metrier för automatisk skalning av Kubernetes-applikationer. För att visa hur allt fungerar anvÀnder författaren metrikvÀrden för HTTP-Ätkomst, som samlas in med hjÀlp av Prometheus.

IstĂ€llet för horisontell automatisk skalning av poddar anvĂ€nds Kubernetes Event Driven Autoscaling (KEDA) — en öppen kĂ€llkodskontrollant för Kubernetes. Den Ă€r ursprungligen integrerad med Horizontal Pod Autoscaler för att sĂ€kerstĂ€lla smidig automatisk skalning (inklusive till/frĂ„n noll) för hĂ€ndelsedrivna arbetsbelastningar. Koden finns tillgĂ€nglig pĂ„ GitHub.

En kort översikt av systemets arbete

Autoskalerade Kubernetes-appar med hjÀlp av Prometheus och KEDA

Diagrammet visar en kort beskrivning av hur allt fungerar:

  1. Applikationen tillhandahÄller metrik för antal HTTP-förfrÄgningar i Prometheus-format.
  2. Prometheus Àr konfigurerat för att samla in dessa mÀtvÀrden.
  3. Prometheus-skalan i KEDA Àr instÀlld pÄ att automatiskt skala applikationen baserat pÄ antalet HTTP-förfrÄgningar.

Nu kommer jag att gÄ in mer i detalj om varje element.

KEDA och Prometheus

Prometheus Àr en uppsÀttning verktyg för övervakning och varning av system med öppen kÀllkod, en del av Cloud Native Computing Foundation. Samlar in mÀtvÀrden frÄn olika kÀllor och lagrar dem i form av tidsserie-data. För att visualisera data kan man anvÀnda Grafana eller andra visualiseringsverktyg som arbetar med Kubernetes API.

KEDA stöder konceptet av en skalar — den fungerar som en bro mellan KEDA och ett externt system. Implementeringen av skalaren Ă€r specifik för varje mĂ„lsystem och hĂ€mtar data frĂ„n det. DĂ€refter anvĂ€nder KEDA dessa data för att hantera automatisk skalning.

Skalare stöder flera datakÀllor, som Kafka, Redis, Prometheus. Det innebÀr att KEDA kan anvÀndas för automatisk skalning av Kubernetes-distributioner, med Prometheus-metrik som kriterier.

Testapplikation

Det testbaserade Golang-applikationen erbjuder Ätkomst via HTTP och utför tvÄ viktiga funktioner:

  1. AnvÀnder klientbiblioteket Prometheus Go för att instrumentera applikationen och erbjuda metrik http_requests, som innehÄller en rÀknare för anrop. Den slutpunkt dÀr Prometheus-metrik Àr tillgÀnglig finns pÄ URI /metrics.
    var httpRequestsCounter = promauto.NewCounter(prometheus.CounterOpts{
           Name: "http_requests",
           Help: "antal http-anrop",
       })
    
  2. Som svar pÄ förfrÄgan GET applikationen ökar vÀrdet av nyckeln (access_count) i Redis. Detta Àr ett enkelt sÀtt att utföra jobbet som en del av HTTP-hanteraren, samt kontrollera Prometheus-metriken. VÀrdet av metrik ska vara samma 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("Kunde inte öka redis-rÀknaren", err)
                   os.Exit(1)
               }
               resp := "Åtkomstdatum " + time.Now().String() + "nÅtkomstantal " + strconv.Itoa(int(count))
               w.Write([]byte(resp))
           })
           http.ListenAndServe(":8080", nil)
       }
    

Applikationen distribueras i Kubernetes genom Deployment. En tjÀnst skapas ocksÄ ClusterIP, som möjliggör för Prometheus-servern att ta emot applikationsmetrik.

HÀr Àr distributionsmanifestet för applikationen.

Prometheus-server

Distributionsmanifestet för Prometheus bestÄr av:

  • ConfigMap — för att överföra Prometheus-konfigurationen;
  • Deployment — för att distribuera Prometheus i Kubernetes-klustret;
  • ClusterIP — en tjĂ€nst för att fĂ„ Ă„tkomst till Prometheus UI;
  • ClusterRole, ClusterRoleBinding och ServiceAccount — för att möjliggöra automatisk upptĂ€ckte av tjĂ€nster i Kubernetes (Auto-discovery).

HÀr Àr manifestet för att köra Prometheus.

KEDA Prometheus ScaledObject

Skalaren fungerar som en bro mellan KEDA och det externa systemet dĂ€r metrik behöver samlas in. ScaledObject — en konfigurerbar resurs, som mĂ„ste distribueras för att synkronisera distributionen med hĂ€ndelsekĂ€llan, i detta fall Prometheus.

ScaledObject innehÄller information om att skala distributionen, metadata om hÀndelsekÀllan (till exempel hemligheter för anslutning, namn pÄ kön), intervall för avkall, ÄterstÀllningsperiod och annan data. Det leder till den relevanta resursen för automatisk skalning (HPA-definition) för att skala distributionen.

NĂ€r objektet ScaledObject raderas, den motsvarande HPA-definitionen rensas.

HÀr Àr en definition ScaledObject för vÄrt exempel, dÀr en skalerare anvÀnds 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]))

TÀnk pÄ följande punkter:

  1. Den pekar pÄ Deployment med namnet go-prom-app.
  2. Typ av trigger Àr Prometheus. Serveradress för Prometheus nÀmns tillsammans med metriknamnet, tröskelvÀrdet och PromQL-frÄgan, som kommer att anvÀndas. PromQL-frÄgan Àr sum(rate(http_requests[2m])).
  3. Enligt pollingInterval, KEDA frÄgar mÄlet hos Prometheus var femtonde sekund. Det stöds minst en podd (minReplicaCount), och det maximala antalet poddar överstiger inte maxReplicaCount i detta exempel - tio.

Du kan stÀlla in minReplicaCount till noll. I det hÀr fallet aktiverar KEDA distributionen frÄn noll till en och ger sedan HPA för vidare automatisk skalning. OmvÀnd ordning Àr Àven möjlig, det vill sÀga scaling frÄn en till noll. I exemplet har vi inte valt noll, eftersom detta Àr en HTTP-tjÀnst och inte en systembegÀran.

Magin bakom autoskalning

TröskelvÀrdet anvÀnds som en trigger för att skala distributionen. I vÄrt exempel ger PromQL-frÄgan sum(rate (http_requests [2m])) ett aggregerat vÀrde för hastigheten pÄ HTTP-förfrÄgningar (antal förfrÄgningar per sekund), vilket mÀts under de senaste tvÄ minuterna.

Eftersom tröskelvÀrdet Àr tre kommer det att finnas en podd sÄ lÀnge vÀrdet sum(rate (http_requests [2m])) Àr mindre Àn tre. Om vÀrdet istÀllet ökar, lÀggs en ytterligare podd till varje gÄng sum(rate (http_requests [2m])) det ökar med tre. Till exempel, om vÀrdet gÄr frÄn 12 till 14, kommer antalet poddar vara fyra.

Nu lÄt oss försöka konfigurera!

FörinstÀllning

Allt du behöver Àr en Kubernetes-kluster och ett konfigurerat verktyg kubectl. I detta exempel anvÀnds klustret minikube, men du kan anvÀnda nÄgot annat. För installation av klustret finns det en guide.

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/

Installera kubectl, för att fÄ tillgÄng till 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

Installation av KEDA

Du kan distribuera KEDA pÄ flera sÀtt, som listas i dokumentationen. Jag anvÀnder en monolitisk YAML:

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

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

kubectl get pods -n keda

VĂ€nta tills KEDA Operator-podden startar — gĂ„r över till Running State. Och fortsĂ€tt sedan.

Installation av Redis med Helm

Om du inte har Helm installerat, anvÀnd den hÀr guiden. Kommandot för installation pÄ Mac:

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

helm init initialiserar det lokala kommandogrÀnssnittet och installerar Tiller i Kubernetes-klustret.

kubectl get pods -n kube-system | grep tiller

VÀnta tills Tiller-podden gÄr till status Running.

ÖversĂ€ttarens kommentar: Författaren anvĂ€nder Helm@2, vilket krĂ€ver installation av serverkomponenten Tiller. Just nu Ă€r Helm@3 aktuellt, för den behövs ingen serverdel.

Efter installationen av Helm behövs endast ett kommando för att starta Redis:

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

Kontrollera att Redis har startat framgÄngsrikt:

kubectl get pods/redis-server-master-0

VÀnta tills Redis-podden gÄr till status Running.

Distribution av applikation

Kommandot för distribution:

kubectl apply -f go-app.yaml

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

Kontrollera att allt har startat:

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

VÀnta tills Redis gÄr till status Running.

Distribution av Prometheus-servern

Manifestet för Prometheus anvÀnder Kubernetes Service Discovery för Prometheus. Den gör det möjligt att dynamiskt upptÀcka applikationspoddar baserat pÄ tjÀnstetiketten.

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

För distribution:

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 startat:

kubectl get pods -l=app=prometheus-server

VÀnta tills Prometheus-podden gÄr till status Running.

AnvÀnd kubectl port-forward för att fÄ Ätkomst till anvÀndargrÀnssnittet för Prometheus (eller API-servern) pÄ adressen http://localhost:9090.

kubectl port-forward service/prometheus-service 9090

Distribution av KEDA:s automatiska skalningskonfiguration

Kommandot för att skapa ScaledObject:

kubectl apply -f keda-prometheus-scaledobject.yaml

Kontrollera KEDA-operatorns loggar:

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"

Kontrollera appens poddar. Det bör finnas en instans som Àr igÄng, eftersom minReplicaCount lika med 1:

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

Kontrollera att HPA-resursen har skapats framgÄngsrikt:

kubectl get hpa

Du bör se nÄgot som liknar:

NAMN                   REFERENS                MÅL     MINPADS   MAXPADS   REPLIKER   ÅLDER
keda-hpa-go-prom-app   Deployment/go-prom-app   0/3 (genomsnitt)   1         10        1          45s

Kontroll av funktionalitet: tillgÄng till applikationen

För att fÄ Ätkomst till REST-endpointen för vÄr applikation, kör:

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

Nu kan du fÄ Ätkomst till Go-applikationen via adressen http://localhost:8080. För detta, kör kommandot:

curl http://localhost:8080/test

Resultatet ser ut ungefÀr sÄ hÀr:

Åtkommet den 2019-10-21 11:29:10.560385986 +0000 UTC 
m=+406004.817901246
Åtkomstantal 1

Vid detta steg bör du ocksÄ kontrollera 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 metrisvÀrdet http_requests Àr detsamma:

curl http://localhost:8080/metrics | grep http_requests
//output
# HELP http_requests antal http-förfrÄgningar
# TYPE http_requests counter
http_requests 1

Skapa belastning

Vi kommer att anvĂ€nda hey — ett verktyg för att generera belastning:

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 kontrollera detta med hjÀlp av Prometheus-metrik samt Redis.

curl http://localhost:8080/metrics | grep http_requests
//output
# HELP http_requests antal http-förfrÄgningar
# TYPE http_requests counter
http_requests 201
kubectl exec -it redis-server-master-0 -- redis-cli get access_count
//output
201

BekrÀfta det faktiska metrisvÀrdet (returnerat av PromQL-förfrÄ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 det hÀr fallet Àr det faktiska resultatet 1,686057971014493 och visas i fÀltet value. Detta Àr inte tillrÀckligt för att skala, eftersom den tröskel vi har stÀllt in Àr 3.

Mer belastning!

I ett nytt terminalfönster, hÄll koll pÄ antalet poddar för applikationen:

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

LÄt oss öka belastningen med kommandot:

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

Efter en tid kommer du att se att HPA skalar distributionen och startar nya poddar. Kontrollera HPA för att bekrÀfta detta:

kubectl get hpa
NAMN                   REFERENS                MÅL         MINPODS   MAXPODS   REPLIKER   ÅLDER
keda-hpa-go-prom-app   Distribution/go-prom-app   1830m/3 (genomsnitt)   1         10        6          4m22s

Om belastningen Àr variabel minskar distributionen till en punkt dÀr endast en podd körs. Om du vill kontrollera den faktiska metrik (som returneras av PromQL-förfrÄgan) anvÀnd kommandot:

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

Rensa

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

KEDA möjliggör automatisk skalning av dina Kubernetes-distributioner (till/frÄn noll) baserat pÄ data frÄn externa metrik. Till exempel baserat pÄ Prometheus-metrik, kölÀngd i Redis, eller förseningar för konsumenten i Kafka-Àmnet.

KEDA utför integration med en extern kÀlla och tillhandahÄller Àven dess metrik via Metrics Server för Horizontal Pod Autoscaler.

Lycka till!

Vad mer att lÀsa:

  1. BÀsta praxis och rekommendationer för att köra containrar och Kubernetes i produktionsmiljöer.
  2. 90+ anvÀndbara verktyg för Kubernetes: distribution, hantering, övervakning, sÀkerhet och mer.
  3. VÄr kanal Om Kubernetes pÄ Telegram.

KĂ€lla: habr.com

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