Aller au contenu principal

Autoscaling

info

Cette page concerne uniquement l'installation sur un existing cluster utilisant KOTS ou Helm.

Prérequis pour l'autoscaling

Vous pouvez utiliser soit Kubernetes HPA (Horizontal Pod Autoscaler) soit KEDA (Kubernetes Event-Driven Autoscaler) pour l'autoscaling. Les deux s'appuient sur les mêmes métriques mais ont des exigences différentes.

  • HPA : intégré à Kubernetes, lit les métriques depuis Metrics Server ou les métriques externes poussées par Prometheus Adapter. Un peu moins réactif que KEDA. Ne peut pas descendre à zéro replica.
  • KEDA : lit les événements depuis diverses sources (ici Prometheus). Scaling plus rapide. Peut descendre à zéro replica. Non disponible sur les installations basées sur KOTS.

Composants requis

Selon la méthode d'autoscaling choisie, vous aurez besoin de différents composants installés dans votre cluster :

ComposantHPAKEDA
Prometheus serverRequisRequis
Prometheus adapterRequisNon requis
KEDA controllerNon requisRequis

HPA nécessite Prometheus adapter pour exposer ces métriques à l'API metrics de Kubernetes, tandis que KEDA peut interroger directement Prometheus.

Installer Prometheus server

Les deux méthodes d'autoscaling ont besoin d'un Prometheus qui scrape les métriques de l'application GitGuardian. Deux configurations sont supportées, selon que vous exécutez ou non le Prometheus Operator dans votre cluster.

Prérequis : autoriser l'export des métriques

Quelle que soit l'option choisie, l'application GitGuardian doit être configurée pour exposer ses métriques au préalable, sinon Prometheus scrape des endpoints vides. Consultez Autoriser la collecte des métriques pour activer l'export applicatif.

Laquelle choisir ?

