Automatisch schalen van Kubernetes-applicaties met Prometheus en KEDA

Automatisch schalen van Kubernetes-applicaties met Prometheus en KEDABallonman van Cimuanos

Schaalbaarheid is een belangrijke vereiste voor cloudapplicaties. Met Kubernetes is het schalen van een applicatie net zo eenvoudig als het verhogen van het aantal replica's voor de juiste implementatie ReplicaSet – maar het is een handmatig proces.

Met Kubernetes kunnen applicaties automatisch worden geschaald (d.w.z. Pods in een implementatie of ReplicaSet) op een declaratieve manier met behulp van de Horizontal Pod Autoscaler-specificatie. Het standaardcriterium voor automatisch schalen zijn CPU-gebruiksstatistieken (resourcestatistieken), maar u kunt aangepaste en extern verstrekte statistieken integreren.

Team Kubernetes aaS van Mail.ru een artikel vertaald over hoe je externe statistieken kunt gebruiken om een ​​Kubernetes-applicatie automatisch te schalen. Om te laten zien hoe alles werkt, gebruikt de auteur HTTP-toegangsverzoekstatistieken, die worden verzameld met behulp van Prometheus.

In plaats van horizontaal automatisch schalen van pods wordt Kubernetes Event Driven Autoscaling (KEDA) gebruikt, een open source Kubernetes-operator. Het integreert native met Horizontal Pod Autoscaler om naadloos automatisch schalen (inclusief van/naar nul) te bieden voor gebeurtenisgestuurde workloads. Code verkrijgbaar bij GitHub.

Kort overzicht van de werking van het systeem

Automatisch schalen van Kubernetes-applicaties met Prometheus en KEDA

Het diagram toont een korte beschrijving van hoe alles werkt:

  1. De applicatie biedt statistieken over het aantal HTTP-hits in Prometheus-indeling.
  2. Prometheus is geconfigureerd om deze statistieken te verzamelen.
  3. De Prometheus-scaler in KEDA is geconfigureerd om de applicatie automatisch te schalen op basis van het aantal HTTP-hits.

Nu zal ik je in detail over elk element vertellen.

KEDA en Prometheus

Prometheus is een open source systeemmonitoring- en waarschuwingstoolkit, onderdeel Stichting Cloud Native Computing. Verzamelt statistieken uit verschillende bronnen en slaat deze op als tijdreeksgegevens. Om gegevens te visualiseren die u kunt gebruiken grafana of andere visualisatietools die werken met de Kubernetes API.

KEDA ondersteunt het concept van een scaler: het fungeert als brug tussen KEDA en het externe systeem. De scaler-implementatie is specifiek voor elk doelsysteem en extraheert er gegevens uit. KEDA gebruikt ze vervolgens om de automatische schaling te regelen.

Scalers ondersteunen meerdere gegevensbronnen, bijvoorbeeld Kafka, Redis, Prometheus. Dat wil zeggen dat KEDA kan worden gebruikt om Kubernetes-implementaties automatisch te schalen met behulp van Prometheus-statistieken als criteria.

Testtoepassing

De Golang-testapplicatie biedt toegang via HTTP en vervult twee belangrijke functies:

  1. Maakt gebruik van de Prometheus Go-clientbibliotheek om de applicatie te instrumenteren en de http_requests-statistiek te leveren, die een aantal hits bevat. Het eindpunt waar Prometheus-statistieken beschikbaar zijn, bevindt zich op de URI /metrics.
    var httpRequestsCounter = promauto.NewCounter(prometheus.CounterOpts{
           Name: "http_requests",
           Help: "number of http requests",
       })
    
  2. Als reactie op een verzoek GET de toepassing verhoogt de waarde van de sleutel (access_count) in Redis. Dit is een eenvoudige manier om het werk uit te voeren als onderdeel van een HTTP-handler en ook de Prometheus-statistieken te controleren. De metrische waarde moet hetzelfde zijn als de waarde access_count in 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 applicatie wordt via Kubernetes geïmplementeerd Deployment. Er wordt ook een dienst gecreëerd ClusterIP, stelt het de Prometheus-server in staat applicatiestatistieken te verkrijgen.

Hier implementatiemanifest voor de toepassing.

Prometheus-server

