Usa APISIX, Prometheus y KEDA para escalar aplicaciones de manera elástica en Kubernetes
February 17, 2023
Introducción
La cantidad de tráfico que entra en una aplicación varía de vez en cuando. Por ejemplo, una aplicación de compras en línea está mucho más ocupada durante la temporada navideña que en días normales. Poder ajustar la capacidad de la aplicación en función del tráfico proporcionará experiencias y servicios mucho mejores para los usuarios.
Apache APISIX es una puerta de enlace API nativa de la nube de alto rendimiento que puede proporcionar métricas significativas para determinar si las aplicaciones necesitan escalarse. Es un middleware que procesa todo el tráfico enviado a las aplicaciones upstream y, por lo tanto, puede recopilar datos de tráfico durante el proceso.
Para realizar un escalado elástico, se utilizará KEDA como controlador, y Prometheus se utilizará para obtener las métricas proporcionadas por APISIX.
Cómo usar el escalador Prometheus en KEDA
KEDA es un escalador automático basado en eventos en Kubernetes, que puede configurar varios escaladores. En este artículo, se utilizará el escalador Prometheus para obtener las métricas expuestas por APISIX.
Desplegar KEDA
El despliegue de KEDA es relativamente simple, solo hay que agregar el repositorio de Helm correspondiente e instalarlo.
(MoeLove) ➜ helm repo add kedacore https://kedacore.github.io/charts
"kedacore" ha sido agregado a tus repositorios
(MoeLove) ➜ helm repo update kedacore
Espera mientras obtenemos lo último de tus repositorios de gráficos...
...Se ha obtenido con éxito una actualización del repositorio de gráficos "kedacore"
Actualización completa. ⎈¡Feliz navegación!⎈
(MoeLove) ➜ helm install keda kedacore/keda --namespace keda --create-namespace
NAME: keda
ÚLTIMO DESPLIEGUE: Jue 19 Ene 00:01:00 2023
NAMESPACE: keda
ESTADO: desplegado
REVISIÓN: 1
SUITE DE PRUEBAS: Ninguna
Después de la instalación, el Pod tiene un estado Running
, lo que indica que se ha instalado correctamente.
(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
Desplegar Prometheus
Aquí utilizamos Prometheus Operator para desplegar Prometheus. Prometheus Operator puede ayudarnos a desplegar rápidamente la instancia de Prometheus en Kubernetes y agregar las reglas de monitoreo mediante configuración declarativa.
Completa la instalación de Prometheus Operator siguiendo los siguientes pasos.
(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 aplicado del lado del servidor
customresourcedefinition.apiextensions.k8s.io/alertmanagers.monitoring.coreos.com aplicado del lado del servidor
customresourcedefinition.apiextensions.k8s.io/podmonitors.monitoring.coreos.com aplicado del lado del servidor
customresourcedefinition.apiextensions.k8s.io/probes.monitoring.coreos.com aplicado del lado del servidor
customresourcedefinition.apiextensions.k8s.io/prometheuses.monitoring.coreos.com aplicado del lado del servidor
customresourcedefinition.apiextensions.k8s.io/prometheusrules.monitoring.coreos.com aplicado del lado del servidor
customresourcedefinition.apiextensions.k8s.io/servicemonitors.monitoring.coreos.com aplicado del lado del servidor
customresourcedefinition.apiextensions.k8s.io/thanosrulers.monitoring.coreos.com aplicado del lado del servidor
clusterrolebinding.rbac.authorization.k8s.io/prometheus-operator aplicado del lado del servidor
clusterrole.rbac.authorization.k8s.io/prometheus-operator aplicado del lado del servidor
deployment.apps/prometheus-operator aplicado del lado del servidor
serviceaccount/prometheus-operator aplicado del lado del servidor
service/prometheus-operator aplicado del lado del servidor
Luego, utiliza lo siguiente como configuración para Prometheus y aplícalo al clúster de 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
Después de aplicar al clúster de Kubernetes, puedes ver que se ha creado una instancia de Prometheus en el espacio de nombres default
. Dado que configuramos Prometheus con TYPE LoadBalancer
, los usuarios pueden acceder directamente a Prometheus a través de la IP pública del 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
Cómo desplegar la puerta de enlace API y habilitar el monitoreo
A continuación, despliega el controlador de entrada APISIX y utiliza Prometheus para la recopilación de métricas.
El método es similar para los usuarios que solo usan APISIX en lugar del controlador de entrada APISIX. No lo explicaremos por separado aquí.
Aquí, se utiliza Helm para el despliegue, y el controlador de entrada APISIX y APISIX pueden desplegarse simultáneamente en el clúster.
(MoeLove) ➜ helm repo add apisix https://charts.apiseven.com
"apisix" ya existe con la misma configuración, omitiendo
(MoeLove) ➜ helm repo update apisix
Espera mientras obtenemos lo último de tus repositorios de gráficos...
...Se ha obtenido con éxito una actualización del repositorio de gráficos "apisix"
Actualización completa. ⎈¡Feliz navegación!⎈
(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
El lanzamiento "apisix" ha sido actualizado. ¡Feliz navegación!
NAME: apisix
ÚLTIMO DESPLIEGUE: Jue 19 Ene 02:11:23 2023
NAMESPACE: apisix
ESTADO: desplegado
REVISIÓN: 1
SUITE DE PRUEBAS: Ninguna
NOTAS:
1. Obtén la URL de la aplicación ejecutando estos comandos:
NOTA: Puede tardar unos minutos en estar disponible la IP del LoadBalancer.
Puedes ver el estado ejecutando '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
A continuación, habilita el plugin de Prometheus de APISIX. Consulta los siguientes dos documentos para obtener métodos de configuración específicos y parámetros relacionados.
- plugins de prometheus | Apache APISIX®
- Cómo acceder a las métricas de Prometheus de Apache APISIX en Kubernetes | Apache APISIX®
Una vez habilitado, Prometheus puede capturar las métricas expuestas por APISIX creando un recurso ServiceMonitor.
apiVersion: monitoring.coreos.com/v1
kind: ServiceMonitor
metadata:
name: example-app
labels:
app: apisix
spec:
selector:
matchLabels:
app: apisix
endpoints:
- port: web
Verificar la capacidad de escalado elástico de la aplicación
Primero, crea una aplicación.
(MoeLove) ➜ kubectl create deploy httpbin --image=kennethreitz/httpbin --port=80
deployment.apps/httpbin creado
(MoeLove) ➜ kubectl expose deploy httpbin --port 80
Crea las siguientes reglas de enrutamiento y aplícalas al clúster de Kubernetes para redirigir las solicitudes a través de 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
A continuación, crea un ScaledObject de KEDA y configura las configuraciones relacionadas con 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]))
La configuración anterior significa que se utiliza sum(rate(apisix_http_status{route="httpserver-route"}[1m]))
como expresión de consulta, y si el resultado puede alcanzar 10, comenzará la expansión. (La configuración aquí es solo para fines de demostración, modifícala según tu propia situación). Luego, realizamos solicitudes continuas al servicio httpbin mediante curl.
Más tarde, si verificamos los pods de la aplicación, puedes ver que KEDA la ha escalado automáticamente a dos.
(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
Cuando la aplicación permanece inactiva después de un tiempo, encontraremos que el número de pods se ha reducido automáticamente a una instancia.
(MoeLove) ➜ kubectl get pods
NAME READY STATUS RESTARTS AGE
httpbin-d46d778d7-chtdw 1/1 Running 0 32m
Resumen
KEDA utiliza Prometheus como escalador para recopilar las métricas expuestas por APISIX. Dado que todo el tráfico pasa primero por APISIX, obtener estadísticas en el lado de APISIX será mucho más simple y conveniente.
Cuando el volumen de solicitudes comerciales aumenta, la aplicación se expandirá automáticamente, y cuando el volumen de solicitudes comerciales disminuya, la aplicación se reducirá automáticamente.
Este método puede aliviar las operaciones manuales de expansión/reducción en muchos entornos de producción para garantizar la mejor experiencia de usuario.