A escalabilidade é un requisito fundamental para as aplicacións na nube. Con Kubernetes, escalar unha aplicación é tan sinxelo como aumentar o número de réplicas para a implantación adecuada ou ReplicaSet - pero é un proceso manual.
Kubernetes permite que as aplicacións se escalan automaticamente (por exemplo, pods nunha implementación ou ReplicaSet) de forma declarativa utilizando a especificación Horizontal Pod Autoscaler. O criterio predeterminado para a escala automática son as métricas de uso da CPU (métricas de recursos), pero podes integrar métricas personalizadas e proporcionadas externamente.
Equipo Kubernetes aaS de Mail.ru traduciu un artigo sobre como usar métricas externas para escalar automaticamente unha aplicación de Kubernetes. Para mostrar como funciona todo, o autor usa métricas de solicitude de acceso HTTP, que se recollen mediante Prometheus.
En lugar da escala automática horizontal dos pods, utilízase Kubernetes Event Driven Autoscaling (KEDA), un operador de Kubernetes de código aberto. Intégrase de forma nativa co Horizontal Pod Autoscaler para proporcionar un autoescalado continuo (incluíndo a/desde cero) para cargas de traballo dirixidas por eventos. Código dispoñible en GitHub.
Breve descrición do sistema
O diagrama mostra unha breve descrición de como funciona todo:
A aplicación ofrece métricas de conta de accesos HTTP en formato Prometheus.
Prometheus está configurado para recoller estas métricas.
O escalador de Prometheus en KEDA está configurado para escalar automaticamente a aplicación en función do número de accesos HTTP.
Agora vouvos falar en detalle de cada elemento.
KEDA e Prometeo
Prometheus é un conxunto de ferramentas de monitorización e alerta de sistemas de código aberto, parte Fundación Cloud Native Computing. Recopila métricas de varias fontes e gárdaas como datos de series temporais. Para visualizar os datos pode usar grafana ou outras ferramentas de visualización que funcionen coa API de Kubernetes.
KEDA admite o concepto de escalador: actúa como ponte entre KEDA e o sistema externo. A implementación do escalador é específica para cada sistema obxectivo e extrae datos del. A continuación, KEDA utilízaos para controlar a escala automática.
Os escaladores admiten varias fontes de datos, por exemplo, Kafka, Redis, Prometheus. É dicir, KEDA pódese usar para escalar automaticamente as implantacións de Kubernetes usando as métricas de Prometheus como criterios.
Aplicación de proba
A aplicación de proba Golang proporciona acceso vía HTTP e realiza dúas funcións importantes:
Usa a biblioteca cliente de Prometheus Go para instrumentar a aplicación e proporcionar a métrica http_requests, que contén un reconto de acertos. O punto final onde están dispoñibles as métricas de Prometheus está situado no URI /metrics.
var httpRequestsCounter = promauto.NewCounter(prometheus.CounterOpts{
Name: "http_requests",
Help: "number of http requests",
})
En resposta a unha solicitude GET a aplicación aumenta o valor da chave (access_count) en Redis. Este é un xeito sinxelo de facer o traballo como parte dun manejador HTTP e tamén de comprobar as métricas de Prometheus. O valor da métrica debe ser o mesmo que o valor access_count en Redis.
A aplicación está implantada en Kubernetes mediante Deployment. Tamén se crea un servizo ClusterIP, permite ao servidor Prometheus obter métricas da aplicación.
O escalador actúa como ponte entre KEDA e o sistema externo do que se deben obter as métricas. ScaledObject é un recurso personalizado que é necesario despregar para sincronizar a implantación coa fonte do evento, neste caso Prometheus.
ScaledObject contén información de escala de implantación, metadatos da fonte de eventos (como segredos de conexión, nome da cola), intervalo de sondeo, período de recuperación e outros datos. Dá como resultado o recurso de escalado automático correspondente (definición HPA) para escalar a implantación.
Cando un obxecto ScaledObject se elimina, borra a definición HPA correspondente.
Aquí está a definición ScaledObject para o noso exemplo, usa un escalador Prometheus:
Tipo de disparador - Prometheus. Menciónase o enderezo do servidor Prometheus xunto co nome da métrica, o limiar e Consulta PromQL, que se utilizará. Consulta PromQL - sum(rate(http_requests[2m])).
Conforme pollingInterval,KEDA solicita un obxectivo a Prometheus cada quince segundos. Polo menos un baixo (minReplicaCount), e o número máximo de vainas non supera maxReplicaCount (neste exemplo - dez).
Pódese instalar minReplicaCount igual a cero. Neste caso, KEDA activa o despregamento cero a un e despois expón o HPA para un maior escalado automático. Tamén é posible a orde inversa, é dicir, escalar de un a cero. No exemplo, non seleccionamos cero porque se trata dun servizo HTTP e non dun sistema baixo demanda.
A maxia dentro do autoscaling
O limiar úsase como disparador para escalar a implantación. No noso exemplo, a consulta PromQL sum(rate (http_requests [2m])) devolve a taxa de solicitude HTTP agregada (solicitudes por segundo), medida nos últimos dous minutos.
Dado que o valor límite é tres, significa que haberá un por debaixo do valor sum(rate (http_requests [2m])) menos de tres. Se o valor aumenta, engádese un sub adicional cada vez sum(rate (http_requests [2m])) aumenta en tres. Por exemplo, se o valor é de 12 a 14, entón o número de pods é catro.
Agora imos tentar configuralo!
Configuración previa
Todo o que necesitas é un clúster de Kubernetes e unha utilidade configurada kubectl. Este exemplo usa un clúster minikube, pero podes levar calquera outro. Para instalar un clúster hai liderado.
helm init inicializa a interface de liña de comandos local e tamén instala Tiller ao clúster de Kubernetes.
kubectl get pods -n kube-system | grep tiller
Agarde a que o tiller pod entre no estado de execución.
Nota do tradutor: O autor usa Helm@2, que require a instalación do compoñente do servidor Tiller. Agora Helm@3 é relevante, non require unha parte do servidor.
Despois de instalar Helm, un comando é 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
Comproba que todo comezou:
kubectl get pods -l=app=prometheus-server
Agarda a que Prometeo entre en estado Running.
Usar kubectl port-forward para acceder á interface de usuario de Prometheus (ou ao 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
O resultado parece algo así:
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"
Consulta nas aplicacións. Debe estar executando unha instancia porque minReplicaCount é igual a 1:
kubectl get pods -l=app=go-prom-app
Verifique que o recurso HPA se creou correctamente:
kubectl get hpa
Deberías ver algo así como:
NAME REFERENCE TARGETS MINPODS MAXPODS REPLICAS AGE
keda-hpa-go-prom-app Deployment/go-prom-app 0/3 (avg) 1 10 1 45s
Verificación de saúde: acceso á aplicación
Para acceder ao punto final REST da nosa aplicación, executa:
Agora podes acceder á túa aplicación Go usando o enderezo http://localhost:8080. Para facelo, execute o comando:
curl http://localhost:8080/test
O resultado parece algo así:
Accessed on 2019-10-21 11:29:10.560385986 +0000 UTC
m=+406004.817901246
Access count 1
Neste punto tamén comprobe Redis. Verás que a clave access_count aumentado a 1:
kubectl exec -it redis-server-master-0 -- redis-cli get access_count
//output
"1"
Asegúrese de que o valor da métrica é http_requests o mesmo:
curl http://localhost:8080/metrics | grep http_requests
//output
# HELP http_requests number of http requests
# TYPE http_requests counter
http_requests 1
Neste caso o resultado real é 1,686057971014493 e móstrase no campo value. Isto non é suficiente para escalar, xa que o limiar que establecemos é 3.
Máis carga!
No novo terminal, supervisa o número de módulos de aplicacións:
kubectl get pods -l=app=go-prom-app -w
Aumentemos a carga usando o comando:
./hey -n 2000 http://localhost:8080/test
Despois dun tempo, verás que HPA escala a implantación e lanza novos pods. Comprobe o seu 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
Se a carga é inconsistente, o despregamento reducirase ata o punto no que só se está a executar un pod. Se desexa comprobar a métrica real (devolta pola consulta PromQL), use o 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 permíteche escalar automaticamente as túas implementacións de Kubernetes (desde e ata cero) en función de datos de métricas externas. Por exemplo, en función das métricas de Prometheus, a lonxitude da cola en Redis, a latencia do consumidor no tema de Kafka.
KEDA intégrase cunha fonte externa e tamén proporciona as súas métricas a través do servidor de métricas ao Horizontal Pod Autoscaler.