Utiliser APISIX, Prometheus et KEDA pour mettre à l'échelle les applications de manière élastique dans Kubernetes

Jintao Zhang

Jintao Zhang

February 17, 2023

Technology

Introduction

La quantité de trafic qui entre dans une application varie au fil du temps. Par exemple, une application de shopping en ligne est beaucoup plus sollicitée pendant la période des fêtes que les jours ordinaires. Pouvoir ajuster la capacité de l'application en fonction du trafic permettra d'offrir une bien meilleure expérience utilisateur et des services de qualité.

Apache APISIX est une passerelle API cloud-native haute performance qui peut fournir des métriques significatives pour déterminer si les applications doivent être mises à l'échelle. C'est un middleware qui traite tout le trafic envoyé aux applications en amont et peut donc collecter des données de trafic au cours du processus.

Pour réaliser une mise à l'échelle élastique, KEDA sera utilisé comme contrôleur, et Prometheus sera utilisé pour récupérer les métriques fournies par APISIX.

using KEDA for autocaling

Comment utiliser le Prometheus Scaler dans KEDA

KEDA est un autoscaler basé sur des événements dans Kubernetes, qui peut configurer divers scalers. Dans cet article, le Prometheus scaler sera utilisé pour obtenir les métriques exposées par APISIX.

Déployer KEDA

Le déploiement de KEDA est relativement simple, il suffit d'ajouter le dépôt Helm correspondant et de l'installer.

(MoeLove) ➜ helm repo add kedacore https://kedacore.github.io/charts
"kedacore" a été ajouté à vos dépôts
(MoeLove) ➜ helm repo update kedacore
Patientez pendant que nous récupérons les dernières versions de vos dépôts de charts...
...Mise à jour réussie du dépôt de charts "kedacore"
Mise à jour terminée. ⎈Bon Helm!⎈
(MoeLove) ➜ helm install keda kedacore/keda --namespace keda --create-namespace
NAME: keda
LAST DEPLOYED: Thu Jan 19 00:01:00 2023
NAMESPACE: keda
STATUS: déployé
REVISION: 1
TEST SUITE: Aucun

Après l'installation, le Pod a un statut Running, indiquant qu'il a été installé.

(MoeLove) ➜ kubectl -n keda get pods
NAME                                               READY   STATUS    RESTARTS   AGE
keda-operator-metrics-apiserver-6d4db7dcff-ck9qg   1/1     Running   0          36s
keda-operator-5dd4748dcd-k8jjz                     1/1     Running   0          36s

Déployer Prometheus

Ici, nous utilisons Prometheus Operator pour déployer Prometheus. Prometheus Operator peut nous aider à déployer rapidement l'instance Prometheus dans Kubernetes et à ajouter les règles de surveillance via une configuration déclarative.

Complétez l'installation de Prometheus Operator en suivant les étapes ci-dessous.

(MoeLove) ➜ https://github.com/prometheus-operator/prometheus-operator/releases/download/v0.62.0/bundle.yaml
(MoeLove) ➜ kubectl apply --server-side -f bundle.yaml
customresourcedefinition.apiextensions.k8s.io/alertmanagerconfigs.monitoring.coreos.com serverside-applied
customresourcedefinition.apiextensions.k8s.io/alertmanagers.monitoring.coreos.com serverside-applied
customresourcedefinition.apiextensions.k8s.io/podmonitors.monitoring.coreos.com serverside-applied
customresourcedefinition.apiextensions.k8s.io/probes.monitoring.coreos.com serverside-applied
customresourcedefinition.apiextensions.k8s.io/prometheuses.monitoring.coreos.com serverside-applied
customresourcedefinition.apiextensions.k8s.io/prometheusrules.monitoring.coreos.com serverside-applied
customresourcedefinition.apiextensions.k8s.io/servicemonitors.monitoring.coreos.com serverside-applied
customresourcedefinition.apiextensions.k8s.io/thanosrulers.monitoring.coreos.com serverside-applied
clusterrolebinding.rbac.authorization.k8s.io/prometheus-operator serverside-applied
clusterrole.rbac.authorization.k8s.io/prometheus-operator serverside-applied
deployment.apps/prometheus-operator serverside-applied
serviceaccount/prometheus-operator serverside-applied
service/prometheus-operator serverside-applied

