Использование APISIX, Prometheus и KEDA для эластичного масштабирования приложений в Kubernetes
February 17, 2023
Введение
Объем трафика, поступающего в приложение, может варьироваться в зависимости от времени. Например, приложение для онлайн-покупок гораздо активнее в праздничный сезон, чем в обычные дни. Возможность регулировать производительность приложения в зависимости от трафика обеспечит гораздо лучший пользовательский опыт и сервис.
Apache APISIX — это высокопроизводительный облачный API-шлюз, который может предоставлять полезные метрики для определения необходимости масштабирования приложений. Это промежуточное ПО, которое обрабатывает весь трафик, направляемый в вышестоящие приложения, и, следовательно, может собирать данные о трафике в процессе.
Для выполнения эластичного масштабирования будет использоваться KEDA в качестве контроллера, а Prometheus — для получения метрик, предоставляемых APISIX.

Как использовать Prometheus Scaler в KEDA
KEDA — это событийный автомасштабатор в Kubernetes, который может настраивать различные скалеры. В этой статье будет использоваться Prometheus scaler для получения метрик, предоставляемых APISIX.
Развертывание KEDA
Развертывание KEDA относительно просто: достаточно добавить соответствующий Helm-репозиторий и установить его.
(MoeLove) ➜ helm repo add kedacore https://kedacore.github.io/charts "kedacore" has been added to your repositories (MoeLove) ➜ helm repo update kedacore Hang tight while we grab the latest from your chart repositories... ...Successfully got an update from the "kedacore" chart repository Update Complete. ⎈Happy Helming!⎈ (MoeLove) ➜ helm install keda kedacore/keda --namespace keda --create-namespace NAME: keda LAST DEPLOYED: Thu Jan 19 00:01:00 2023 NAMESPACE: keda STATUS: deployed REVISION: 1 TEST SUITE: None
После установки Pod имеет статус Running, что указывает на успешную установку.
(MoeLove) ➜ kubectl -n keda get pods NAME READY STATUS RESTARTS AGE keda-operator-metrics-apiserver-6d4db7dcff-ck9qg 1/1 Running 0 36s keda-operator-5dd4748dcd-k8jjz 1/1 Running 0 36s
Развертывание Prometheus
Здесь мы используем Prometheus Operator для развертывания Prometheus. Prometheus Operator помогает быстро развернуть экземпляр Prometheus в Kubernetes и добавить правила мониторинга с помощью декларативной конфигурации.
Завершите установку Prometheus Operator, выполнив следующие шаги.
(MoeLove) ➜ https://github.com/prometheus-operator/prometheus-operator/releases/download/v0.62.0/bundle.yaml (MoeLove) ➜ kubectl apply --server-side -f bundle.yaml customresourcedefinition.apiextensions.k8s.io/alertmanagerconfigs.monitoring.coreos.com serverside-applied customresourcedefinition.apiextensions.k8s.io/alertmanagers.monitoring.coreos.com serverside-applied customresourcedefinition.apiextensions.k8s.io/podmonitors.monitoring.coreos.com serverside-applied customresourcedefinition.apiextensions.k8s.io/probes.monitoring.coreos.com serverside-applied customresourcedefinition.apiextensions.k8s.io/prometheuses.monitoring.coreos.com serverside-applied customresourcedefinition.apiextensions.k8s.io/prometheusrules.monitoring.coreos.com serverside-applied customresourcedefinition.apiextensions.k8s.io/servicemonitors.monitoring.coreos.com serverside-applied customresourcedefinition.apiextensions.k8s.io/thanosrulers.monitoring.coreos.com serverside-applied clusterrolebinding.rbac.authorization.k8s.io/prometheus-operator serverside-applied clusterrole.rbac.authorization.k8s.io/prometheus-operator serverside-applied deployment.apps/prometheus-operator serverside-applied serviceaccount/prometheus-operator serverside-applied service/prometheus-operator serverside-applied
Затем используйте следующую конфигурацию для Prometheus и примените ее к кластеру Kubernetes.
--- apiVersion: v1 kind: ServiceAccount metadata: name: prometheus --- apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRole metadata: name: prometheus rules: - apiGroups: [""] resources: - nodes - nodes/metrics - services - endpoints - pods verbs: ["get", "list", "watch"] - apiGroups: [""] resources: - configmaps verbs: ["get"] - apiGroups: - networking.k8s.io resources: - ingresses verbs: ["get", "list", "watch"] - nonResourceURLs: ["/metrics"] verbs: ["get"] --- apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRoleBinding metadata: name: prometheus roleRef: apiGroup: rbac.authorization.k8s.io kind: ClusterRole name: prometheus subjects: - kind: ServiceAccount name: prometheus namespace: default --- apiVersion: monitoring.coreos.com/v1 kind: Prometheus metadata: name: prometheus spec: serviceAccountName: prometheus serviceMonitorSelector: matchLabels: app: apisix serviceMonitorNamespaceSelector: matchLabels: team: apisix resources: requests: memory: 400Mi enableAdminAPI: false --- apiVersion: v1 kind: Service metadata: name: prometheus spec: type: LoadBalancer ports: - name: web port: 9090 protocol: TCP targetPort: web selector: prometheus: prometheus
После применения к кластеру Kubernetes вы увидите, что экземпляр Prometheus создан в пространстве имен default. Поскольку мы настроили Prometheus с TYPE LoadBalancer, пользователи могут напрямую обращаться к Prometheus через публичный IP-адрес LoadBalancer.
(MoeLove) ➜ kubectl get svc NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE kubernetes ClusterIP 10.43.0.1 <none> 443/TCP 96m prometheus-operator ClusterIP None <none> 8080/TCP 92m prometheus-operated ClusterIP None <none> 9090/TCP 41m prometheus LoadBalancer 10.43.125.194 216.6.66.66 9090:30099/TCP 41m
Как развернуть API-шлюз и включить мониторинг
Далее разверните APISIX Ingress controller и используйте Prometheus для сбора метрик.
Метод аналогичен для пользователей, которые используют только APISIX вместо APISIX Ingress Controller. Мы не будем отдельно объяснять это здесь.
Здесь для развертывания используется Helm, и APISIX Ingress controller и APISIX могут быть одновременно развернуты в кластере.
(MoeLove) ➜ helm repo add apisix https://charts.apiseven.com "apisix" already exists with the same configuration, skipping (MoeLove) ➜ helm repo update apisix Hang tight while we grab the latest from your chart repositories... ...Successfully got an update from the "apisix" chart repository Update Complete. ⎈Happy Helming!⎈ (MoeLove) ➜ helm upgrade --install apisix apisix/apisix --create-namespace --namespace apisix --set gateway.type=LoadBalancer --set ingress-controller.enabled=true --set ingress-controller.config.apisix.serviceNamespace=apisix Release "apisix" has been upgraded. Happy Helming! NAME: apisix LAST DEPLOYED: Thu Jan 19 02:11:23 2023 NAMESPACE: apisix STATUS: deployed REVISION: 1 TEST SUITE: None NOTES: 1. Get the application URL by running these commands: NOTE: It may take a few minutes for the LoadBalancer IP to be available. You can watch the status of by running 'kubectl get --namespace apisix svc -w apisix-gateway' export SERVICE_IP=$(kubectl get svc --namespace apisix apisix-gateway --template "{{ range (index .status.loadBalancer.ingress 0) }}{{.}}{{ end }}") echo http://$SERVICE_IP:80
Затем включите плагин Prometheus в APISIX. Пожалуйста, обратитесь к следующим двум документам для получения конкретных методов конфигурации и связанных параметров.
- prometheus plugins | Apache APISIX®
- How to access Apache APISIX Prometheus metrics on Kubernetes | Apache APISIX®
После включения Prometheus может захватывать метрики, предоставляемые APISIX, создав ресурс ServiceMonitor.
apiVersion: monitoring.coreos.com/v1 kind: ServiceMonitor metadata: name: example-app labels: app: apisix spec: selector: matchLabels: app: apisix endpoints: - port: web
Проверка возможности эластичного масштабирования приложения
Сначала создайте приложение.
(MoeLove) ➜ kubectl create deploy httpbin --image=kennethreitz/httpbin --port=80 deployment.apps/httpbin created (MoeLove) ➜ kubectl expose deploy httpbin --port 80
Создайте следующие правила маршрутизации и примените их к кластеру Kubernetes для проксирования запросов через APISIX.
apiVersion: apisix.apache.org/v2 kind: ApisixRoute metadata: name: httpserver-route spec: http: - name: rule1 match: hosts: - local.httpbin.org paths: - /* backends: - serviceName: httpbin servicePort: 80
Затем создайте KEDA ScaledObject и настройте конфигурации, связанные с Prometheus.
apiVersion: keda.sh/v1alpha1 kind: ScaledObject metadata: name: prometheus-scaledobject namespace: default spec: scaleTargetRef: name: httpbin triggers: - type: prometheus metadata: serverAddress: http://prometheus.default.svc:9090 metricName: apisix_http_status threshold: '10' query: sum(rate(apisix_http_status{route="httpserver-route"}[1m]))
Вышеуказанная конфигурация означает, что sum(rate(apisix_http_status{route="httpserver-route"}[1m])) используется в качестве выражения запроса, и если результат достигает 10, начнется масштабирование. (Эта конфигурация предназначена только для демонстрации, пожалуйста, измените ее в соответствии с вашими потребностями). Затем мы делаем непрерывные запросы к сервису httpbin через curl.
Позже, если мы проверим поды приложения, вы увидите, что KEDA автоматически масштабировал их до двух.
(MoeLove) ➜ kubectl get pods NAME READY STATUS RESTARTS AGE httpbin-d46d778d7-chtdw 1/1 Running 0 12m httpbin-d46d778d7-xanbj 1/1 Running 0 10s
Когда приложение простаивает некоторое время, мы обнаружим, что количество подов автоматически сократилось до одного экземпляра.
(MoeLove) ➜ kubectl get pods NAME READY STATUS RESTARTS AGE httpbin-d46d778d7-chtdw 1/1 Running 0 32m
Заключение
KEDA использует Prometheus в качестве скалера для сбора метрик, предоставляемых APISIX. Поскольку весь трафик сначала проходит через APISIX, получение статистики на стороне APISIX будет гораздо проще и удобнее.
Когда объем бизнес-запросов увеличивается, приложение автоматически масштабируется, а когда объем бизнес-запросов снижается, приложение автоматически сокращается.
Этот метод может облегчить ручные операции по масштабированию/сокращению во многих производственных средах, чтобы обеспечить наилучший пользовательский опыт.