Utiliser APISIX, Prometheus et KEDA pour mettre à l'échelle les applications de manière élastique dans Kubernetes
February 17, 2023
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.
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.
- prometheus plugins | Apache APISIX®
- How to access Apache APISIX Prometheus metrics on Kubernetes | Apache APISIX®
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.