Autoscaling d'aplicacions Kubernetes amb Prometheus i KEDA

Autoscaling d'aplicacions Kubernetes amb Prometheus i KEDABalloon Man de Cimuanos

L'escalabilitat és un requisit clau per a les aplicacions al núvol. Amb Kubernetes, escalar una aplicació és tan senzill com augmentar el nombre de rèpliques per al desplegament adequat o ReplicaSet — però és un procés manual.

Kubernetes permet escalar automàticament les aplicacions (és a dir, pods en un desplegament o ReplicaSet) de manera declarativa mitjançant l'especificació Horizontal Pod Autoscaler. El criteri predeterminat per a l'escala automàtica són les mètriques d'ús de la CPU (mètriques de recursos), però podeu integrar mètriques personalitzades i proporcionades externament.

Equip Kubernetes aaS de Mail.ru va traduir un article sobre com utilitzar mètriques externes per escalar automàticament una aplicació Kubernetes. Per mostrar com funciona tot, l'autor utilitza mètriques de sol·licitud d'accés HTTP, que es recullen mitjançant Prometheus.

En lloc de l'escala automàtica horitzontal dels pods, s'utilitza l'Escaling automàtic impulsat per esdeveniments de Kubernetes (KEDA), un operador de Kubernetes de codi obert. S'integra de manera nativa amb Horizontal Pod Autoscaler per proporcionar un autoescalat perfecte (incloent-hi des de zero) per a càrregues de treball basades en esdeveniments. Codi disponible a GitHub.

Breu visió general del sistema

Autoscaling d'aplicacions Kubernetes amb Prometheus i KEDA

El diagrama mostra una breu descripció de com funciona tot:

  1. L'aplicació proporciona mètriques de recompte de visites HTTP en format Prometheus.
  2. Prometheus està configurat per recopilar aquestes mètriques.
  3. L'escalador de Prometheus a KEDA està configurat per escalar automàticament l'aplicació en funció del nombre de visites HTTP.

Ara us explicaré amb detall cada element.

KEDA i Prometeu

Prometheus és un conjunt d'eines de monitorització i alerta del sistema de codi obert, part Fundació Cloud Native Computing. Recull mètriques de diverses fonts i les emmagatzema com a dades de sèries temporals. Per visualitzar dades podeu utilitzar Grafana o altres eines de visualització que funcionen amb l'API de Kubernetes.

KEDA admet el concepte d'escalador: actua com a pont entre KEDA i el sistema extern. La implementació de l'escalador és específica per a cada sistema objectiu i n'extreu dades. Aleshores, KEDA els utilitza per controlar l'escala automàtica.

Els escaladors admeten diverses fonts de dades, per exemple, Kafka, Redis, Prometheus. És a dir, KEDA es pot utilitzar per escalar automàticament els desplegaments de Kubernetes utilitzant mètriques de Prometheus com a criteris.

Aplicació de prova

L'aplicació de prova de Golang proporciona accés mitjançant HTTP i realitza dues funcions importants:

  1. Utilitza la biblioteca de client Prometheus Go per instrumentar l'aplicació i proporcionar la mètrica http_requests, que conté un recompte de visites. El punt final on estan disponibles les mètriques de Prometheus es troba a l'URI /metrics.
    var httpRequestsCounter = promauto.NewCounter(prometheus.CounterOpts{
           Name: "http_requests",
           Help: "number of http requests",
       })
    
  2. En resposta a una petició GET l'aplicació augmenta el valor de la clau (access_count) a Redis. Aquesta és una manera senzilla de fer la feina com a part d'un controlador HTTP i també de comprovar les mètriques de Prometheus. El valor de la mètrica ha de ser el mateix que el valor access_count a 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)
       }
    

L'aplicació es desplega a Kubernetes mitjançant Deployment. També es crea un servei ClusterIP, permet al servidor Prometheus obtenir mètriques de l'aplicació.

aquí està manifest de desplegament de l'aplicació.

Servidor Prometheus

El manifest de desplegament de Prometheus consta de:

  • ConfigMap — per transferir la configuració de Prometheus;
  • Deployment — per desplegar Prometheus en un clúster de Kubernetes;
  • ClusterIP — servei d'accés a UI Prometheus;
  • ClusterRole, ClusterRoleBinding и ServiceAccount — per a la detecció automàtica de serveis a Kubernetes (descobriment automàtic).

aquí està manifest per executar Prometeu.

KEDA Prometheus ScaledObject

L'escalador actua com un pont entre KEDA i el sistema extern del qual s'han d'obtenir mètriques. ScaledObject és un recurs personalitzat que s'ha de desplegar per sincronitzar el desplegament amb la font de l'esdeveniment, en aquest cas Prometheus.

ScaledObject conté informació d'escala del desplegament, metadades de la font d'esdeveniments (com ara secrets de connexió, nom de cua), interval de sondeig, període de recuperació i altres dades. Dóna lloc al recurs d'escala automàtica corresponent (definició HPA) per escalar el desplegament.

Quan un objecte ScaledObject s'elimina, s'esborra la definició HPA corresponent.

Aquí teniu la definició ScaledObject per al nostre exemple, utilitza un escalador 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]))

Penseu en els punts següents:

  1. Ell assenyala Deployment Amb nom go-prom-app.
  2. Tipus d'activador - Prometheus. L'adreça del servidor Prometheus s'esmenta juntament amb el nom de la mètrica, el llindar i Consulta PromQL, que s'utilitzarà. Consulta PromQL - sum(rate(http_requests[2m])).
  3. Segons pollingInterval,KEDA demana un objectiu a Prometeu cada quinze segons. Almenys un sota (minReplicaCount), i el nombre màxim de beines no supera maxReplicaCount (en aquest exemple - deu).

Es pot instal·lar minReplicaCount igual a zero. En aquest cas, KEDA activa el desplegament zero a un i després exposa l'HPA per a una escala automàtica addicional. També és possible l'ordre invers, és a dir, escalar d'un a zero. A l'exemple, no hem seleccionat zero perquè es tracta d'un servei HTTP i no d'un sistema sota demanda.

La màgia dins de l'autoscaling

El llindar s'utilitza com a activador per escalar el desplegament. En el nostre exemple, la consulta PromQL sum(rate (http_requests [2m])) retorna la taxa de sol·licitud HTTP agregada (sol·licituds per segon), mesurada durant els darrers dos minuts.

Com que el valor llindar és tres, vol dir que hi haurà un per sota del valor sum(rate (http_requests [2m])) menys de tres. Si el valor augmenta, cada vegada s'afegeix un subordinat addicional sum(rate (http_requests [2m])) augmenta en tres. Per exemple, si el valor és de 12 a 14, el nombre de beines és quatre.

Ara provem de configurar-lo!

preconfiguració

Tot el que necessiteu és un clúster de Kubernetes i una utilitat configurada kubectl. Aquest exemple utilitza un clúster minikube, però pots agafar-ne qualsevol altre. Per instal·lar un clúster hi ha lideratge.

Instal·leu la darrera versió a 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/

Instal·lar kubectlper accedir al clúster de Kubernetes.

Instal·leu la darrera versió a 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

Instal·lació KEDA

Podeu implementar KEDA de diverses maneres, s'enumeren a documentació. Estic utilitzant YAML monolític:

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

KEDA i els seus components s'instal·len a l'espai de noms keda. Ordre per comprovar:

kubectl get pods -n keda

Espereu que l'operador KEDA s'iniciï i aneu a Running State. I després d'això, continua.

Instal·lació de Redis amb Helm

Si no teniu Helm instal·lat, feu servir aquest lideratge. Ordre per instal·lar a Mac:

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

helm init inicialitza la interfície de la línia d'ordres local i també s'instal·la Tiller al clúster de Kubernetes.

kubectl get pods -n kube-system | grep tiller

Espereu que el Tiller pod entri a l'estat d'execució.

Nota del traductor: L'autor utilitza Helm@2, que requereix que el component del servidor Tiller estigui instal·lat. Ara Helm@3 és rellevant, no requereix cap part del servidor.

Després d'instal·lar Helm, n'hi ha prou amb una ordre per iniciar Redis:

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

Comproveu que Redis s'ha iniciat correctament:

kubectl get pods/redis-server-master-0

Espereu que Redis entri en estat Running.

Desplegament d'aplicacions

Ordre de desplegament:

kubectl apply -f go-app.yaml

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

Comprova que tot ha començat:

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

Espereu que Redis entri en estat Running.

Desplegant un servidor Prometheus

El manifest de Prometeu utilitza Kubernetes Service Discovery per a Prometheus. Permet el descobriment dinàmic de pods d'aplicacions en funció de l'etiqueta del servei.

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

Per desplegar:

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

Comprova que tot ha començat:

kubectl get pods -l=app=prometheus-server

Espereu que Prometeu entri en estat Running.

ús kubectl port-forward per accedir a la interfície d'usuari de Prometheus (o al servidor API) a http://localhost:9090.

kubectl port-forward service/prometheus-service 9090

Desplegament de la configuració d'escala automàtica de KEDA

Ordre per crear ScaledObject:

kubectl apply -f keda-prometheus-scaledobject.yaml

Comproveu els registres de l'operador KEDA:

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

El resultat sembla una cosa així:

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"

Comproveu sota aplicacions. S'ha d'executar una instància perquè minReplicaCount és igual a 1:

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

Verifiqueu que el recurs HPA s'ha creat correctament:

kubectl get hpa

Hauríeu de veure alguna cosa com:

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

Comprovació de l'estat: accés a l'aplicació

Per accedir al punt final REST de la nostra aplicació, executeu:

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

Ara podeu accedir a l'aplicació Go mitjançant l'adreça http://localhost:8080. Per fer-ho, executeu l'ordre:

curl http://localhost:8080/test

El resultat sembla una cosa així:

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

En aquest punt també comproveu Redis. Ja veuràs que la clau access_count augmentat a 1:

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

Assegureu-vos que el valor de la mètrica és http_requests el mateix:

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

Creació de càrrega

L’utilitzarem hey — Utilitat per generar càrrega:

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

També podeu descarregar la utilitat per Linux o Windows.

Executeu-ho:

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

Per defecte, la utilitat envia 200 peticions. Podeu verificar-ho mitjançant mètriques de Prometheus 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

Valideu el valor de la mètrica real (retornada per la consulta PromQL):

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

En aquest cas el resultat real és 1,686057971014493 i es mostra al camp value. Això no és suficient per escalar, ja que el llindar que establim és 3.

Més càrrega!

Al nou terminal, controleu el nombre de pods d'aplicacions:

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

Augmentem la càrrega amb l'ordre:

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

Després d'un temps, veureu que HPA escala el desplegament i llança nous pods. Comproveu el vostre HPA per assegurar-vos que:

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

Si la càrrega és inconsistent, el desplegament es reduirà fins al punt en què només s'executa un pod. Si voleu comprovar la mètrica real (retornada per la consulta PromQL), feu servir l'ordre:

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

Neteja

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

Conclusió

KEDA us permet escalar automàticament les vostres implementacions de Kubernetes (des de zero) en funció de les dades de mètriques externes. Per exemple, segons les mètriques de Prometheus, la durada de la cua a Redis, la latència del consumidor al tema Kafka.

KEDA s'integra amb una font externa i també proporciona les seves mètriques mitjançant Metrics Server a Horizontal Pod Autoscaler.

Bona sort!

Què més cal llegir:

  1. Bones pràctiques i bones pràctiques per executar contenidors i Kubernetes en entorns de producció.
  2. Més de 90 eines útils per a Kubernetes: desplegament, gestió, supervisió, seguretat i molt més.
  3. El nostre canal Al voltant de Kubernetes a Telegram.

Font: www.habr.com

Afegeix comentari