L'évolutivité est une exigence clé pour les applications cloud. Avec Kubernetes, faire évoluer une application est aussi simple que d'augmenter le nombre de réplicas pour le déploiement approprié ou ReplicaSet - mais c'est un processus manuel.
Kubernetes permet aux applications d'être automatiquement mises à l'échelle (c'est-à-dire les pods dans un déploiement ou ReplicaSet) de manière déclarative à l'aide de la spécification Horizontal Pod Autoscaler. Le critère par défaut pour la mise à l'échelle automatique est les métriques d'utilisation du processeur (métriques de ressources), mais vous pouvez intégrer des métriques personnalisées et fournies en externe.
Équipe Kubernetes aaS de Mail.ru a traduit un article sur la façon d'utiliser des métriques externes pour faire évoluer automatiquement une application Kubernetes. Pour montrer comment tout fonctionne, l'auteur utilise des métriques de requêtes d'accès HTTP, qui sont collectées à l'aide de Prometheus.
Au lieu de la mise à l'échelle automatique horizontale des pods, Kubernetes Event Driven Autoscaling (KEDA) est utilisé, un opérateur Kubernetes open source. Il s'intègre nativement à Horizontal Pod Autoscaler pour fournir une mise à l'échelle automatique transparente (y compris vers/depuis zéro) pour les charges de travail basées sur des événements. Code disponible sur GitHub.
Bref aperçu du système
Le diagramme montre une brève description de la façon dont tout fonctionne :
L'application fournit des mesures du nombre d'accès HTTP au format Prometheus.
Prometheus est configuré pour collecter ces métriques.
Le scaler Prometheus dans KEDA est configuré pour mettre automatiquement à l'échelle l'application en fonction du nombre d'accès HTTP.
Je vais maintenant vous parler en détail de chaque élément.
KEDA et Prométhée
Prometheus est une boîte à outils open source de surveillance et d'alerte du système, qui fait partie Fondation Cloud Native Computing. Collecte des métriques provenant de diverses sources et les stocke sous forme de données de séries chronologiques. Pour visualiser les données, vous pouvez utiliser grafana ou d'autres outils de visualisation qui fonctionnent avec l'API Kubernetes.
KEDA soutient le concept de scaler - il agit comme un pont entre KEDA et le système externe. L'implémentation du scaler est spécifique à chaque système cible et en extrait les données. KEDA les utilise ensuite pour contrôler la mise à l'échelle automatique.
Les scalers prennent en charge plusieurs sources de données, par exemple Kafka, Redis, Prometheus. Autrement dit, KEDA peut être utilisé pour faire évoluer automatiquement les déploiements Kubernetes en utilisant les métriques Prometheus comme critères.
Tester l'application
L'application de test Golang fournit un accès via HTTP et remplit deux fonctions importantes :
Utilise la bibliothèque client Prometheus Go pour instrumenter l'application et fournir la métrique http_requests, qui contient un nombre d'accès. Le point de terminaison où les métriques Prometheus sont disponibles est situé au niveau de l'URI /metrics.
var httpRequestsCounter = promauto.NewCounter(prometheus.CounterOpts{
Name: "http_requests",
Help: "number of http requests",
})
En réponse à une demande GET l'application incrémente la valeur de la clé (access_count) dans Redis. Il s'agit d'un moyen simple d'effectuer le travail dans le cadre d'un gestionnaire HTTP et également de vérifier les métriques Prometheus. La valeur de la métrique doit être la même que la valeur access_count dans Redis.
L'application est déployée sur Kubernetes via Deployment. Un service est également créé ClusterIP, il permet au serveur Prometheus d'obtenir des métriques d'application.
Le scaler agit comme un pont entre KEDA et le système externe à partir duquel les métriques doivent être obtenues. ScaledObject est une ressource personnalisée qui doit être déployée pour synchroniser le déploiement avec la source d'événement, dans ce cas Prometheus.
ScaledObject contient des informations de mise à l'échelle du déploiement, des métadonnées de source d'événements (telles que les secrets de connexion, le nom de la file d'attente), l'intervalle d'interrogation, la période de récupération et d'autres données. Il en résulte la ressource de mise à l'échelle automatique correspondante (définition HPA) pour faire évoluer le déploiement.
Lorsqu'un objet ScaledObject est supprimé, la définition HPA correspondante est effacée.
Voici la définition ScaledObject pour notre exemple, il utilise un scaler Prometheus:
Type de déclencheur - Prometheus. L'adresse du serveur Prometheus est mentionnée avec le nom de la métrique, le seuil et Requête PromQL, qui sera utilisé. Requête PromQL - sum(rate(http_requests[2m])).
selon pollingInterval,KEDA demande une cible à Prometheus toutes les quinze secondes. Au moins un sous (minReplicaCount), et le nombre maximum de pods ne dépasse pas maxReplicaCount (dans cet exemple - dix).
Peut installer minReplicaCount égal à zéro. Dans ce cas, KEDA active le déploiement de zéro à un, puis expose le HPA pour une mise à l'échelle automatique ultérieure. L'ordre inverse est également possible, c'est-à-dire une mise à l'échelle de un à zéro. Dans l'exemple, nous n'avons pas sélectionné zéro car il s'agit d'un service HTTP et non d'un système à la demande.
La magie de l'autoscaling
Le seuil est utilisé comme déclencheur pour faire évoluer le déploiement. Dans notre exemple, la requête PromQL sum(rate (http_requests [2m])) renvoie le taux de requêtes HTTP agrégé (requêtes par seconde), mesuré au cours des deux dernières minutes.
Puisque la valeur seuil est de trois, cela signifie qu'il y en aura un en dessous tant que la valeur sum(rate (http_requests [2m])) moins de trois. Si la valeur augmente, un sous supplémentaire est ajouté à chaque fois sum(rate (http_requests [2m])) augmente de trois. Par exemple, si la valeur est comprise entre 12 et 14, le nombre de pods est de quatre.
Essayons maintenant de le configurer !
préréglage
Tout ce dont vous avez besoin est un cluster Kubernetes et un utilitaire configuré kubectl. Cet exemple utilise un cluster minikube, mais vous pouvez en prendre un autre. Pour installer un cluster il y a руководство.
helm init initialise l'interface de ligne de commande locale et installe également Tiller au cluster Kubernetes.
kubectl get pods -n kube-system | grep tiller
Attendez que le pod Tiller passe à l'état En cours d'exécution.
Note du traducteur: L'auteur utilise Helm@2, qui nécessite l'installation du composant serveur Tiller. Désormais Helm@3 est pertinent, il ne nécessite pas de partie serveur.
Après avoir installé Helm, une seule commande suffit pour démarrer 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
Vérifiez que tout a démarré :
kubectl get pods -l=app=prometheus-server
Attendez que Prométhée entre en état Running.
utilisation kubectl port-forward pour accéder à l'interface utilisateur Prometheus (ou au serveur API) à l'adresse http://localhost:9090.
KEDA_POD_NAME=$(kubectl get pods -n keda
-o=jsonpath='{.items[0].metadata.name}')
kubectl logs $KEDA_POD_NAME -n keda
Le résultat ressemble à ceci :
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"
Vérifiez sous les candidatures. Une instance doit être en cours d'exécution car minReplicaCount est égal à 1 :
kubectl get pods -l=app=go-prom-app
Vérifiez que la ressource HPA a été créée avec succès :
kubectl get hpa
Vous devriez voir quelque chose comme :
NAME REFERENCE TARGETS MINPODS MAXPODS REPLICAS AGE
keda-hpa-go-prom-app Deployment/go-prom-app 0/3 (avg) 1 10 1 45s
Bilan de santé : accès aux applications
Pour accéder au point de terminaison REST de notre application, exécutez :
Vous pouvez désormais accéder à votre application Go en utilisant l'adresse http://localhost:8080. Pour ce faire, exécutez la commande :
curl http://localhost:8080/test
Le résultat ressemble à ceci :
Accessed on 2019-10-21 11:29:10.560385986 +0000 UTC
m=+406004.817901246
Access count 1
À ce stade, vérifiez également Redis. Vous verrez que la clé access_count augmenté à 1 :
kubectl exec -it redis-server-master-0 -- redis-cli get access_count
//output
"1"
Assurez-vous que la valeur métrique est http_requests le même:
curl http://localhost:8080/metrics | grep http_requests
//output
# HELP http_requests number of http requests
# TYPE http_requests counter
http_requests 1
Création de charge
Nous utiliserons hé — utilitaire de génération de charge :
Dans ce cas, le résultat réel est 1,686057971014493 et s'affiche dans le champ value. Ce n'est pas suffisant pour la mise à l'échelle, puisque le seuil que nous fixons est de 3.
Plus de charge !
Dans le nouveau terminal, surveillez le nombre de pods d'application :
kubectl get pods -l=app=go-prom-app -w
Augmentons la charge à l'aide de la commande :
./hey -n 2000 http://localhost:8080/test
Après un certain temps, vous verrez HPA étendre le déploiement et lancer de nouveaux pods. Vérifiez votre HPA pour vous assurer :
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 charge est incohérente, le déploiement sera réduit au point où un seul pod est en cours d'exécution. Si vous souhaitez vérifier la métrique réelle (renvoyée par la requête PromQL), utilisez la commande :
//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
Conclusion
KEDA vous permet de faire évoluer automatiquement vos déploiements Kubernetes (de/vers zéro) en fonction des données provenant de métriques externes. Par exemple, sur la base des métriques Prometheus, de la longueur de la file d'attente dans Redis, de la latence du consommateur dans le sujet Kafka.
KEDA s'intègre à une source externe et fournit également ses métriques via Metrics Server à Horizontal Pod Autoscaler.