Un serveur Prometheus autonome ne lit pas les ressources ServiceMonitor — il ne scrape que ce que son propre fichier de configuration liste. Ainsi, les objets ServiceMonitor fournis par le chart GitGuardian n'ont aucun effet sur un serveur autonome, et vous devez ajouter une configuration de scrape manuelle à la place.

  • Option A (recommandée) — si vous exécutez déjà, ou êtes prêt à installer, kube-prometheus-stack (regroupe l'opérateur + un Prometheus managé). Le chart GitGuardian fournit les objets ServiceMonitor, la collecte se limite donc à les activer.
  • Option B — si vous voulez un unique Prometheus autonome sans opérateur. Vous écrivez la configuration de scrape à la main.

Ajoutez le dépôt Helm Prometheus Community (utilisé par les deux options) :

helm repo add prometheus-community https://prometheus-community.github.io/helm-charts
helm repo update

Pour l'autoscaling, vous n'avez besoin que de l'opérateur (pour traiter les objets ServiceMonitor) et de l'instance Prometheus elle-même. Désactivez tous les autres composants pour garder l'installation légère. Créez un fichier kube-prometheus-stack-values.yaml :

# L'opérateur (prometheusOperator) et Prometheus restent activés par défaut —
# tout ce qui suit est du monitoring cluster-wide dont l'autoscaling n'a pas besoin.
alertmanager:
enabled: false
grafana:
enabled: false
nodeExporter:
enabled: false # désactive le sous-chart prometheus-node-exporter
kubeStateMetrics:
enabled: false # désactive le sous-chart kube-state-metrics
defaultRules:
create: false # ignore les règles d'alerting/recording Kubernetes fournies
# Ignore le scraping du control-plane et des composants de nœud Kubernetes
kubeApiServer:
enabled: false
kubelet:
enabled: false
kubeControllerManager:
enabled: false
coreDns:
enabled: false
kubeDns:
enabled: false
kubeEtcd:
enabled: false
kubeScheduler:
enabled: false
kubeProxy:
enabled: false
helm install kube-prometheus-stack prometheus-community/kube-prometheus-stack \
--namespace monitoring \
--create-namespace \
-f kube-prometheus-stack-values.yaml

Le Prometheus managé est ensuite accessible dans le cluster à l'adresse http://kube-prometheus-stack-prometheus.monitoring.svc.cluster.local:9090.

Activez les objets ServiceMonitor GitGuardian dans votre local-values.yaml :

observability:
exporters:
statefulAppExporter:
enabled: true
serviceMonitors:
enabled: true
labels:
# Doit correspondre au nom de release Helm de votre installation kube-prometheus-stack.
# Le Prometheus du stack ne sélectionne que les ServiceMonitors portant ce label.
release: kube-prometheus-stack
Le label release est obligatoire

Par défaut, le Prometheus du stack a serviceMonitorSelector: {matchLabels: {release: <stack-release-name>}}. Un ServiceMonitor sans ce label exact est silencieusement ignoré — pas de cibles, pas de métriques, et le Prometheus Adapter finit par n'exposer aucune donnée. Soit vous définissez le label comme ci-dessus, soit vous définissez prometheus.prometheusSpec.serviceMonitorSelectorNilUsesHelmValues=false sur le stack pour qu'il sélectionne tous les ServiceMonitor.

Après helm upgrade du chart GitGuardian, confirmez que les cibles sont prises en compte (état UP) dans l'interface Prometheus sous Status > Targets, ou :

kubectl -n monitoring port-forward svc/kube-prometheus-stack-prometheus 9090
# puis naviguez sur http://localhost:9090/targets et cherchez serviceMonitor/<gim-namespace>/...

Option B : Prometheus autonome avec configuration de scrape manuelle

Installez le serveur autonome :

helm install prometheus prometheus-community/prometheus \
--namespace monitoring \
--create-namespace \
--set alertmanager.enabled=false \
--set prometheus-pushgateway.enabled=false

Le serveur est ensuite accessible dans le cluster à l'adresse http://prometheus-server.monitoring.svc.cluster.local:80.

Comme le serveur autonome ignore les objets ServiceMonitor, ajoutez un job de scrape pointant vers les endpoints de métriques GitGuardian. La métrique de longueur de queue Celery (gim_celery_queue_length) est publiée par l'app exporter, un endpoint unique d'agrégation — une seule cible statique suffit donc. Définissez ceci dans les values du chart Prometheus autonome :

extraScrapeConfigs: |
- job_name: "gim"
static_configs:
# Remplacez <gim-namespace> par le namespace dans lequel votre release GitGuardian est installée
- targets: ["app-exporter.<gim-namespace>.svc.cluster.local:9808"]
metric_relabel_configs:
# La règle de l'adapter mappe les métriques à un namespace (overrides.namespace), donc la
# série doit porter un label `namespace`. Une cible statique n'en a pas, on le dérive donc
# du hostname de l'instance : app-exporter.<namespace>.svc... -> <namespace>
- source_labels: [instance]
regex: '.*\.([^.]+)\.svc.*'
target_label: namespace
action: replace
replacement: '$1'
Mettez à jour le hostname placeholder

<gim-namespace> dans app-exporter.<gim-namespace>.svc.cluster.local est le namespace de votre release GitGuardian — remplacez-le par le namespace dans lequel vous avez installé. Le bloc metric_relabel_configs dérive ensuite le label namespace de ce que vous définissez, gardez donc les deux cohérents.

info

Le service app-exporter n'existe que lorsque l'exporter d'agrégation est activé — définissez observability.exporters.statefulAppExporter.enabled: true dans vos values GitGuardian.

Pour l'autoscaling du Machine Learning Secret Engine, vous avez également besoin de bentoml_service_request_in_progress, qui est servi par le secret engine lui-même plutôt que par l'app exporter. Ajoutez une seconde cible statique pour cela (le port 3000 est la valeur par défaut de secretEngine.port — ne le changez que si vous avez surchargé cette valeur) :

- job_name: "gim-ml-secret-engine"
metrics_path: /metrics
static_configs:
# Remplacez <gim-namespace> par votre namespace, et 3000 si vous avez changé secretEngine.port
- targets: ["ml-secret-engine.<gim-namespace>.svc.cluster.local:3000"]
metric_relabel_configs:
- source_labels: [instance]
regex: '.*\.([^.]+)\.svc.*'
target_label: namespace
action: replace
replacement: '$1'
N'activez pas observability.serviceMonitors

Gardez observability.serviceMonitors.enabled: false (la valeur par défaut) pour cette option. Une installation Prometheus autonome n'enregistre pas les CRDs monitoring.coreos.com (celles-ci viennent avec le Prometheus Operator). Si vous l'activez, le chart GitGuardian tente de créer des objets ServiceMonitor dont la CRD est absente et le helm install/helm upgrade échoue avec une erreur no matches for kind "ServiceMonitor". Le serveur autonome ignorerait de toute façon ces objets — la collecte ici provient uniquement de la configuration de scrape ci-dessus.

Installer Prometheus adapter

Si vous choisissez HPA pour l'autoscaling, installez Prometheus Adapter pour exposer les métriques Prometheus à l'API metrics de Kubernetes. Faites pointer prometheus.url/prometheus.port vers le Prometheus que vous avez installé ci-dessus — c'est la mauvaise configuration la plus courante.

Pour l'Option A (kube-prometheus-stack) :

helm install prometheus-adapter prometheus-community/prometheus-adapter \
--namespace monitoring \
--set prometheus.url=http://kube-prometheus-stack-prometheus.monitoring.svc.cluster.local \
--set prometheus.port=9090

Pour l'Option B (serveur autonome) :

helm install prometheus-adapter prometheus-community/prometheus-adapter \
--namespace monitoring \
--set prometheus.url=http://prometheus-server.monitoring.svc.cluster.local \
--set prometheus.port=80
Adapter pointant vers le mauvais Prometheus

Si prometheus.url pointe vers un service qui n'existe pas (par exemple, vous avez migré du serveur autonome vers le stack mais laissé l'adapter sur l'ancienne URL), l'adapter reste AVAILABLE=True mais expose zéro métrique. Vérifiez avec :

kubectl get --raw "/apis/custom.metrics.k8s.io/v1beta1" | jq '.resources[].name'
kubectl get --raw "/apis/external.metrics.k8s.io/v1beta1" | jq '.resources[].name'

Une liste resources vide signifie que l'adapter n'atteint aucune série correspondante — vérifiez d'abord l'URL, puis les règles.

Consultez la section Configuration de Prometheus Adapter ci-dessous pour les règles à ajouter.

Installer le contrôleur KEDA

Installez le contrôleur KEDA pour activer l'autoscaling. Vous pouvez l'installer en utilisant le chart Helm KEDA avec les commandes suivantes :

helm repo add kedacore https://kedacore.github.io/charts
helm install keda kedacore/keda \
--namespace keda \
--create-namespace

Vous devez configurer les values Helm de votre chart GitGuardian pour permettre à KEDA de se connecter à votre serveur Prometheus :

autoscaling:
keda:
prometheus:
metadata:
# Utilisez l'adresse du serveur Prometheus de votre installation :
# Option A (kube-prometheus-stack) : http://kube-prometheus-stack-prometheus.monitoring.svc.cluster.local:9090
# Option B (serveur autonome) : http://prometheus-server.monitoring.svc.cluster.local:80
serverAddress: http://prometheus-server.monitoring.svc.cluster.local:80
# Facultatif. En-têtes personnalisés à inclure dans la requête
customHeaders: X-Client-Id=cid,X-Tenant-Id=tid,X-Organization-Id=oid
# Facultatif. Spécifiez le mode d'authentification (basic, bearer, tls)
authModes: bearer
# Facultatif. Spécifiez la ressource TriggerAuthentication à utiliser lorsque authModes est spécifié.
authenticationRef:
name: keda-prom-creds

Un ScaledObject et un hpa seront créés dans le namespace GitGuardian.

Autoscaling des workers

L'autoscaling permet une mise à l'échelle dynamique des pods worker en fonction de la longueur de la queue de tâches Celery comme métrique externe pour les décisions de scaling, améliorant l'efficacité et les performances tout en optimisant les coûts en ressources.

Pour activer l'autoscaling basé sur les longueurs de queues Celery, vous devez d'abord autoriser la collecte des métriques afin que l'application expose ses métriques.

Si vous utilisez KEDA, la configuration de Prometheus adapter n'est pas nécessaire.

Configuration de Prometheus adapter

Configurez Prometheus adapter pour exposer les longueurs de queues Celery comme métriques externes. Cela se fait en définissant une règle personnalisée dans la configuration de Prometheus Adapter.

La règle suivante doit être ajoutée à vos values Helm de Prometheus Adapter pour exposer les longueurs de queues Celery :

rules:
external:
- seriesQuery: '{__name__="gim_celery_queue_length",queue_name!=""}'
metricsQuery: sum(<<.Series>>{<<.LabelMatchers>>}) by (queue_name)
resources:
namespaced: true
overrides:
namespace:
resource: namespace

Si vous utilisez le Machine Learning, vous aurez également besoin de cette règle :

rules:
external:
- seriesQuery: '{__name__="bentoml_service_request_in_progress",exported_endpoint!=""}'
resources:
namespaced: false
metricsQuery: sum(<<.Series>>{<<.LabelMatchers>>}) by (<<.GroupBy>>)

Comportement de l'autoscaling

Le comportement suivant sera appliqué :

  • Scaling Up : si la longueur d'une queue Celery dépasse 10 tâches par replica de worker actuel, le nombre de replicas sera augmenté, à condition que le nombre actuel de replicas soit inférieur à la limite maximale spécifiée.
  • Scaling Down : si le nombre de tâches par replica de worker actuel reste inférieur à 10 pendant une période continue de 5 minutes, le nombre de replicas sera diminué, à condition que le nombre actuel de replicas soit supérieur à la limite minimale spécifiée.

HPA behavior

info

En utilisant KEDA, lorsque la queue Celery est vide, le worker passera en état inactif, ce qui entraînera la mise à l'échelle du nombre de replicas à zéro.

Autoscaling des applications web

Les déploiements web (par exemple public_api, internal_api) s'auto-scalent sur la latence des requêtes, en lisant les métriques Prometheus de votre contrôleur ingress. GitGuardian fournit une requête de latence intégrée pour un ensemble de contrôleurs ; pour tout autre contrôleur, vous fournissez votre propre trigger KEDA.

Exigence de routage

L'autoscaling des applications web nécessite le routage Gateway API (routingApi: gateway-api) — le mode activement développé qui expose les métriques par webapp que l'autoscaler lit. Il n'est pas disponible avec le routage nginx intégré par défaut (routingApi: ingress), qui fait passer tout le trafic par un unique pod nginx intégré au chart et n'expose aucune métrique par webapp.

Prérequis

En plus de Prometheus et KEDA, la requête intégrée lit les métriques émises par votre contrôleur ingress, que GitGuardian n'installe pas ni ne scrape. Vous devez donc :

  1. Activer les métriques Prometheus du contrôleur, sur le propre chart du contrôleur — par exemple :
    • traefik : metrics.prometheus.serviceMonitor.enabled=true
    • istio / contour : leurs métriques Envoy proxy (pas de flag supplémentaire, mais voir le point suivant)
  2. Faire scraper ces métriques par Prometheus, via un ServiceMonitor/PodMonitor (Prometheus Operator). La plupart des charts de contrôleurs en fournissent un derrière un flag (par exemple traefik …metrics.serviceMonitor.enabled=true) ; istio et l'Envoy de Contour sont scrapés avec un PodMonitor sur les pods proxy (chemin /stats/prometheus).

Avec la configuration standard ServiceMonitor, Prometheus renomme le label service du contrôleur en exported_service (collision de label avec la cible de scrape) — c'est ce que les requêtes intégrées matchent. Si les séries attendues sont absentes, l'autoscaling n'a pas de données : vérifiez dans Prometheus que la métrique de durée de requête du contrôleur existe avant de déboguer le chart.

Contrôleurs supportés

La requête de latence intégrée est sélectionnée par ingress.controller :

ingress.controllerRequête de latence intégrée
istio
traefik
contour✅ (nécessite le canal de CRD Gateway API experimental — voir ci-dessous)
nginx-gateway-fabric❌ (pas de métriques par route dans l'édition OSS)
other❌ (par conception — apportez votre propre trigger)

La requête intégrée couvre istio, traefik et contour. Contour nécessite en plus le canal de CRD experimental de Gateway API (le canal de release upstream Kubernetes Gateway API SIG). Tout autre data plane (nginx-gateway-fabric, Kong, Cilium, Envoy Gateway, aws_alb, …) n'a pas de requête intégrée — définissez controller: other et fournissez votre propre trigger KEDA comme celui ci-dessous.

Autoscaling par latence intégré (contrôleurs supportés)

Définissez un seuil de latence (en millisecondes) ; le chart construit automatiquement la bonne requête Prometheus pour votre contrôleur :

ingress:
controller: istio # l'un de : istio, traefik, contour
webapps:
public_api:
autoscaling:
keda: { enabled: true }
minReplicas: 1
maxReplicas: 5
metrics:
targetLatency: 1000 # ms

Trigger personnalisé pour un contrôleur non listé (par exemple Gateway API avec Kong / Cilium / Envoy Gateway)

Lorsque votre data plane n'a pas de requête intégrée, définissez ingress.controller: other, désactivez la requête intégrée avec targetLatency: null, et fournissez votre propre trigger KEDA. Le routage n'est pas affecté — other produit des HTTPRoutes Gateway API standard (ou un Ingress classique avec votre ingressClassName).

ingress:
routingApi: gateway-api
controller: other
gatewayApi:
gatewayClassName: kong # votre contrôleur Gateway API
webapps:
public_api:
autoscaling:
keda:
enabled: true
triggers:
- type: prometheus
metricType: Value
metadata:
serverAddress: http://prometheus-server.monitoring.svc.cluster.local:80
query: 'sum(rate(kong_http_requests_total{service="gim.public-api.pnum-5051"}[1m]))'
threshold: "20"
minReplicas: 1
maxReplicas: 5
metrics:
targetLatency: null # désactive la requête intégrée

Surcharger la requête intégrée

Vous pouvez également remplacer la requête intégrée par la vôtre (par exemple, scaler sur une métrique, un percentile ou une fenêtre différente) : définissez targetLatency: null pour supprimer la requête intégrée et définissez votre trigger. Une fois targetLatency à null, la valeur controller n'affecte plus l'autoscaling, vous pouvez donc garder votre vrai contrôleur (par exemple istio) ou définir controller: other — les deux se comportent de la même manière avec un trigger personnalisé.

ingress:
controller: istio # ou "other" — sans importance pour l'autoscaling une fois targetLatency à null
webapps:
public_api:
autoscaling:
keda:
enabled: true
triggers:
- type: prometheus
metricType: Value
metadata:
serverAddress: http://prometheus-server.monitoring.svc.cluster.local:80
# par exemple p99 au lieu de la latence p95 par défaut
query: 'histogram_quantile(0.99, sum(rate(istio_request_duration_milliseconds_bucket{destination_service_name="public-api"}[2m])) by (destination_service_name, le))'
threshold: "800"
minReplicas: 1
maxReplicas: 5
metrics:
targetLatency: null
info

autoscaling.keda.triggers sont passés à KEDA tels quels, vous n'êtes donc pas limité à Prometheus — n'importe quel scaler KEDA (CPU, mémoire, Kafka, SQS, …) peut être utilisé.

Installation basée sur KOTS

L'installation basée sur KOTS n'autorise que l'autoscaling HPA.

Naviguez sous Config > Scaling dans la KOTS Admin Console, vous aurez accès aux options de scaling des workers.

Pour chaque worker, vous pouvez activer l'autoscaling en cochant l'option Enable Horizontal Pod Autoscaling, puis vous pourrez spécifier le nombre minimum et maximum de replicas. Worker Autoscaling configuration

Installation basée sur Helm

Personnalisez les applications Helm en utilisant votre fichier local-values.yaml, soumis avec la commande helm.

Autoscaling des workers

Vous pouvez activer l'autoscaling des workers en définissant les values Helm suivantes (ici, nous activons HPA pour le worker "worker") :

celeryWorkers:
worker:
autoscaling:
hpa:
enabled: true
keda:
enabled: false
minReplicas: 1
maxReplicas: 10

Autoscaling du Machine Learning Secret Engine

Pour un autoscaling efficace du Machine Learning Secret Engine, vous devez activer l'autoscaling pour les deux :

  • Le ML Worker traitant la queue Celery (ml-api-priority) : ce worker est responsable de la mise en queue et de la répartition des tâches liées au ML. Sans autoscaling, il pourrait devenir un goulet d'étranglement, entraînant des retards dans le traitement des requêtes.

  • Le Secret Engine effectuant les calculs (secretEngine) : activer l'autoscaling pour le Secret Engine garantit qu'il peut monter en charge en réponse à la demande de calculs ML.

Pour activer l'autoscaling, configurez les values Helm suivantes :

# ML Secret Engine
secretEngine:
autoscaling:
hpa:
enabled: true
keda:
enabled: false
minReplicas: 1
maxReplicas: 2

celeryWorkers:
# ML Worker
ml-api-priority:
autoscaling:
hpa:
enabled: true
keda:
enabled: false
minReplicas: 1
maxReplicas: 2

Consultez la documentation de référence des values pour plus de détails.

attention

Les paramètres Helm autoscaling.hpa.enabled et autoscaling.keda.enabled sont mutuellement exclusifs, vous devez choisir entre hpa (utilisant Prometheus adapter) et le contrôleur KEDA.