Мащабируемостта е ключово изискване за облачните приложения. С 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.
Кратък преглед на системата
Диаграмата показва кратко описание на това как работи всичко:
Приложението предоставя показатели за броя на посещенията на HTTP във формат Prometheus.
Prometheus е конфигуриран да събира тези показатели.
Скалерът Prometheus в KEDA е конфигуриран да мащабира автоматично приложението въз основа на броя HTTP посещения.
Сега ще ви разкажа подробно за всеки елемент.
КЕДА и Прометей
Prometheus е инструментариум за система с отворен код за наблюдение и предупреждение, част Фондация за облачни компютри в облака. Събира показатели от различни източници и ги съхранява като данни за времеви серии. За визуализиране на данни можете да използвате Графана или други инструменти за визуализация, които работят с Kubernetes API.
KEDA поддържа концепцията за скалер - той действа като мост между KEDA и външната система. Реализацията на скалера е специфична за всяка целева система и извлича данни от нея. След това KEDA ги използва, за да контролира автоматичното мащабиране.
Скалерите поддържат множество източници на данни, например Kafka, Redis, Prometheus. Това означава, че KEDA може да се използва за автоматично мащабиране на внедрявания на Kubernetes, като се използват показателите на Prometheus като критерии.
Тестово приложение
Тестовото приложение Golang осигурява достъп чрез HTTP и изпълнява две важни функции:
Използва клиентската библиотека на Prometheus Go, за да инструментира приложението и да предостави показателя http_requests, който съдържа брой посещения. Крайната точка, където са налични показателите на Prometheus, се намира в URI /metrics.
var httpRequestsCounter = promauto.NewCounter(prometheus.CounterOpts{
Name: "http_requests",
Help: "number of http requests",
})
В отговор на запитване GET приложението увеличава стойността на ключа (access_count) в Redis. Това е лесен начин да свършите работата като част от HTTP манипулатор и също така да проверите показателите на Prometheus. Стойността на показателя трябва да е същата като стойността access_count в Redis.
Приложението се внедрява в Kubernetes чрез Deployment. Създава се и услуга ClusterIP, позволява на сървъра на Prometheus да получава показатели на приложението.
Скалерът действа като мост между KEDA и външната система, от която трябва да се получат показатели. ScaledObject е персонализиран ресурс, който трябва да бъде внедрен, за да синхронизира внедряването с източника на събитието, в този случай Prometheus.
ScaledObject съдържа информация за мащабиране на внедряване, метаданни за източника на събитие (като тайни връзки, име на опашка), интервал на анкетиране, период на възстановяване и други данни. Това води до съответния ресурс за автоматично мащабиране (дефиниция на HPA) за мащабиране на внедряването.
Когато обект ScaledObject се изтрие, съответната HPA дефиниция се изчиства.
Ето дефиницията ScaledObject за нашия пример той използва скалер Prometheus:
Тип тригер - Prometheus. Адресът на сървъра на Prometheus се споменава заедно с името на показателя, прага и PromQL заявка, които ще бъдат използвани. PromQL заявка - sum(rate(http_requests[2m])).
Според 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, но можете да вземете всяка друга. За инсталиране на клъстер има ръководство.
helm init инициализира локалния интерфейс на командния ред и също така инсталира Tiller към клъстера Kubernetes.
kubectl get pods -n kube-system | grep tiller
Изчакайте пулта на Tiller да влезе в състояние Running.
Бележка на преводача: Авторът използва Helm@2, който изисква инсталиране на сървърния компонент Tiller. Сега Helm@3 е актуален, не изисква сървърна част.
След като инсталирате Helm, една команда е достатъчна, за да стартирате Redis:
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.
Проверете регистрационните файлове на оператора на 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 крайната точка на нашето приложение изпълнете:
Вече можете да получите достъп до вашето приложение 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
Създаване на натоварване
Ще използваме хей — полезност за генериране на натоварване:
В този случай действителният резултат е 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), тогава използвайте командата:
//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.