Het Prometheus-implementatiemanifest bestaat uit:

  • ConfigMap — om de Prometheus-configuratie over te dragen;
  • Deployment — voor het inzetten van Prometheus in een Kubernetes-cluster;
  • ClusterIP — dienst voor toegang tot UI Prometheus;
  • ClusterRole, ClusterRoleBinding и ServiceAccount — voor automatische detectie van services in Kubernetes (Auto-discovery).

Hier manifest voor het runnen van Prometheus.

KEDA Prometheus ScaledObject

De scaler fungeert als brug tussen KEDA en het externe systeem waaruit de statistieken moeten worden verkregen. ScaledObject is een aangepaste bron die moet worden geïmplementeerd om de implementatie te synchroniseren met de gebeurtenisbron, in dit geval Prometheus.

ScaledObject bevat informatie over de implementatieschaal, metagegevens van de gebeurtenisbron (zoals verbindingsgeheimen, wachtrijnaam), pollinginterval, herstelperiode en andere gegevens. Het resulteert in de overeenkomstige bron voor automatisch schalen (HPA-definitie) om de implementatie te schalen.

Wanneer een voorwerp ScaledObject wordt verwijderd, wordt de overeenkomstige HPA-definitie gewist.

Hier is de definitie ScaledObject in ons voorbeeld wordt een scaler gebruikt 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 volgende punten:

  1. Hij wijst naar Deployment Met naam go-prom-app.
  2. Triggertype - Prometheus. Het Prometheus-serveradres wordt vermeld samen met de metrische naam, drempelwaarde en PromQL-query, die zal worden gebruikt. PromQL-query - sum(rate(http_requests[2m])).
  3. Volgens pollingInterval,KEDA vraagt ​​Prometheus elke vijftien seconden om een ​​doelwit. Minstens één onder (minReplicaCount), en het maximale aantal pods is niet groter dan maxReplicaCount (in dit voorbeeld - tien).

Kan worden geïnstalleerd minReplicaCount gelijk aan nul. In dit geval activeert KEDA de nul-op-één-implementatie en stelt vervolgens de HPA bloot voor verdere automatische schaalvergroting. De omgekeerde volgorde is ook mogelijk, dat wil zeggen: opschalen van één naar nul. In het voorbeeld hebben we niet nul geselecteerd, omdat dit een HTTP-service is en geen on-demand-systeem.

De magie van automatisch schalen

De drempelwaarde wordt gebruikt als trigger om de implementatie te schalen. In ons voorbeeld de PromQL-query sum(rate (http_requests [2m])) retourneert de verzamelde HTTP-verzoeksnelheid (verzoeken per seconde), gemeten over de afgelopen twee minuten.

Omdat de drempelwaarde drie is, betekent dit dat er één onder de waarde ligt sum(rate (http_requests [2m])) minder dan drie. Als de waarde stijgt, wordt er telkens een extra sub toegevoegd sum(rate (http_requests [2m])) met drie toeneemt. Als de waarde bijvoorbeeld tussen 12 en 14 ligt, is het aantal peulen vier.

Laten we het nu proberen in te stellen!

Voorinstelling

Het enige dat u nodig hebt, is een Kubernetes-cluster en een geconfigureerd hulpprogramma kubectl. In dit voorbeeld wordt een cluster gebruikt minikube, maar je kunt elke andere nemen. Om een ​​cluster te installeren is er руководство.

Installeer de nieuwste versie 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/

Ingesteld kubectlom toegang te krijgen tot het Kubernetes-cluster.

Installeer de nieuwste versie 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-installatie

U kunt KEDA op verschillende manieren inzetten, ze staan ​​vermeld in documentatie. Ik gebruik monolithische YAML:

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

KEDA en zijn componenten worden in de naamruimte geïnstalleerd keda. Commando om te controleren:

kubectl get pods -n keda

Wacht tot KEDA Operator start en ga naar Running State. En ga daarna verder.

Redis installeren met Helm

Als u Helm niet hebt geïnstalleerd, gebruikt u dit leiderschap. Commando om op Mac te installeren:

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

helm init initialiseert de lokale opdrachtregelinterface en installeert ook Tiller naar het Kubernetes-cluster.

kubectl get pods -n kube-system | grep tiller

Wacht tot de Tiller-pod de status Actief heeft bereikt.

