Usa APISIX, Prometheus y KEDA para escalar aplicaciones de manera elástica en Kubernetes

Jintao Zhang

Jintao Zhang

February 17, 2023

Technology

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.

usando KEDA para el escalado automático

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.

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.

Tags: