Auto-scaling e aplikacioneve Kubernetes me ndihmën e Prometheus dhe KEDA

Auto-scaling e aplikacioneve Kubernetes me ndihmën e Prometheus dhe KEDABalloon Man nga Cimuanos

ShkallĂ«zueshmĂ«ria Ă«shtĂ« njĂ« kĂ«rkesĂ« kyçe pĂ«r aplikacionet nĂ« cloud. Me Kubernetes, Ă«shtĂ« po aq e lehtĂ« tĂ« shkallĂ«zohet njĂ« aplikacion siç Ă«shtĂ« rritja e numrit tĂ« replicave pĂ«r njĂ« implementim tĂ« caktuar ose ReplicaSet — por ky Ă«shtĂ« njĂ« proces manual.

Kubernetes mundëson shkallëzim automatik të aplikacioneve (domethënë Pod në implementim ose ReplicaSet) në një mënyrë deklarative duke përdorur specifikimin Horizontal Pod Autoscaler. Në mënyrë të parazgjedhur, kriteri për shkallëzim automatik janë metrikat e përdorimit të CPU (metrikat e burimeve), por është e mundur të integrohen metrika të personalizuara dhe metrika të ofruara nga jashtë.

Ekipa Kubernetes aaS nga Mail.ru ka përkthyer një artikull mbi përdorimin e metrikave të jashtme për shkallëzimin automatik të aplikacionit Kubernetes. Për të ilustruar se si funksionon gjithçka, autori përdor metrikat e kërkesave të HTTP-së që mblidhen me ndihmën e Prometheus.

NĂ« vend tĂ« autoskalimit horizontal tĂ« podĂ«ve, aplikohet Kubernetes Event Driven Autoscaling (KEDA) — njĂ« operator Kubernetes me kod tĂ« hapur. Ai integron fillimisht me Horizontal Pod Autoscaler, pĂ«r tĂ« siguruar autoskalim tĂ« qetĂ« (pĂ«rfshirĂ« deri/nga zero) pĂ«r ngarkesat e punĂ«s qĂ« menaxhohen nga ngjarjet. Kodi Ă«shtĂ« i disponueshĂ«m nĂ« GitHub.

Një përmbledhje e shkurtër e punës së sistemit

Auto-scaling e aplikacioneve Kubernetes me ndihmën e Prometheus dhe KEDA

NĂ« diagram — njĂ« pĂ«rshkrim i shkurtĂ«r i mĂ«nyrĂ«s se si funksionon gjithçka:

  1. Aplikacioni ofron metrika për numrin e kërkesave HTTP në formatin Prometheus.
  2. Prometheus është i konfiguruar për të mbledhur këto tregues.
  3. Skaleri Prometheus në KEDA është i konfiguruar për të autoskalimin e aplikacionit në bazë të numrit të kërkesave HTTP.

Tani do të flas në hollësi për çdo element.

KEDA dhe Prometheus

Prometheus është një grup mjetesh për monitorimin dhe njoftimin e sistemeve me kod të hapur, pjesë e Cloud Native Computing Foundation. Ai mbledh metrika nga burime të ndryshme dhe i ruan si të dhëna të serive temporale. Për vizualizimin e të dhënave mund të përdoren Grafana ose mjete të tjera vizualizimi që punojnë me API Kubernetes.

KEDA mbĂ«shtet konceptin e skailerit — ai shĂ«rben si njĂ« urĂ« midis KEDA-s dhe sistemit tĂ« jashtĂ«m. Zbatimi i skailerit Ă«shtĂ« specifik pĂ«r çdo sistem qĂ« synohet dhe nxjerr tĂ« dhĂ«na prej tij. Pastaj, KEDA i pĂ«rdor ato pĂ«r tĂ« menaxhuar shkallĂ«zimin automatik.

Skailerët mbështesin disa burime të dhënash, si Kafka, Redis, dhe Prometheus. Kështu, KEDA mund të përdoret për shkallëzimin automatik të implementimeve Kubernetes, duke përdorur metrikat e Prometheus si kritere.

Aplikacioni testues

