La escalabilidad es un requisito clave para las aplicaciones en la nube. Con Kubernetes, escalar una aplicación es tan simple como aumentar la cantidad de réplicas para la implementación adecuada o ReplicaSet - pero es un proceso manual.
Kubernetes permite escalar automáticamente las aplicaciones (es decir, pods en una implementación o ReplicaSet) de forma declarativa utilizando la especificación Horizontal Pod Autoscaler. El criterio predeterminado para el escalado automático son las métricas de uso de CPU (métricas de recursos), pero puede integrar métricas personalizadas y proporcionadas externamente.
Equipo Kubernetes aaS de Mail.ru tradujo un artículo sobre cómo utilizar métricas externas para escalar automáticamente una aplicación Kubernetes. Para mostrar cómo funciona todo, el autor utiliza métricas de solicitud de acceso HTTP, que se recopilan mediante Prometheus.
En lugar del escalado automático horizontal de pods, se utiliza Kubernetes Event Driven Autoscaling (KEDA), un operador de Kubernetes de código abierto. Se integra de forma nativa con Horizontal Pod Autoscaler para proporcionar un escalado automático fluido (incluso hacia/desde cero) para cargas de trabajo basadas en eventos. Código disponible en GitHub.
Breve descripción general del sistema.
El diagrama muestra una breve descripción de cómo funciona todo:
La aplicación proporciona métricas de recuento de visitas HTTP en formato Prometheus.
Prometheus está configurado para recopilar estas métricas.
El escalador de Prometheus en KEDA está configurado para escalar automáticamente la aplicación en función del número de visitas HTTP.
Ahora te contaré en detalle sobre cada elemento.
KEDA y Prometeo
Prometheus es un conjunto de herramientas de alerta y monitoreo de sistemas de código abierto, parte Fundación de computación nativa de la nube. Recopila métricas de diversas fuentes y las almacena como datos de series temporales. Para visualizar datos puedes utilizar Grafana u otras herramientas de visualización que funcionan con la API de Kubernetes.
KEDA apoya el concepto de escalador: actúa como puente entre KEDA y el sistema externo. La implementación del escalador es específica de cada sistema de destino y extrae datos de él. Luego, KEDA los utiliza para controlar el escalado automático.
Los escaladores admiten múltiples fuentes de datos, por ejemplo, Kafka, Redis, Prometheus. Es decir, KEDA se puede utilizar para escalar automáticamente las implementaciones de Kubernetes utilizando las métricas de Prometheus como criterio.
Aplicación de prueba
La aplicación de prueba Golang proporciona acceso a través de HTTP y realiza dos funciones importantes:
Utiliza la biblioteca cliente de Prometheus Go para instrumentar la aplicación y proporcionar la métrica http_requests, que contiene un recuento de visitas. El punto final donde están disponibles las métricas de Prometheus se encuentra en el URI /metrics.
var httpRequestsCounter = promauto.NewCounter(prometheus.CounterOpts{
Name: "http_requests",
Help: "number of http requests",
})
En respuesta a una solicitud GET la aplicación incrementa el valor de la clave (access_count) en Redis. Esta es una manera fácil de hacer el trabajo como parte de un controlador HTTP y también verificar las métricas de Prometheus. El valor de la métrica debe ser el mismo que el valor. access_count en Redis.
La aplicación se implementa en Kubernetes a través de Deployment. También se crea un servicio. ClusterIP, permite al servidor Prometheus obtener métricas de la aplicación.
El escalador actúa como un puente entre KEDA y el sistema externo del cual se deben obtener las métricas. ScaledObject es un recurso personalizado que debe implementarse para sincronizar la implementación con el origen del evento, en este caso Prometheus.
ScaledObject contiene información de escala de implementación, metadatos de origen de eventos (como secretos de conexión, nombre de cola), intervalo de sondeo, período de recuperación y otros datos. Da como resultado el recurso de escalado automático correspondiente (definición de HPA) para escalar la implementación.
Cuando un objeto ScaledObject se elimina, se borra la definición HPA correspondiente.
Aquí está la definición ScaledObject para nuestro ejemplo, utiliza un escalador Prometheus:
Tipo de disparador - Prometheus. La dirección del servidor Prometheus se menciona junto con el nombre de la métrica, el umbral y consulta PromQL, que será utilizado. Consulta PromQL - sum(rate(http_requests[2m])).
según pollingIntervalKEDA solicita un objetivo a Prometheus cada quince segundos. Al menos uno menos (minReplicaCount), y el número máximo de vainas no excede maxReplicaCount (en este ejemplo, diez).
puede instalar minReplicaCount igual a cero. En este caso, KEDA activa la implementación de cero a uno y luego expone el HPA para un mayor escalamiento automático. También es posible el orden inverso, es decir, escalar de uno a cero. En el ejemplo, no seleccionamos cero porque se trata de un servicio HTTP y no de un sistema bajo demanda.
La magia dentro del autoescalado
El umbral se utiliza como disparador para escalar la implementación. En nuestro ejemplo, la consulta PromQL sum(rate (http_requests [2m])) devuelve la tasa de solicitudes HTTP agregada (solicitudes por segundo), medida durante los últimos dos minutos.
Dado que el valor umbral es tres, significa que habrá uno por debajo mientras el valor sum(rate (http_requests [2m])) menos que tres. Si el valor aumenta, se agrega un sub adicional cada vez sum(rate (http_requests [2m])) aumenta en tres. Por ejemplo, si el valor es de 12 a 14, entonces el número de pods es cuatro.
¡Ahora intentemos configurarlo!
Preajuste
Todo lo que necesitas es un clúster de Kubernetes y una utilidad configurada. kubectl. Este ejemplo utiliza un clúster minikube, pero puedes tomar cualquier otro. Para instalar un cluster hay руководство.
helm init inicializa la interfaz de línea de comando local y también instala Tiller al clúster de Kubernetes.
kubectl get pods -n kube-system | grep tiller
Espere a que el módulo Tiller entre en estado En ejecución.
Nota del traductor: El autor utiliza Helm@2, que requiere la instalación del componente del servidor Tiller. Ahora Helm@3 es relevante, no requiere una parte del servidor.
Después de instalar Helm, un comando es suficiente para iniciar 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
Comprueba que todo ha comenzado:
kubectl get pods -l=app=prometheus-server
Espere a que Prometheus entre en estado Running.
uso kubectl port-forward para acceder a la interfaz de usuario de Prometheus (o servidor API) en http://localhost:9090.
KEDA_POD_NAME=$(kubectl get pods -n keda
-o=jsonpath='{.items[0].metadata.name}')
kubectl logs $KEDA_POD_NAME -n keda
El resultado se parece a esto:
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"
Consulte en aplicaciones. Una instancia debe estar ejecutándose porque minReplicaCount es igual a 1:
kubectl get pods -l=app=go-prom-app
Verifique que el recurso HPA se haya creado correctamente:
kubectl get hpa
Deberías ver algo como:
NAME REFERENCE TARGETS MINPODS MAXPODS REPLICAS AGE
keda-hpa-go-prom-app Deployment/go-prom-app 0/3 (avg) 1 10 1 45s
Control de salud: acceso a la aplicación
Para acceder al punto final REST de nuestra aplicación, ejecute:
Ahora puede acceder a su aplicación Go usando la dirección http://localhost:8080. Para hacer esto, ejecute el comando:
curl http://localhost:8080/test
El resultado se parece a esto:
Accessed on 2019-10-21 11:29:10.560385986 +0000 UTC
m=+406004.817901246
Access count 1
En este punto, consulte también Redis. Verás que la clave access_count aumentado a 1:
kubectl exec -it redis-server-master-0 -- redis-cli get access_count
//output
"1"
Asegúrese de que el valor de la métrica sea http_requests lo mismo:
curl http://localhost:8080/metrics | grep http_requests
//output
# HELP http_requests number of http requests
# TYPE http_requests counter
http_requests 1
En este caso el resultado real es 1,686057971014493 y se muestra en el campo value. Esto no es suficiente para escalar, ya que el umbral que establecemos es 3.
¡Más carga!
En la nueva terminal, controle la cantidad de pods de aplicaciones:
kubectl get pods -l=app=go-prom-app -w
Aumentemos la carga usando el comando:
./hey -n 2000 http://localhost:8080/test
Después de un tiempo, verá que HPA escala la implementación y lanza nuevos pods. Verifique su HPA para asegurarse de:
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
Si la carga es inconsistente, la implementación se reducirá hasta el punto en que solo se esté ejecutando un pod. Si desea verificar la métrica real (devuelta por la consulta PromQL), use el comando:
//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
Conclusión
KEDA le permite escalar automáticamente sus implementaciones de Kubernetes (hacia/desde cero) en función de datos de métricas externas. Por ejemplo, según las métricas de Prometheus, la longitud de la cola en Redis y la latencia del consumidor en el tema Kafka.
KEDA se integra con una fuente externa y también proporciona sus métricas a través de Metrics Server al Horizontal Pod Autoscaler.