Ensuite, utilisez la configuration suivante pour Prometheus et appliquez-la au cluster Kubernetes.

---
apiVersion: v1
kind: ServiceAccount
metadata:
  name: prometheus
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
  name: prometheus
rules:
- apiGroups: [""]
  resources:
  - nodes
  - nodes/metrics
  - services
  - endpoints
  - pods
  verbs: ["get", "list", "watch"]
- apiGroups: [""]
  resources:
  - configmaps
  verbs: ["get"]
- apiGroups:
  - networking.k8s.io
  resources:
  - ingresses
  verbs: ["get", "list", "watch"]
- nonResourceURLs: ["/metrics"]
  verbs: ["get"]
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
  name: prometheus
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: ClusterRole
  name: prometheus
subjects:
- kind: ServiceAccount
  name: prometheus
  namespace: default
---
apiVersion: monitoring.coreos.com/v1
kind: Prometheus
metadata:
  name: prometheus
spec:
  serviceAccountName: prometheus
  serviceMonitorSelector:
    matchLabels:
      app: apisix
  serviceMonitorNamespaceSelector:
    matchLabels:
      team: apisix
  resources:
    requests:
      memory: 400Mi
  enableAdminAPI: false
---
apiVersion: v1
kind: Service
metadata:
  name: prometheus
spec:
  type: LoadBalancer
  ports:
  - name: web
    port: 9090
    protocol: TCP
    targetPort: web
  selector:
    prometheus: prometheus

Après avoir appliqué la configuration au cluster Kubernetes, vous pouvez voir qu'une instance Prometheus est créée dans le namespace default. Comme nous avons configuré Prometheus avec le TYPE LoadBalancer, les utilisateurs peuvent accéder directement à Prometheus via l'IP publique du LoadBalancer.

(MoeLove) ➜ kubectl get svc
NAME                  TYPE           CLUSTER-IP      EXTERNAL-IP    PORT(S)          AGE
kubernetes            ClusterIP      10.43.0.1       <none>         443/TCP          96m
prometheus-operator   ClusterIP      None            <none>         8080/TCP         92m
prometheus-operated   ClusterIP      None            <none>         9090/TCP         41m
prometheus            LoadBalancer   10.43.125.194   216.6.66.66    9090:30099/TCP   41m

Comment déployer la passerelle API et activer la surveillance

Ensuite, déployez le contrôleur APISIX Ingress et utilisez Prometheus pour la collecte de métriques.

La méthode est similaire pour les utilisateurs qui utilisent uniquement APISIX au lieu du contrôleur APISIX Ingress. Nous ne l'expliquerons pas séparément ici.

Ici, Helm est utilisé pour le déploiement, et le contrôleur APISIX Ingress ainsi qu'APISIX peuvent être déployés simultanément dans le cluster.

(MoeLove) ➜ helm repo add apisix https://charts.apiseven.com
"apisix" existe déjà avec la même configuration, ignoré
(MoeLove) ➜ helm repo update apisix
Patientez pendant que nous récupérons les dernières versions de vos dépôts de charts...
...Mise à jour réussie du dépôt de charts "apisix"
Mise à jour terminée. ⎈Bon Helm!⎈
(MoeLove) ➜ helm upgrade --install apisix apisix/apisix --create-namespace  --namespace apisix --set gateway.type=LoadBalancer --set ingress-controller.enabled=true --set ingress-controller.config.apisix.serviceNamespace=apisix
Release "apisix" a été mis à niveau. Bon Helm!
NAME: apisix
LAST DEPLOYED: Thu Jan 19 02:11:23 2023
NAMESPACE: apisix
STATUS: déployé
REVISION: 1
TEST SUITE: Aucun
NOTES:
1. Obtenez l'URL de l'application en exécutant ces commandes :
     NOTE : Cela peut prendre quelques minutes pour que l'IP du LoadBalancer soit disponible.
           Vous pouvez surveiller le statut en exécutant 'kubectl get --namespace apisix svc -w apisix-gateway'
  export SERVICE_IP=$(kubectl get svc --namespace apisix apisix-gateway --template "{{ range (index .status.loadBalancer.ingress 0) }}{{.}}{{ end }}")
  echo http://$SERVICE_IP:80