Aplikacioni testues Golang ofron akses përmes HTTP dhe realizon dy funksione të rëndësishme:

  1. Përdor bibliotekën e klientit Prometheus Go për instrumentimin e aplikacionit dhe ofrimin e metrikës http_requests, e cila përmban një numërues të kërkesave. Pikë e fundit ku metrikat e Prometheus janë të aksesueshme ndodhet në URI /metrics.
    var httpRequestsCounter = promauto.NewCounter(prometheus.CounterOpts{
           Name: "http_requests",
           Help: "numri i kërkesave http",
       })
    
  2. Në përgjigje të kërkesës GET aplikacioni rrit vlerën e çelësit (access_count) në Redis. Kjo është një mënyrë e thjeshtë për të kryer punën si pjesë e manipulatorit HTTP, si dhe për të verifikuar metrikat e Prometheus. Vlera e metrikës duhet të jetë e njëjtë me vlerën access_count në 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("Nuk ju ha marre me rritjen e numrit te redis", err)
                   os.Exit(1)
               }
               resp := "Keni aksesuar ne " + time.Now().String() + "nNumri i aksesimeve " + strconv.Itoa(int(count))
               w.Write([]byte(resp))
           })
           http.ListenAndServe(":8080", nil)
       }
    

Aplikacioni deployohet në Kubernetes përmes Deployment. Po ashtu krijohet një shërbim ClusterIP, i cili lejon serverin Prometheus të marrë metrikat e aplikacionit.

Këtu është manifesti i deployment-it për aplikacionin.

Serveri Prometheus

Manifesti i deployment-it të Prometheus përbëhet nga:

  • ConfigMap — pĂ«r kalimin e konfiguracionit tĂ« Prometheus;
  • Deployment — pĂ«r deployment-in e Prometheus nĂ« klasterin Kubernetes;
  • ClusterIP — shĂ«rbimi pĂ«r akses nĂ« UI tĂ« Prometheus;
  • ClusterRole, ClusterRoleBinding dhe ServiceAccount — pĂ«r tĂ« punuar me auto-pĂ«rcaktimin e shĂ«rbimeve nĂ« Kubernetes (Auto-discovery).

Këtu është manifesti për nisjen e Prometheus.

KEDA Prometheus ScaledObject

Skaleri vepron si njĂ« urĂ« midis KEDA-s dhe sistemit tĂ« jashtĂ«m nga i cili nevojiten tĂ« merren metrikat. ScaledObject — njĂ« burim qĂ« mund tĂ« konfigurohet, i cili duhet tĂ« bĂ«het deploy pĂ«r tĂ« sinkronizuar deployment-in me burimin e ngjarjeve, nĂ« kĂ«tĂ« rast me Prometheus.

ScaledObject përmban informacion mbi shpërndarjen e masave, metadata për burimin e ngjarjeve (p.sh., sekrete për lidhjen, emrin e radhës), intervalin e anketimit, periudhën e rikuperimit dhe të dhëna të tjera. Kjo të çon te burimi përkatës i automatik-shkallëzimit (përcaktimi HPA) për shkallëzim të shpërndarjes.

Kur objekti ScaledObject fshihet, përkufizimi përkatës HPA pastron.

Këtu është përkufizimi ScaledObject për shembullin tonë, në të përdoret skaler 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]))

Merrni parasysh këto pika:

  1. Ai tregon te Deployment me emrin go-prom-app.
  2. Lloji i tĂ«rheqjes Ă«shtĂ« — Prometheus. Adresa e serverit Prometheus pĂ«rmendet sĂ« bashku me emrin e metrikĂ«s, vlerĂ«n e pragut dhe pyetjen PromQL, e cila do tĂ« pĂ«rdoret. Pyetja PromQL Ă«shtĂ« sum(rate(http_requests[2m])).
  3. Sipas pollingInterval, KEDA anketon objektivĂ«n nga Prometheus çdo pesĂ«mbĂ«dhjetĂ« sekonda. Minimumi i mbĂ«shtetur Ă«shtĂ« njĂ« pod (minReplicaCount), dhe numri maksimal i pods nuk kalon maxReplicaCount (nĂ« kĂ«tĂ« shembull — dhjetĂ«).

Mund të vendoset minReplicaCount të jetë zero. Në këtë rast, KEDA aktivizon një deploy nga zero në një, dhe pastaj ofron HPA për automatizimin e mëtejshëm. E kundërta gjithashtu është e mundur, pra, të kalosh nga një në zero. Në shembullin tonë nuk zgjodhëm zero, pasi kjo është një shërbim HTTP, dhe jo një sistem në kërkesë.

Magjia brenda automatikëve të shkallëzimit

Vlera prag përdoret si një nxitës për shkallëzimin e deploy-it. Në shembullin tonë, kërkesa PromQL sum(rate (http_requests [2m])) kthen një vlerë të agreguar të shkallës së HTTP-kërkesave (numri i kërkesave në sekondë), e cila matet gjatë dy minuteve të fundit.

Duke qenë se vlera prag është tri, do të jetë një pod, derisa vlera sum(rate (http_requests [2m])) të jetë më pak se tri. Nëse vlera rritet, shtohet një pod i shtuar çdo herë që sum(rate (http_requests [2m])) rritet me tre. Për shembull, nëse vlera shkon nga 12 në 14, atëherë numri i pods është katër.

Tani le të provojmë të konfigurojmë!

Parakonfigurim

Gjithçka që ju nevojitet është një klaster Kubernetes dhe një mjet i konfiguruar kubectl. Në këtë shembull, përdoret klasteri minikube, por mund të përdorni ndonjë tjetrë. Për të instaluar klasterin, ka një udhëzues.

Instalo versionin më të fundit në 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/

Instaloni kubectl, për të aksesuar klasterin Kubernetes.

Instalo versionin më të fundit në 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

Instalimi i KEDA

Mund të zbatoni KEDA në disa mënyra, të cilat janë të përshkruara në dokumentacion. Unë përdor një YAML monolit:

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

KEDA dhe komponentët e saj instalohen në hapësirën emërtuese keda. Komanda për kontroll:

kubectl get pods -n keda

Pritni derisa pod-i KEDA Operator tĂ« fillojĂ« — tĂ« kalojĂ« nĂ« Gjendja Punuese. Dhe pas kĂ«saj vazhdoni.

Instalimi i Redis me Helm

Nëse nuk e keni instaluar Helm, përdorni këtë udhëzues. Komanda për instalim në Mac:

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

helm init inizializon ndërfaqen lokale të komandës, si dhe instalon Tiller në Kubernetes cluster.

kubectl get pods -n kube-system | grep tiller

Pritni deri sa pod-i Tiller të kalojë në gjendjen Running.

Shënimi i përkthyesit: Autori përdor Helm@2, i cili kërkon instalimin e komponentit server Tiller. Tani është i rëndësishëm Helm@3, për të cilin pjesa server nuk është e nevojshme.

Pas instalimit të Helm, për të nisur Redis mjafton një komandë:

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

Sigurohu që Redis është nisur me sukses:

kubectl get pods/redis-server-master-0

Pritni deri sa pod-i Redis të kalojë në gjendje Running.

Zhvillimi i aplikacionit

Komanda për zhvillim:

kubectl apply -f go-app.yaml

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

Kontrollo që gjithçka të jetë nisur:

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

Pritni deri sa Redis të kalojë në gjendje Running.

Zhvillimi i serverit Prometheus

Manifesti i Prometheus përdor Kubernetes Service Discovery për Prometheus. Ai lejon të zbulohen dinamikisht pods e aplikacionit në bazë të etiketës së shërbimit.

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

Për zhvillim:

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

Kontrollo që gjithçka të jetë nisur:

kubectl get pods -l=app=prometheus-server

Prisni se që podi Prometheus kalon në gjendjen Running.

Përdorni kubectl port-forward për qasje në ndërfaqen e përdoruesit të Prometheus (ose serverin API) në adresën http://localhost:9090.

kubectl port-forward service/prometheus-service 9090

Zhvillimi i konfigurimit të auto-skalimit KEDA

Komanda për krijimin e ScaledObject:

kubectl apply -f keda-prometheus-scaledobject.yaml

Kontrolloni logjet e operatorit KEDA:

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

Rezultati duket kështu:

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"

Kontrolloni podin e aplikacionit. Duhet të jetë aktiv një instancë, pasi minReplicaCount është e barabartë me 1:

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

Kontrolloni që burimi HPA është krijuar me sukses:

kubectl get hpa

Duhet të shihni diçka si:

EMRI                   REFERENCAT                TARGETS     MINPODS   MAXPODS   REPLICAS   MOSHA
keda-hpa-go-prom-app   Zhvillimi/go-prom-app   0/3 (mesatare)   1         10        1          45s

Verifikimi i funksionit: qasje në aplikacion

Për të aksesuar pikën përfundimtare REST të aplikacionit tonë, drejtoni:

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

Tani mund të aksesoni aplikacionin Go, duke përdorur adresën http://localhost:8080. Për këtë, ekzekutoni komandën:

curl http://localhost:8080/test

Rezultati duket kështu:

Aksesuara më 2019-10-21 11:29:10.560385986 +0000 UTC 
m=+406004.817901246
Numri i akseseve 1

Në këtë fazë, kontrolloni gjithashtu Redis. Do të shihni se çelësi access_count është rritur në 1:

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

Sigurohuni që vlera e metrikës http_requests të jetë e njëjtë:

curl http://localhost:8080/metrics | grep http_requests
//output
# HELP http_requests numri i kërkesave http
# TYPE http_requests counter
http_requests 1

Krijimi i ngarkesës

Do tĂ« pĂ«rdorim hey — utilitarin pĂ«r tĂ« gjeneruar ngarkesĂ«:

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

Mund të shkarkoni gjithashtu utilitarin për Linux ose Windows.

Ekzekutoni atë:

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

Sipas parazgjedhjes, utilitari dërgon 200 kërkesa. Mund ta verifikoni këtë, duke përdorur metrikat Prometheus, si dhe Redis.

curl http://localhost:8080/metrics | grep http_requests
//output
# HELP http_requests numri i kërkesave http
# TYPE http_requests counter
http_requests 201
kubectl exec -it redis-server-master-0 -- redis-cli get access_count
//output
201

Konfirmoni vlerën e metrikës reale (që kthehet nga kërkesa 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"]}]}}

Në këtë rast, rezultati aktual është 1,686057971014493 dhe shfaqet në fushën vlera. Kjo nuk është e mjaftueshme për të shkallëzuar, pasi pragun që kemi vendosur është 3.

Më shumë ngarkesë!

Në terminalin e ri, ndjekni numrin e pod-eve të aplikacionit:

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

Le të rritim ngarkesën duke përdorur komandën:

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

Pas një kohe, do të shihni se HPA po shkallëzon zbatuar dhe po drejton pod-e të reja. Kontrolloni HPA-në për t'u siguruar për këtë:

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

Nëse ngarkesa është e paqëndrueshme, zbatuari do të ulet në pikën ku funksionon vetëm një pod. Nëse dëshironi të kontrolloni metrikën reale (të kthyer nga kërkesa PromQL), përdorni komandën:

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

Pastrimi

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

Përfundimi

KEDA mundëson që të skalohet automatikisht implementimi juaj Kubernetes (nga zero në) në bazë të të dhënave nga metrikat e jashtme. Për shembull, në bazë të metrikave Prometheus, gjatësi e radhës në Redis, vonesën e konsumatorit në temën Kafka.

KEDA integron me një burim të jashtëm, dhe gjithashtu siguron metrikat e tij përmes Metrics Server për Horizontal Pod Autoscaler.

Suksese!

ÇfarĂ« tjetĂ«r mund tĂ« lexoni:

  1. Praktikat më të mira dhe rekomandimet për ekzekutimin e kontejnerëve dhe Kubernetes në ambientet prodhuese.
  2. 90+ mjete të dobishme për Kubernetes: implementim, menaxhim, monitorim, siguri dhe jo vetëm.
  3. Kanalin tonë Rreth Kubernetes në Telegram.

Burimi: habr.com

Bli njĂ« hosting tĂ« besueshĂ«m pĂ«r faqet me mbrojtje DDoS, VPS VDS serverĂ« đŸ”„ Bli njĂ« hosting tĂ« besueshĂ«m pĂ«r faqet me mbrojtje DDoS, VPS VDS serverĂ« | ProHoster