Noot van de vertaler: De auteur gebruikt Helm@2, waarvoor de Tiller-servercomponent moet worden geïnstalleerd. Nu is Helm@3 relevant, er is geen servergedeelte voor nodig.

Na het installeren van Helm is één commando voldoende om Redis te starten:

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

Controleer of Redis succesvol is gestart:

kubectl get pods/redis-server-master-0

Wacht tot Redis in de staat gaat Running.

Applicatie-implementatie

Implementatieopdracht:

kubectl apply -f go-app.yaml

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

Controleer of alles is gestart:

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

Wacht tot Redis de status heeft bereikt Running.

Een Prometheus-server implementeren

Het Prometheus-manifest gebruikt Kubernetes Service Discovery voor Prometheus. Het maakt dynamische detectie van applicatie-pods mogelijk op basis van het servicelabel.

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

Implementeren:

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

Controleer of alles is gestart:

kubectl get pods -l=app=prometheus-server

Wacht tot Prometheus de staat betreedt Running.

Gebruiken kubectl port-forward om toegang te krijgen tot de Prometheus-gebruikersinterface (of API-server) op http://localhost:9090.

kubectl port-forward service/prometheus-service 9090

Implementatie van KEDA-configuratie voor automatisch schalen

Commando om te creëren ScaledObject:

kubectl apply -f keda-prometheus-scaledobject.yaml

Controleer de KEDA-operatorlogboeken:

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

Het resultaat ziet er ongeveer zo uit:

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"

Kijk onder toepassingen. Er moet één exemplaar actief zijn omdat minReplicaCount gelijk aan 1:

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

Controleer of de HPA-bron met succes is gemaakt:

kubectl get hpa

Je zou zoiets moeten zien als:

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

Gezondheidscontrole: toegang tot applicaties

Voer het volgende uit om toegang te krijgen tot het REST-eindpunt van onze applicatie:

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

Je hebt nu toegang tot je Go-app via het adres http://localhost:8080. Om dit te doen, voert u de opdracht uit:

curl http://localhost:8080/test

Het resultaat ziet er ongeveer zo uit:

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

Controleer op dit punt ook Redis. Je zult zien dat de sleutel access_count verhoogd naar 1:

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

Zorg ervoor dat de metrische waarde is http_requests hetzelfde:

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

Laad creatie

We zullen gebruiken he — hulpprogramma voor het genereren van belasting:

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

U kunt het hulpprogramma ook downloaden voor Linux of Dakramen en raamkozijnen.

Voer het uit:

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

Standaard verzendt het hulpprogramma 200 verzoeken. U kunt dit verifiëren met behulp van Prometheus-statistieken en 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

Valideer de waarde van de werkelijke metriek (geretourneerd door 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"]}]}}

In dit geval is het daadwerkelijke resultaat 1,686057971014493 en wordt weergegeven in het veld value. Dit is niet genoeg voor schaalvergroting, aangezien de drempel die we instellen 3 is.

Meer lading!

Controleer in de nieuwe terminal het aantal applicatiepods:

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

Laten we de belasting verhogen met behulp van de opdracht:

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

Na een tijdje zul je zien dat HPA de implementatie opschaalt en nieuwe pods lanceert. Controleer uw HPA om er zeker van te zijn 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

Als de belasting inconsistent is, wordt de implementatie teruggebracht tot het punt waarop slechts één pod actief is. Als u de daadwerkelijke metriek wilt controleren (geretourneerd door de PromQL-query), gebruikt u de opdracht:

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

Очистка

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

Conclusie

Met KEDA kunt u uw Kubernetes-implementaties automatisch schalen (van/naar nul) op basis van gegevens uit externe statistieken. Bijvoorbeeld op basis van Prometheus-statistieken, wachtrijlengte in Redis, consumentenlatentie in Kafka-onderwerp.

KEDA kan worden geïntegreerd met een externe bron en levert de statistieken ook via Metrics Server aan Horizontal Pod Autoscaler.

Good Luck!

Wat nog meer te lezen:

  1. Best Practices en Best Practices voor het uitvoeren van containers en Kubernetes in productieomgevingen.
  2. 90+ handige tools voor Kubernetes: implementatie, beheer, monitoring, beveiliging en meer.
  3. Ons kanaal Around Kubernetes in Telegram.

Bron: www.habr.com

Voeg een reactie