
Мащабируемостта е ключово изискване за облачни приложения. С Kubernetes е толкова лесно да мащабираш приложението, колкото и да увеличиш броя на репликите за съответстващото разгръщане или ReplicaSet — но това е ръчен процес.
Kubernetes позволява автоматично мащабиране на приложения (тоест Pod в разгръщането или ReplicaSet) декларативно, използвайки спецификацията Horizontal Pod Autoscaler. По подразбиране критерия за автоматично мащабиране е метриките за използване на CPU (ресурсни метрики), но могат да се интегрират потребителски метрики и метрики, предоставяни от външни източници.
Екип преведе статия за това как да се използват външни метрики за автоматично мащабиране на Kubernetes приложение. За да покажеш как всичко работи, авторът използва метрики на HTTP заявки, събирани с помощта на Prometheus.
Вместо хоризонтално автомасштабиране на подове, се прилага Kubernetes Event Driven Autoscaling (KEDA) — оператор на Kubernetes с отворен код. Той първоначално се интегрира с Horizontal Pod Autoscaler, за да осигури плавно вале автоматично мащабиране (включително до/от нула) за управлявани от събития натоварвания. Кодът е наличен на .
Кратък преглед на работата на системата

На схемата — кратко описание на начина, по който всичко работи:
- Приложението предоставя метрики за количеството на HTTP заявките в формат Prometheus.
- Prometheus е конфигуриран да събира тези показатели.
- Скейлерът Prometheus в KEDA е настроен за автоматично мащабиране на приложението на базата на количеството заявките към HTTP.
Сега подробно ще разкажа за всеки елемент.
KEDA и Prometheus
Prometheus е набор от инструменти за мониторинг и оповестяване на системи с отворен код, част от . Събира метрики от различни източници и ги съхранява под формата на времеви редове. За визуализиране на данните може да се използва или други инструменти за визуализация, работещи с API на Kubernetes.
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: "брой http запитвания", }) - В отговор на запитването
ИЗИСКВАНЕприложението увеличава стойността на ключа (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("Не може да се увеличи броят в Redis", err) os.Exit(1) } resp := "Достъпен на " + time.Now().String() + "nБрой достъпи " + strconv.Itoa(int(count)) w.Write([]byte(resp)) }) http.ListenAndServe(":8080", nil) }
Приложението се разгръща в Kubernetes чрез Deployment. Също така се създава услуга ClusterIP, която позволява на сървъра на Prometheus да получава метрики от приложението.
Ето .
Сървър Prometheus
Манифестът за разгръщане на Prometheus се състои от:
ConfigMap— за предаване на конфигурацията на Prometheus;Deployment— за разгръщане на Prometheus в Kubernetes клъстера;ClusterIP— услуга за достъп до потребителския интерфейс на Prometheus;ClusterRole,ClusterRoleBindingиServiceAccount— за работа на автоопределението на услугите в Kubernetes (Auto-discovery).
Ето .
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]))
Обърнете внимание на следните моменти:
- Той указва на
Deploymentс иметоgo-prom-app. - Тип на тригера —
Prometheus. Адресът на сървъра Prometheus се споменава заедно с името на метриката, праговото значение и , която ще се използва. Запитването 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, но можете да вземете всеки друг. За инсталация на клъстера има .
Инсталирайте последната версия на 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/
Установете , за да получите достъп до клъстера 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 стартира — премине в Работещо състояние. И след това продължете.
Инсталиране на 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 премине в състояние Работи.
Бележка на преводача: Авторът използва 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 премине в състояние В процес на изпълнение.
Разгръщане на приложението
Команда за разполагане:
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 премине в състояние В процес на изпълнение.
Разполагане на сървър Prometheus
Манифестът на 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 премине в състояние В процес на изпълнение.
Използвайте kubectl port-forward за достъп до потребителския интерфейс на Prometheus (или API сървър) на адрес .
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
Трябва да видите нещо подобно:
ИМЕ РЕФЕРЕНЦИЯ ЦЕЛИ MINPODS MAXPODS РЕПЛИКИ ВЪЗРАСТ
keda-hpa-go-prom-app Deployment/go-prom-app 0/3 (средно) 1 10 1 45s
Проверка на работоспособността: достъп до приложението
За да получите достъп до REST крайната точка на нашето приложение, стартирайте:
kubectl port-forward service/go-prom-app-service 8080
Сега можете да получите достъп до приложението Go, използвайки адреса . За целта изпълнете командата:
curl http://localhost:8080/test
Резултатът изглежда приблизително така:
Достъпен на 2019-10-21 11:29:10.560385986 +0000 UTC
m=+406004.817901246
Брой на достъпите 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 брой на HTTP заявките
# TYPE http_requests counter
http_requests 1
Създаване на натоварване
Ще използваме — инструмент за генериране на натоварване:
curl -o hey https://storage.googleapis.com/hey-release/hey_darwin_amd64
&& chmod a+x hey
Може също така да изтеглите инструмента за или .
Стартирайте го:
./hey http://localhost:8080/test
По подразбиране инструментът изпраща 200 заявки. Можете да се уверите в това, използвайки метриките на Prometheus, както и Redis.
curl http://localhost:8080/metrics | grep http_requests
//output
# HELP http_requests брой на HTTP заявките
# 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
ИМЕ РЕФЕРЕНЦИЯ ЦЕЛИ MINPODS MAXPODS РЕПЛИКИ ВЪЗРАСТ
keda-hpa-go-prom-app Deployment/go-prom-app 1830m/3 (средно) 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.
Успех!
Какво друго да прочетете:
- .
- .
- .
Източник: habr.com
