Kubernetes prend en charge l'autoscaling horizontal (augmentation / diminution du nombre de pods ) de pods basé sur la consommation de CPU et de mémoire.
Cependant, il est de fois nécessaire de configurer de l'autoscaling sur autre chose que ces metrics-là, comme par exemple le nombre de visiteurs sur votre application web, de l'heure de la journée, ou même d'un résultat d'une requête API.
L'autoscaling avec HPA (Horizontal Pod Autoscaler) de Kubernetes permet de gérer automatiquement le nombre de réplicas d'un déploiement en fonction de la charge de travail.
Il utilise des métriques telles que la CPU ou la mémoire pour déterminer si le nombre de réplicas doit être augmenté ou diminué. Les utilisateurs peuvent définir des seuils pour déclencher l'ajout ou la suppression de réplicas.
HPA utilise les informations de la pile de surveillance Kubernetes pour obtenir des informations sur l'état des pods et de la charge de travail.
L'algorithme HPA de Kubernetes surveille en permanence les métriques de la charge de travail et utilise des règles de scalabilité pour déterminer s'il faut ajouter ou supprimer des réplicas.
Kubernetes utilise un rapport entre les valeurs métriques actuelles et souhaitées pour permettre l'autoscaling.
Voici la formule :
desiredReplicas = ceil[currentReplicas * ( currentMetricValue / desiredMetricValue )]
Si nous avons un déploiement mon-application
avec un réplica qui requests
100Mi
de mémoire :
resources:
limits:
cpu: 500m
memory: "500Mi"
requests:
cpu: 100m
memory: "100Mi"
Et un object HPA comme ci-dessous :
apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
name: mon-application-hpa
spec:
scaleTargetRef:
apiVersion: apps/v1
kind: Deployment
name: mon-application # Nom de notre deploiement
minReplicas: 1 # Le nombre minimum de replicas
maxReplicas: 10 # Le nombre maximum de replicas
metrics:
- type: Resource
resource:
name: memory # Type de ressource qu'on veux vérifier
target:
type: Utilization
averageUtilization: 50 # Pourcentage de consomation de la memoire par replicas qu'on désire soit 50% de la mémoire request du pod (50Mi)
Et qu'on génère la consommation de la mémoire de ce pods à environ 100Mi
, alors le système HPA de Kubernetes va augmenter le nombre de pods à 2 :
Nombre_de_replicas = 1 * (100/50)
Nombre_de_replicas = 2
KEDA est un composant très léger qui peut être installé sur n'importe quel cluster Kubernetes. Il
fonctionne avec des composants Kubernetes standard tel que HPA sans pour autant le remplacer.
Les scalers KEDA peuvent à la fois détecter si un déploiement doit être activé ou désactivé, et fournir des métriques personnalisées pour une source d'événement spécifique.
Lors de la création d'un objet KEDA, Kubernetes va automatiquement créer un HPA qui sera affilié à notre objet KEDA. Le fait d'utiliser KEDA va nous permettre de réduire le nombre de réplicas à 0, ce qui n'est pas possible avec seulement HPA.
Il est possible de configurer Keda très facilement à l'aide des différentes integration logiciels, voici une liste de quelque unes :
La meilleure solution pour installer l'operateur Keda est de passé par helm3
kubectl create namespace keda
helm repo add kedacore https://kedacore.github.io/charts
helm repo update
helm install keda kedacore/keda --namespace keda
kubectl -n keda get po
Nous allons déployer un pod api
qui affichera une métrique number_of_replicas
et selon la valeur de cette métrique nous allons ajuster le nombre de replicas du déploiement mon-application
.
L'ajustement se fera donc via l'opérateur Keda et le scalers Metrics-API
basé sur l'URL de notre pod api
.
API configuration
apiVersion: apps/v1
kind: Deployment
metadata:
name: api
namespace: demo
spec:
selector:
matchLabels:
run: api
replicas: 1
template:
metadata:
labels:
run: api
spec:
containers:
- name: api
image: mon/api
---
apiVersion: v1
kind: Service
metadata:
name: api-service
namespace: demo
spec:
selector:
run: api
ports:
- name: app
protocol: TCP
port: 80
targetPort: api
mon-application configuration
apiVersion: apps/v1
kind: Deployment
metadata:
name: mon-application
namespace: demo
spec:
selector:
matchLabels:
run: mon-application
replicas: 1
template:
metadata:
labels:
run: mon-application
spec:
containers:
- name: monapplication
image: mon/application
resources:
limits:
cpu: 50m
memory: "50Mi"
requests:
cpu: 50m
memory: "50Mi"
Keda configuration
apiVersion: keda.sh/v1alpha1
kind: ScaledObject
metadata:
name: mon-application-keda
namespace: demo
spec:
minReplicaCount: 0 # Nombre minimum de replicas
maxReplicaCount: 10 # Nombre maximum de replicas
scaleTargetRef:
name: mon-application # Nom du déploiement
triggers:
- type: metrics-api # Type de scalers
metadata:
targetValue: "1"
url: "http://api-service.demo.svc.cluster.local" # URL de la métrique API
valueLocation: 'mon_application.number_of_replicas' # Chemin de la valeur de la métrique qu'on veux analyser
# Pods
root@mon-pc ~ $ kubectl -n demo get po
NAME READY STATUS RESTARTS AGE
api-5f79f5c8c6-tjmlc 1/1 Running 0 13s
mon-application-7f64d45cd5-xs6fk 1/1 Running 0 8s
# Get Service API
root@mon-pc ~ $ kubectl -n demo get svc
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
api-service ClusterIP 10.244.117.193 <none> 80/TCP 5m27s
# Resultat du contenu du pod API
root@mon-pc ~ kubectl -n demo exec -it mon-application-7f64d45cd5-xs6fk -- curl api-service
{
"mon_application": {
"number_of_replicas": 1
},
"mon_backend": {
"number_of_replicas": 0
}
}
Si la valeur de mon_application.number_of_replicas
passe de 1 à 5, alors le nombre de replicas pour mon-application
va augmenter.
# Check de la configuration keda
root@mon-pc ~ $ kubectl -n demo get scaledobjects
NAME SCALETARGETKIND SCALETARGETNAME MIN MAX TRIGGERS AUTHENTICATION READY ACTIVE FALLBACK AGE
mon-application-keda apps/v1.Deployment mon-application 0 10 metrics-api True True False 4m40s
# Check contenu de notre API
root@mon-pc ~ $ kubectl -n demo exec -it mon-application-7f64d45cd5-xs6fk -- curl api-service
{
"mon_application": {
"number_of_replicas": 5
},
"mon_backend": {
"number_of_replicas": 0
}
}
# Check le nombre de pods
root@mon-pc ~ $ kubect -n demo get po
root@node150453-env-2204261 ~ $ kubectl -n demo get po
NAME READY STATUS RESTARTS AGE
api-6b444485d7-dzvtp 1/1 Running 0 69s
mon-application-7f64d45cd5-xs6fk 1/1 Running 0 32m
mon-application-7f64d45cd5-58bg5 1/1 Running 0 39s
mon-application-7f64d45cd5-8pfhq 1/1 Running 0 39s
mon-application-7f64d45cd5-jrjj2 1/1 Running 0 24s
mon-application-7f64d45cd5-r9jch 1/1 Running 0 39s
Il est également possible de diminuer le nombre de replicas à 0, ce qui n'est pas possible avec seulement HPA.
HPA (Horizontal Pod Autoscaler) est un outil intégré à Kubernetes qui permet de réguler automatiquement le nombre de réplicas (instances) d'un déploiement en fonction de la charge de travail. Il utilise des indicateurs de performance tels que la mémoire et le CPU pour ajuster le nombre de réplicas en cours d'exécution.
KEDA (Kubernetes-based Event-Driven Autoscaling) est un outil open source qui permet également de réguler automatiquement le nombre de réplicas d'un déploiement, mais il est conçu pour les scénarios d'échelle événementielle plutôt que d'échelle de ressources. Il utilise des indicateurs tels que les messages dans une file d'attente, les événements de bus de service, etc. pour ajuster le nombre de réplicas en cours d'exécution (et même de le réduire à 0).
En résumé, HPA est conçu pour l'échelle en fonction des ressources tandis que KEDA est conçu pour l'échelle en fonction des événements. Les deux peuvent être utilisés ensemble pour gérer l'échelle dans différents scénarios.