استخدم APISIX و Prometheus و KEDA لتوسيع تطبيقاتك بشكل مرن في Kubernetes

Jintao Zhang

Jintao Zhang

February 17, 2023

Technology

مقدمة

تختلف كمية الحركة المرورية التي تدخل إلى التطبيق من وقت لآخر. على سبيل المثال، يكون تطبيق التسوق عبر الإنترنت أكثر انشغالًا خلال مواسم العطلات مقارنة بالأيام العادية. القدرة على ضبط سعة التطبيق بناءً على الحركة المرورية ستوفر تجارب وخدمات أفضل للمستخدمين.

Apache APISIX هو بوابة API عالية الأداء مصممة للعمل في البيئات السحابية، ويمكنها توفير مقاييس ذات معنى لتحديد ما إذا كان التطبيق بحاجة إلى التوسع. إنه برنامج وسيط يعالج كل الحركة المرورية المرسلة إلى التطبيقات العلوية، وبالتالي يمكنه جمع بيانات الحركة المرورية خلال هذه العملية.

لتنفيذ التوسع المرن، سيتم استخدام KEDA كوحدة تحكم، وPrometheus سيتم استخدامه لجلب المقاييس التي يوفرها APISIX.

استخدام KEDA للتوسع التلقائي

كيفية استخدام مقياس Prometheus في KEDA

KEDA هو مقياس توسع يعتمد على الأحداث في Kubernetes، ويمكنه تكوين مقاييس مختلفة. في هذه المقالة، سيتم استخدام مقياس Prometheus للحصول على المقاييس التي يعرضها APISIX.

نشر KEDA

نشر KEDA بسيط نسبيًا، فقط قم بإضافة مستودع Helm المقابل وقم بتثبيته.

(MoeLove) ➜ helm repo add kedacore https://kedacore.github.io/charts
تمت إضافة "kedacore" إلى مستودعاتك
(MoeLove) ➜ helm repo update kedacore
انتظر بينما نحصل على آخر التحديثات من مستودعاتك...
...تم الحصول على تحديث بنجاح من مستودع "kedacore"
التحديث مكتمل. ⎈تمنياتنا بالنجاح في استخدام Helm!⎈
(MoeLove) ➜ helm install keda kedacore/keda --namespace keda --create-namespace
الاسم: keda
تم النشر الأخير: الخميس 19 يناير 00:01:00 2023
مساحة الاسم: keda
الحالة: تم النشر
الإصدار: 1
مجموعة الاختبار: لا شيء

بعد التثبيت، يكون للـ Pod حالة status Running، مما يشير إلى أنه تم تثبيته.

(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

نشر Prometheus

هنا نستخدم Prometheus Operator لنشر Prometheus. يمكن لـ Prometheus Operator مساعدتنا في نشر نسخة Prometheus بسرعة في Kubernetes وإضافة قواعد المراقبة من خلال التكوين التصريحي.

أكمل تثبيت Prometheus Operator من خلال الخطوات التالية.

(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

ثم استخدم التكوين التالي لـ Prometheus وقم بتطبيقه على مجموعة 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

بعد التطبيق على مجموعة Kubernetes، يمكنك رؤية أن نسخة Prometheus تم إنشاؤها تحت مساحة الاسم default. نظرًا لأننا قمنا بتكوين Prometheus مع TYPE LoadBalancer، يمكن للمستخدمين الوصول مباشرة إلى Prometheus من خلال عنوان IP العام لـ 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

كيفية نشر بوابة API وتمكين المراقبة

بعد ذلك، قم بنشر وحدة تحكم APISIX Ingress واستخدم Prometheus لجمع المقاييس.

الطريقة مشابهة للمستخدمين الذين يستخدمون APISIX فقط بدلاً من وحدة تحكم APISIX Ingress. لن نشرحها بشكل منفصل هنا.

هنا، يتم استخدام Helm للنشر، ويمكن نشر وحدة تحكم APISIX Ingress وAPISIX في نفس الوقت إلى المجموعة.

(MoeLove) ➜ helm repo add apisix https://charts.apiseven.com
"apisix" موجود بالفعل بنفس التكوين، يتم التخطي
(MoeLove) ➜ helm repo update apisix
انتظر بينما نحصل على آخر التحديثات من مستودعاتك...
...تم الحصول على تحديث بنجاح من مستودع "apisix"
التحديث مكتمل. ⎈تمنياتنا بالنجاح في استخدام 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
تم ترقية الإصدار "apisix". تمنياتنا بالنجاح في استخدام Helm!
الاسم: apisix
تم النشر الأخير: الخميس 19 يناير 02:11:23 2023
مساحة الاسم: apisix
الحالة: تم النشر
الإصدار: 1
مجموعة الاختبار: لا شيء
ملاحظات:
1. احصل على عنوان URL للتطبيق عن طريق تشغيل هذه الأوامر:
     ملاحظة: قد يستغرق الحصول على عنوان IP لـ LoadBalancer بضع دقائق.
           يمكنك مشاهدة الحالة عن طريق تشغيل '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

بعد ذلك، قم بتمكين مكون Prometheus الخاص بـ APISIX. يرجى الرجوع إلى الوثائق التالية لطرق التكوين المحددة والمعلمات ذات الصلة.

بمجرد التمكين، يمكن لـ Prometheus التقاط المقاييس التي يعرضها APISIX عن طريق إنشاء مورد ServiceMonitor.

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

التحقق من قدرة التطبيق على التوسع المرن

قم بإنشاء تطبيق أولاً.

(MoeLove) ➜ kubectl create deploy httpbin --image=kennethreitz/httpbin --port=80
تم إنشاء deployment.apps/httpbin
(MoeLove) ➜ kubectl expose deploy httpbin --port 80

قم بإنشاء قواعد التوجيه التالية وقم بتطبيقها على مجموعة Kubernetes لتوجيه الطلبات عبر 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

بعد ذلك، قم بإنشاء ScaledObject لـ KEDA وقم بتكوين إعدادات 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]))

التكوين أعلاه يعني أن sum(rate(apisix_http_status{route="httpserver-route"}[1m])) سيتم استخدامه كتعبير استعلام، وإذا كانت النتيجة تصل إلى 10، سيبدأ التوسع. (التكوين هنا هو لأغراض العرض فقط، يرجى تعديله وفقًا لاحتياجاتك الخاصة). ثم نقوم بإجراء طلبات مستمرة إلى خدمة httpbin عبر curl.

لاحقًا، إذا قمنا بفحص تطبيق pods، يمكنك رؤية أنه تم توسيعه تلقائيًا إلى اثنين بواسطة 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

عندما يكون التطبيق في حالة خمول بعد بعض الوقت، سنجد أن عدد pods قد تقلص تلقائيًا إلى نسخة واحدة.

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

الخلاصة

يستخدم KEDA Prometheus كمقياس لجمع المقاييس التي يعرضها APISIX. نظرًا لأن كل الحركة المرورية تمر عبر APISIX أولاً، فإن الحصول على إحصائيات من جانب APISIX سيكون أسهل وأكثر ملاءمة.

عندما تزداد كمية طلبات الأعمال، سيتم توسيع التطبيق تلقائيًا، وعندما تنخفض كمية طلبات الأعمال، سيتم تقليص التطبيق تلقائيًا.

هذه الطريقة يمكن أن تخفف من عمليات التوسع/التقليص اليدوية في العديد من بيئات الإنتاج لضمان أفضل تجربة للمستخدمين.

Tags: