Автоматично мащабиране на приложения на Kubernetes с помощта на Prometheus и KEDA

Автоматично мащабиране на приложения на Kubernetes с помощта на Prometheus и KEDAЧовекът балон от Cimuanos

Мащабируемостта е ключово изискване за облачните приложения. С Kubernetes мащабирането на приложение е толкова просто, колкото увеличаване на броя на репликите за подходящо внедряване или ReplicaSet — но това е ръчен процес.

Kubernetes позволява приложенията да бъдат автоматично мащабирани (т.е. Pods в разгръщане или ReplicaSet) по декларативен начин, използвайки спецификацията на Horizontal Pod Autoscaler. Критерият по подразбиране за автоматично мащабиране е показателите за използване на процесора (метрики за ресурси), но можете да интегрирате персонализирани и външно предоставени показатели.

Отбор Kubernetes aaS от Mail.ru преведе статия за това как да използвате външни показатели за автоматично мащабиране на приложение на Kubernetes. За да покаже как работи всичко, авторът използва показатели за заявка за HTTP достъп, които се събират с помощта на Prometheus.

Вместо хоризонтално автоматично мащабиране на подове се използва Kubernetes Event Driven Autoscaling (KEDA), оператор на Kubernetes с отворен код. Той се интегрира естествено с Horizontal Pod Autoscaler, за да осигури безпроблемно автоматично мащабиране (включително до/от нула) за натоварвания, управлявани от събития. Кодът е наличен на GitHub.

Кратък преглед на системата

Автоматично мащабиране на приложения на Kubernetes с помощта на Prometheus и KEDA

Диаграмата показва кратко описание на това как работи всичко:

  1. Приложението предоставя показатели за броя на посещенията на HTTP във формат Prometheus.
  2. Prometheus е конфигуриран да събира тези показатели.
  3. Скалерът Prometheus в KEDA е конфигуриран да мащабира автоматично приложението въз основа на броя HTTP посещения.

Сега ще ви разкажа подробно за всеки елемент.

КЕДА и Прометей

Prometheus е инструментариум за система с отворен код за наблюдение и предупреждение, част Фондация за облачни компютри в облака. Събира показатели от различни източници и ги съхранява като данни за времеви серии. За визуализиране на данни можете да използвате Графана или други инструменти за визуализация, които работят с Kubernetes API.

KEDA поддържа концепцията за скалер - той действа като мост между KEDA и външната система. Реализацията на скалера е специфична за всяка целева система и извлича данни от нея. След това KEDA ги използва, за да контролира автоматичното мащабиране.

Скалерите поддържат множество източници на данни, например Kafka, Redis, Prometheus. Това означава, че KEDA може да се използва за автоматично мащабиране на внедрявания на Kubernetes, като се използват показателите на Prometheus като критерии.

Тестово приложение

Тестовото приложение Golang осигурява достъп чрез HTTP и изпълнява две важни функции:

  1. Използва клиентската библиотека на Prometheus Go, за да инструментира приложението и да предостави показателя http_requests, който съдържа брой посещения. Крайната точка, където са налични показателите на Prometheus, се намира в URI /metrics.
    var httpRequestsCounter = promauto.NewCounter(prometheus.CounterOpts{
           Name: "http_requests",
           Help: "number of http requests",
       })
    
  2. В отговор на запитване GET приложението увеличава стойността на ключа (access_count) в Redis. Това е лесен начин да свършите работата като част от HTTP манипулатор и също така да проверите показателите на Prometheus. Стойността на показателя трябва да е същата като стойността access_count в 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)
       }
    

Приложението се внедрява в Kubernetes чрез Deployment. Създава се и услуга ClusterIP, позволява на сървъра на Prometheus да получава показатели на приложението.

тук е манифест за внедряване на приложението.

Prometheus сървър

Манифестът за внедряване на Prometheus се състои от:

  • ConfigMap — за прехвърляне на конфигурацията на Prometheus;
  • Deployment — за разполагане на Prometheus в клъстер Kubernetes;
  • ClusterIP — услуга за достъп до UI Prometheus;
  • ClusterRole, ClusterRoleBinding и ServiceAccount — за автоматично откриване на услуги в Kubernetes (Auto-discovery).

тук е манифест за стартиране на Prometheus.

KEDA Prometheus ScaledObject

Скалерът действа като мост между KEDA и външната система, от която трябва да се получат показатели. ScaledObject е персонализиран ресурс, който трябва да бъде внедрен, за да синхронизира внедряването с източника на събитието, в този случай Prometheus.

ScaledObject съдържа информация за мащабиране на внедряване, метаданни за източника на събитие (като тайни връзки, име на опашка), интервал на анкетиране, период на възстановяване и други данни. Това води до съответния ресурс за автоматично мащабиране (дефиниция на HPA) за мащабиране на внедряването.

Когато обект ScaledObject се изтрие, съответната HPA дефиниция се изчиства.

Ето дефиницията ScaledObject за нашия пример той използва скалер 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]))

Моля, обърнете внимание на следните точки:

  1. Той посочва към Deployment С име go-prom-app.
  2. Тип тригер - Prometheus. Адресът на сървъра на Prometheus се споменава заедно с името на показателя, прага и PromQL заявка, които ще бъдат използвани. PromQL заявка - sum(rate(http_requests[2m])).
  3. Според pollingInterval,KEDA иска цел от Prometheus на всеки петнадесет секунди. Поне един под (minReplicaCount), а максималният брой шушулки не надвишава maxReplicaCount (в този пример - десет).

Може да се инсталира minReplicaCount равен на нула. В този случай KEDA активира внедряването от нула към едно и след това излага HPA за по-нататъшно автоматично мащабиране. Възможен е и обратният ред, т.е. мащабиране от едно до нула. В примера не сме избрали нула, защото това е HTTP услуга, а не система при поискване.

Магията в автоматичното мащабиране

Прагът се използва като тригер за мащабиране на внедряването. В нашия пример, PromQL заявката sum(rate (http_requests [2m])) връща сумарната честота на HTTP заявки (заявки в секунда), измерена през последните две минути.

Тъй като праговата стойност е три, това означава, че ще има една под, докато стойността sum(rate (http_requests [2m])) по-малко от три. Ако стойността се увеличи, всеки път се добавя допълнителен суб sum(rate (http_requests [2m])) се увеличава с три. Например, ако стойността е от 12 до 14, тогава броят на капсулите е четири.

Сега нека опитаме да го настроим!

предварителна настройка

Всичко, от което се нуждаете, е клъстер Kubernetes и конфигурирана помощна програма kubectl. Този пример използва клъстер minikube, но можете да вземете всяка друга. За инсталиране на клъстер има ръководство.

Инсталирайте най-новата версия на 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/

Определен kubectlза достъп до клъстера Kubernetes.

Инсталирайте най-новата версия на 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

Можете да внедрите KEDA по няколко начина, те са изброени в документация. Използвам монолитен YAML:

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

KEDA и неговите компоненти са инсталирани в пространството на имената keda. Команда за проверка:

kubectl get pods -n keda

Изчакайте KEDA Operator да стартира и отидете на Running State. И след това продължете.

Инсталиране на Redis с помощта на Helm

Ако нямате инсталиран Helm, използвайте това лидерство. Команда за инсталиране на Mac:

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

helm init инициализира локалния интерфейс на командния ред и също така инсталира Tiller към клъстера Kubernetes.

kubectl get pods -n kube-system | grep tiller

Изчакайте пулта на Tiller да влезе в състояние Running.

Бележка на преводача: Авторът използва Helm@2, който изисква инсталиране на сървърния компонент Tiller. Сега Helm@3 е актуален, не изисква сървърна част.

След като инсталирате Helm, една команда е достатъчна, за да стартирате Redis:

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

Проверете дали Redis е стартиран успешно:

kubectl get pods/redis-server-master-0

Изчакайте Redis да премине в състояние Running.

Внедряване на приложение

Команда за внедряване:

kubectl apply -f go-app.yaml

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

Проверете дали всичко е започнало:

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

Изчакайте Redis да влезе в състояние Running.

Разполагане на Prometheus сървър

Манифестът на Прометей използва Откриване на услуга Kubernetes за Prometheus. Позволява динамично откриване на пакети на приложения въз основа на етикета на услугата.

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

За внедряване:

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

Проверете дали всичко е започнало:

kubectl get pods -l=app=prometheus-server

Изчакайте Prometheus да влезе в състояние Running.

употреба kubectl port-forward за достъп до потребителския интерфейс на Prometheus (или API сървър) на http://localhost:9090.

kubectl port-forward service/prometheus-service 9090

Внедряване на конфигурация за автоматично мащабиране на KEDA

Команда за създаване ScaledObject:

kubectl apply -f keda-prometheus-scaledobject.yaml

Проверете регистрационните файлове на оператора на KEDA:

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

Резултатът изглежда нещо подобно:

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"

Проверете под приложения. Един екземпляр трябва да работи, защото minReplicaCount е равно на 1:

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

Проверете дали HPA ресурсът е създаден успешно:

kubectl get hpa

Трябва да видите нещо като:

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

Проверка на състоянието: достъп до приложението

За достъп до REST крайната точка на нашето приложение изпълнете:

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

Вече можете да получите достъп до вашето приложение Go, като използвате адреса http://localhost:8080. За да направите това, изпълнете командата:

curl http://localhost:8080/test

Резултатът изглежда нещо подобно:

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

На този етап проверете и Redis. Ще видите, че ключът access_count увеличен до 1:

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

Уверете се, че метричната стойност е http_requests същото:

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

Създаване на натоварване

Ще използваме хей — полезност за генериране на натоварване:

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

Можете също да изтеглите помощната програма за Linux или Windows.

Стартирайте го:

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

По подразбиране помощната програма изпраща 200 заявки. Можете да проверите това, като използвате показателите на Prometheus, както и 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

Потвърдете стойността на действителния показател (върнат от заявката 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"]}]}}

В този случай действителният резултат е 1,686057971014493 и се показва в полето value. Това не е достатъчно за мащабиране, тъй като прагът, който сме задали, е 3.

Повече натоварване!

В новия терминал наблюдавайте броя на пакетите за приложения:

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

Нека увеличим натоварването с помощта на командата:

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

След известно време ще видите как HPA мащабира внедряването и стартира нови подове. Проверете HPA, за да се уверите, че:

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

Ако натоварването е непоследователно, разгръщането ще бъде намалено до точката, в която работи само един под. Ако искате да проверите действителния показател (върнат от заявката PromQL), тогава използвайте командата:

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

Заключение

KEDA ви позволява автоматично да мащабирате своите внедрявания на Kubernetes (до/от нула) въз основа на данни от външни показатели. Например въз основа на показатели на Prometheus, дължина на опашката в Redis, латентност на потребителите в тема Kafka.

KEDA се интегрира с външен източник и също така предоставя своите показатели чрез Metrics Server към Horizontal Pod Autoscaler.

Good Luck!

Какво друго да прочетете:

  1. Най-добри практики и най-добри практики за изпълнение на контейнери и Kubernetes в производствени среди.
  2. 90+ полезни инструмента за Kubernetes: внедряване, управление, наблюдение, сигурност и други.
  3. Нашият канал Около Kubernetes в Telegram.

Източник: www.habr.com

Добавяне на нов коментар