Habituellement, ce scaling se fait via des métriques système, comme l’utilisation CPU ou mémoire. C’est en effet les métriques par défaut des horizontal pods autoscalers de Kubernetes, la ressource de base de l’autoscaling pour cette technologie :
spec:
maxReplicas: 3 # Nombre maximal de réplicas
metrics:
- resource:
name: cpu # Métrique utilisée pour le scaling
target:
averageUtilization: 50 # Utilisation moyenne visée
type: Utilization
type: Resource
minReplicas: 1 # Nombre minimal de réplicas
scaleTargetRef:
apiVersion: apps/v1
kind: Deployment
name: ingress-nginx-controller # Cible du scaling
Exemple de HPA et explications utilisant les métriques de CPU et de mémoire pour faire son scaling
Voici donc un exemple de Horizontal Pod Autoscaler utilisant les métriques de mémoire et de CPU pour faire un son autoscaling. On voit donc une variation du nombre de replicas entre 5 et 20, avec pour objectif d’avoir une utilisation CPU proche des 50%. Il est aussi possible de faire ce scaling via la mémoire, mais c’est une solution plus dangereuse car certaines applications ne consomment pas plus de mémoire en fonction de leur utilisation.
Il est aussi possible de faire de l’autoscaling en dehors de Kubernetes, comme par exemple pour des tasks ECS dans AWS, en utilisant les autoscalings groups.
(716 < CPU < +Infinity correspond à plus de 70% (716/1024 = 0,7)
Voici un example d’autoscaling d’une task ECS. Cette task va avoir 5 nouvelles replicas quand son utilisation CPU moyenne dépasse les 70% et va perdre 3 replicas quand son utilisation CPU moyenne descend en dessous des 60%.
Une technologie similaire existe chez GCP : les Managed Instances et autoscaling groups. Il est donc possible de faire cet autoscaling directement via les outils des cloud providers, même sur les machines virtuelles directement, comme avec les autoscalings groups d’AWS
Cependant, cette méthode ne permet pas de résoudre tous les problèmes de scaling.
Cependant, il arrive que ces métriques ne suffisent pas. Prenons par exemple une application qui fonctionne de la manière suivante :
Que se passerait-il si 8 requêtes longues arrivent en même temps sur cette application ?
Les 8 workers de l’application seraient occupés à traiter les requêtes en base de données, et l’application refuserait les requêtes courtes car aucun workers n'est disponible. Cependant, il n’y aurait aucune charge sur le CPU ou sur la mémoire, car les workers seraient uniquement en attente de réponse de la base de données. L’application ne scalerait donc pas si il y l'autoscaling en place se basait seulement sur les métriques CPU ou mémoire.
Dans notre cas, il est donc utile de mettre en place un autoscaling utilisant d’autre métriques que les ressources des machines. On peut ainsi à avoir un autoscaling en place utilisant des métriques orientée vers l’expérience utilisateur et non les statistiques de la machine, comme le nombre de requêtes ou le temps de réponse de l’application, avec des outils externes qui mesurent ces données.
Dans notre cas, une solution envisagée serait de mettre en place un scaling sur le nombre de requêtes et le temps de réponse de l’application, données qui seraient récupérées au niveau du load balancer de l’application. En effet, dans notre cas, le temps de réponse de l’application augmenterait fortement lorsque les workers ne sont pas disponibles, l’application scalerait pour ajouter de nouveaux worker et absorber la charge. De plus, l’application scalerait en fonction du nombre de requêtes, ce qui permet aussi de traiter la variation de traffic pendant la journée.
Nombre de requêtes par seconde
Nombre de conteneurs voulus
On vois ainsi la corrélation entre le nombre de requête et les nombre de conteneurs du service, montrant que l’autoscaling suit le nombre de requête que l’application reçois
Il existe plusieurs méthodes pour mettre en place ce type de scaling, voici donc une méthode utilisant les métriques cloudwatch et les autoscaling groups aws. Pour faire son scaling, le composant responsable de l’autoscaling dans AWS va récupérer les métriques du load balancer servant d'entrée dans les services, et plus particulièrement les métriques suivantes :
L’objectif va donc être d’augmenter le nombre de replicas quand le temps de réponse dépasse un certain seuil, et quand le nombre de requêtes dépasse un certain seuil, pour éviter d’augmenter le nombre de réplicas en l’absence de traffic. Il sera aussi possible de réduire le nombre de replicas quand le temps de réponse sera revenu à des valeurs plus faibles.
En conclusion cet article vous a présenté une solution de scaling, utilisant des métriques métiers tels que le temps de réponse et le nombre de requêtes, cette solution étant une alternative au scaling utilisant les métriques CPU et mémoire. Il existe cependant d’autres méthodes pour faire ce type de scaling, notamment en utilisant Keda sur Kubernetes