Ensuite, activez le plugin Prometheus d'APISIX. Veuillez vous référer aux deux documents suivants pour les méthodes de configuration spécifiques et les paramètres associés.

Une fois activé, Prometheus peut capturer les métriques exposées par APISIX en créant une ressource ServiceMonitor.

apiVersion: monitoring.coreos.com/v1
kind: ServiceMonitor
metadata:
  name: example-app
  labels:
    app: apisix
spec:
  selector:
    matchLabels:
      app: apisix
  endpoints:
  - port: web

Vérifier la capacité de mise à l'échelle élastique de l'application

Créez d'abord une application.

(MoeLove) ➜ kubectl create deploy httpbin --image=kennethreitz/httpbin --port=80
deployment.apps/httpbin créé
(MoeLove) ➜ kubectl expose deploy httpbin --port 80

Créez les règles de routage suivantes et appliquez-les au cluster Kubernetes pour rediriger les requêtes via APISIX.

apiVersion: apisix.apache.org/v2
kind: ApisixRoute
metadata:
  name: httpserver-route
spec:
  http:
  - name: rule1
    match:
      hosts:
      - local.httpbin.org
      paths:
      - /*
    backends:
       - serviceName: httpbin
         servicePort: 80

Ensuite, créez un ScaledObject KEDA et configurez les paramètres liés à Prometheus.

apiVersion: keda.sh/v1alpha1
kind: ScaledObject
metadata:
  name: prometheus-scaledobject
  namespace: default
spec:
  scaleTargetRef:
    name: httpbin
  triggers:
  - type: prometheus
    metadata:
      serverAddress: http://prometheus.default.svc:9090
      metricName: apisix_http_status
      threshold: '10'
      query: sum(rate(apisix_http_status{route="httpserver-route"}[1m]))

La configuration ci-dessus signifie que sum(rate(apisix_http_status{route="httpserver-route"}[1m])) est utilisé comme expression de requête, et si le résultat atteint 10, l'expansion commencera. (La configuration ici est uniquement à des fins de démonstration, veuillez la modifier selon votre propre situation). Ensuite, nous effectuons des requêtes continues au service httpbin via curl.

Plus tard, si nous vérifions les pods de l'application, vous pouvez voir qu'elle a été mise à l'échelle automatiquement à deux par KEDA.

(MoeLove) ➜ kubectl get pods
NAME                      READY   STATUS    RESTARTS   AGE
httpbin-d46d778d7-chtdw   1/1     Running   0          12m
httpbin-d46d778d7-xanbj   1/1     Running   0          10s

Lorsque l'application reste inactive après un certain temps, nous constaterons que le nombre de pods a automatiquement diminué à une instance.

(MoeLove) ➜ kubectl get pods
NAME                      READY   STATUS    RESTARTS   AGE
httpbin-d46d778d7-chtdw   1/1     Running   0          32m

Résumé

KEDA utilise Prometheus comme scaler pour collecter les métriques exposées par APISIX. Comme tout le trafic passe d'abord par APISIX, obtenir des statistiques côté APISIX sera beaucoup plus simple et pratique.

Lorsque le volume des requêtes métier augmente, l'application sera automatiquement mise à l'échelle, et lorsque le volume des requêtes métier diminue, l'application sera automatiquement réduite.

Cette méthode peut atténuer les opérations manuelles de mise à l'échelle/réduction dans de nombreux environnements de production pour garantir la meilleure expérience utilisateur.

Tags: