Use APISIX, Prometheus, and KEDA to Scale Applications Elastically in Kubernetes

Jintao Zhang

Jintao Zhang

February 17, 2023

Technology

Einführung

Die Menge des Datenverkehrs, der in eine Anwendung eingeht, variiert von Zeit zu Zeit. Beispielsweise ist eine Online-Shopping-Anwendung während der Ferienzeit viel stärker ausgelastet als an normalen Tagen. Die Möglichkeit, die Kapazität der Anwendung basierend auf dem Datenverkehr anzupassen, bietet ein viel besseres Benutzererlebnis und bessere Dienstleistungen.

Apache APISIX ist ein leistungsstarker, cloud-nativer API-Gateway, der aussagekräftige Metriken liefern kann, um festzustellen, ob die Anwendungen skaliert werden müssen. Es ist ein Middleware, der den gesamten Datenverkehr verarbeitet, der an die Upstream-Anwendungen gesendet wird, und kann daher während des Prozesses Verkehrsdaten sammeln.

Um elastische Skalierung durchzuführen, wird KEDA als Controller verwendet, und Prometheus wird verwendet, um die von APISIX bereitgestellten Metriken abzurufen.

Verwendung von KEDA für Autoscaling

Verwendung des Prometheus-Scalers in KEDA

KEDA ist ein ereignisbasierter Autoscaler in Kubernetes, der verschiedene Scaler konfigurieren kann. In diesem Artikel wird der Prometheus-Scaler verwendet, um die von APISIX bereitgestellten Metriken zu erhalten.

Bereitstellung von KEDA

Die Bereitstellung von KEDA ist relativ einfach, fügen Sie einfach das entsprechende Helm-Repo hinzu und installieren Sie es.

(MoeLove) ➜ helm repo add kedacore https://kedacore.github.io/charts
"kedacore" wurde zu Ihren Repositories hinzugefügt
(MoeLove) ➜ helm repo update kedacore
Warten Sie, während wir die neuesten Updates aus Ihren Chart-Repositories abrufen...
...Erfolgreich ein Update aus dem "kedacore" Chart-Repository erhalten
Update abgeschlossen. ⎈Viel Spaß beim Helmen!⎈
(MoeLove) ➜ helm install keda kedacore/keda --namespace keda --create-namespace
NAME: keda
LAST DEPLOYED: Thu Jan 19 00:01:00 2023
NAMESPACE: keda
STATUS: deployed
REVISION: 1
TEST SUITE: None

Nach der Installation hat der Pod den Status Running, was darauf hinweist, dass er erfolgreich installiert wurde.

(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

Bereitstellung von Prometheus

Hier verwenden wir den Prometheus Operator, um Prometheus bereitzustellen. Der Prometheus Operator hilft uns, die Prometheus-Instanz schnell in Kubernetes bereitzustellen und die Überwachungsregeln durch deklarative Konfiguration hinzuzufügen.

Führen Sie die Installation des Prometheus Operators durch die folgenden Schritte durch.

(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

Verwenden Sie dann die folgende Konfiguration für Prometheus und wenden Sie sie auf den Kubernetes-Cluster an.

---
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

Nach der Anwendung auf den Kubernetes-Cluster können Sie sehen, dass eine Prometheus-Instanz im default-Namespace erstellt wurde. Da wir Prometheus mit dem TYPE LoadBalancer konfiguriert haben, können Benutzer direkt über die öffentliche IP des LoadBalancers auf Prometheus zugreifen.

(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

Bereitstellung des API-Gateways und Aktivierung der Überwachung

Als Nächstes wird der APISIX Ingress Controller bereitgestellt und Prometheus für die Metrikensammlung verwendet.

Die Methode ist ähnlich für Benutzer, die nur APISIX und nicht den APISIX Ingress Controller verwenden. Wir werden dies hier nicht gesondert erklären.

Hier wird Helm für die Bereitstellung verwendet, und der APISIX Ingress Controller sowie APISIX können gleichzeitig im Cluster bereitgestellt werden.

(MoeLove) ➜ helm repo add apisix https://charts.apiseven.com
"apisix" existiert bereits mit der gleichen Konfiguration, wird übersprungen
(MoeLove) ➜ helm repo update apisix
Warten Sie, während wir die neuesten Updates aus Ihren Chart-Repositories abrufen...
...Erfolgreich ein Update aus dem "apisix" Chart-Repository erhalten
Update abgeschlossen. ⎈Viel Spaß beim Helmen!⎈
(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" wurde aktualisiert. Viel Spaß beim Helmen!
NAME: apisix
LAST DEPLOYED: Thu Jan 19 02:11:23 2023
NAMESPACE: apisix
STATUS: deployed
REVISION: 1
TEST SUITE: None
NOTES:
1. Holen Sie sich die Anwendungs-URL, indem Sie diese Befehle ausführen:
     HINWEIS: Es kann einige Minuten dauern, bis die LoadBalancer-IP verfügbar ist.
           Sie können den Status verfolgen, indem Sie 'kubectl get --namespace apisix svc -w apisix-gateway' ausführen
  export SERVICE_IP=$(kubectl get svc --namespace apisix apisix-gateway --template "{{ range (index .status.loadBalancer.ingress 0) }}{{.}}{{ end }}")
  echo http://$SERVICE_IP:80

Aktivieren Sie als Nächstes das Prometheus-Plugin von APISIX. Bitte lesen Sie die folgenden beiden Dokumente für spezifische Konfigurationsmethoden und verwandte Parameter.

Sobald aktiviert, kann Prometheus die von APISIX bereitgestellten Metriken erfassen, indem eine ServiceMonitor-Ressource erstellt wird.

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

Überprüfung der elastischen Skalierungsfähigkeit der Anwendung

Erstellen Sie zuerst eine Anwendung.

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

Erstellen Sie die folgenden Routing-Regeln und wenden Sie sie auf den Kubernetes-Cluster an, um Anfragen über APISIX zu leiten.

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

Erstellen Sie als Nächstes ein KEDA ScaledObject und konfigurieren Sie die Prometheus-bezogenen Einstellungen.

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]))

Die obige Konfiguration bedeutet, dass sum(rate(apisix_http_status{route="httpserver-route"}[1m])) als Abfrageausdruck verwendet wird, und wenn das Ergebnis 10 erreicht, beginnt die Skalierung. (Die Konfiguration hier dient nur Demonstrationszwecken, bitte passen Sie sie an Ihre eigenen Bedürfnisse an). Dann senden wir kontinuierlich Anfragen an den httpbin-Dienst über curl.

Später, wenn wir die Anwendungs-Pods überprüfen, können Sie sehen, dass sie von KEDA auf zwei skaliert wurden.

(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

Wenn die Anwendung nach einiger Zeit im Leerlauf ist, werden wir feststellen, dass die Anzahl der Pods automatisch auf eine Instanz reduziert wurde.

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

Zusammenfassung

KEDA verwendet Prometheus als Scaler, um die von APISIX bereitgestellten Metriken zu sammeln. Da der gesamte Datenverkehr zuerst durch APISIX geleitet wird, ist die Erfassung von Statistiken auf der APISIX-Seite viel einfacher und bequemer.

Wenn das Volumen der Geschäftsanfragen steigt, wird die Anwendung automatisch skaliert, und wenn das Volumen der Geschäftsanfragen sinkt, wird die Anwendung automatisch verkleinert.

Diese Methode kann manuelle Skalierungs-/Reduzierungsoperationen in vielen Produktionsumgebungen erleichtern, um das beste Benutzererlebnis zu gewährleisten.

Tags: