التوسع التلقائي لتطبيقات Kubernetes باستخدام Prometheus وKEDA

التوسع التلقائي لتطبيقات Kubernetes باستخدام Prometheus وKEDAرجل البالون بواسطة كيموانوس

تعد قابلية التوسع مطلبًا أساسيًا للتطبيقات السحابية. مع Kubernetes، يعد توسيع نطاق التطبيق أمرًا بسيطًا مثل زيادة عدد النسخ المتماثلة للنشر المناسب أو ReplicaSet – لكنها عملية يدوية.

يسمح Kubernetes بتوسيع نطاق التطبيقات تلقائيًا (أي البودات في النشر أو ReplicaSet) بطريقة تعريفية باستخدام مواصفات Horizontal Pod Autoscaler. المعيار الافتراضي للقياس التلقائي هو مقاييس استخدام وحدة المعالجة المركزية (مقاييس الموارد)، ولكن يمكنك دمج المقاييس المخصصة والمقدمة خارجيًا.

فريق Kubernetes aaS من Mail.ru ترجمة مقال حول كيفية استخدام المقاييس الخارجية لتوسيع نطاق تطبيق Kubernetes تلقائيًا. لإظهار كيفية عمل كل شيء، يستخدم المؤلف مقاييس طلب الوصول إلى HTTP، والتي يتم جمعها باستخدام Prometheus.

بدلاً من القياس التلقائي الأفقي للبودات، يتم استخدام القياس التلقائي المدفوع بالأحداث في Kubernetes (KEDA)، وهو مشغل Kubernetes مفتوح المصدر. وهو يتكامل أصلاً مع Horizontal Pod Autoscaler لتوفير قياس تلقائي سلس (بما في ذلك من/إلى الصفر) لأحمال العمل المستندة إلى الأحداث. الكود متاح على GitHub جيثب:.

لمحة موجزة عن النظام

التوسع التلقائي لتطبيقات Kubernetes باستخدام Prometheus وKEDA

يوضح الرسم البياني وصفًا موجزًا ​​لكيفية عمل كل شيء:

  1. يوفر التطبيق مقاييس عدد مرات دخول HTTP بتنسيق Prometheus.
  2. تم تكوين بروميثيوس لجمع هذه المقاييس.
  3. تم تكوين مقياس Prometheus في KEDA لتوسيع نطاق التطبيق تلقائيًا بناءً على عدد زيارات HTTP.

الآن سأخبرك بالتفصيل عن كل عنصر.

كده وبروميثيوس

بروميثيوس هو جزء من مجموعة أدوات مراقبة وتنبيه النظام مفتوحة المصدر مؤسسة الحوسبة السحابية الأصلية. يجمع المقاييس من مصادر مختلفة ويخزنها كبيانات سلاسل زمنية. لتصور البيانات التي يمكنك استخدامها جرافانا أو أدوات التصور الأخرى التي تعمل مع Kubernetes API.

تدعم KEDA مفهوم المقياس - فهو يعمل كجسر بين KEDA والنظام الخارجي. يكون تطبيق المقياس خاصًا بكل نظام مستهدف ويستخرج البيانات منه. ثم تستخدمها KEDA للتحكم في القياس التلقائي.

تدعم أدوات القياس مصادر بيانات متعددة، على سبيل المثال، Kafka وRedis وPrometheus. وهذا يعني أنه يمكن استخدام KEDA لتوسيع نطاق عمليات نشر Kubernetes تلقائيًا باستخدام مقاييس Prometheus كمعايير.

تطبيق الاختبار

يوفر تطبيق اختبار Golang الوصول عبر HTTP ويؤدي وظيفتين مهمتين:

  1. يستخدم مكتبة عميل Prometheus Go لأداة التطبيق وتوفير مقياس http_requests، الذي يحتوي على عدد مرات الدخول. تقع نقطة النهاية حيث تتوفر مقاييس Prometheus في URI /metrics.
    var httpRequestsCounter = promauto.NewCounter(prometheus.CounterOpts{
           Name: "http_requests",
           Help: "number of http requests",
       })
    
  2. ردا على طلب GET يزيد التطبيق قيمة المفتاح (access_count) في ريديس. هذه طريقة سهلة للقيام بالعمل كجزء من معالج HTTP وكذلك التحقق من مقاييس Prometheus. يجب أن تكون قيمة المقياس هي نفس القيمة access_count في ريديس.
    func main() {
           http.Handle("/metrics", promhttp.Handler())
           http.HandleFunc("/test", func(w http.ResponseWriter, r 
    *http.Request) {
               defer httpRequestsCounter.Inc()
               count, err := client.Incr(redisCounterName).Result()
               if err != nil {
                   fmt.Println("Unable to increment redis counter", err)
                   os.Exit(1)
               }
               resp := "Accessed on " + time.Now().String() + "nAccess count " + strconv.Itoa(int(count))
               w.Write([]byte(resp))
           })
           http.ListenAndServe(":8080", nil)
       }
    

يتم نشر التطبيق على Kubernetes عبر Deployment. يتم أيضًا إنشاء خدمة ClusterIP، فهو يسمح لخادم Prometheus بالحصول على مقاييس التطبيق.

ها هو بيان النشر للتطبيق.

خادم بروميثيوس

يتكون بيان نشر بروميثيوس من:

  • ConfigMap — لنقل تكوين بروميثيوس؛
  • Deployment - لنشر بروميثيوس في مجموعة Kubernetes؛
  • ClusterIP — خدمة الوصول إلى واجهة المستخدم بروميثيوس.
  • ClusterRole, ClusterRoleBinding и ServiceAccount - للاكتشاف التلقائي للخدمات في Kubernetes (الاكتشاف التلقائي).

ها هو بيان لتشغيل بروميثيوس.

KEDA Prometheus ScaledObject

يعمل المقياس كجسر بين KEDA والنظام الخارجي الذي يجب الحصول على المقاييس منه. ScaledObject هو مورد مخصص يجب نشره لمزامنة النشر مع مصدر الحدث، وهو Prometheus في هذه الحالة.

ScaledObject يحتوي على معلومات قياس النشر وبيانات تعريف مصدر الحدث (مثل أسرار الاتصال واسم قائمة الانتظار) والفاصل الزمني للاستقصاء وفترة الاسترداد وبيانات أخرى. وينتج عن ذلك مورد القياس التلقائي المقابل (تعريف HPA) لتوسيع نطاق النشر.

عندما كائن ScaledObject إذا تم حذفه، فسيتم مسح تعريف HPA المقابل.

وهنا التعريف ScaledObject على سبيل المثال، يستخدم المقياس Prometheus:

apiVersion: keda.k8s.io/v1alpha1
kind: ScaledObject
metadata:
 name: prometheus-scaledobject
 namespace: default
 labels:
   deploymentName: go-prom-app
spec:
 scaleTargetRef:
   deploymentName: go-prom-app
 pollingInterval: 15
 cooldownPeriod:  30
 minReplicaCount: 1
 maxReplicaCount: 10
 triggers:
 - type: prometheus
   metadata:
     serverAddress: 
http://prometheus-service.default.svc.cluster.local:9090
     metricName: access_frequency
     threshold: '3'
     query: sum(rate(http_requests[2m]))

يرجى ملاحظة النقاط التالية:

  1. يشير إلى Deployment بالاسم go-prom-app.
  2. نوع الزناد - Prometheus. يتم ذكر عنوان خادم Prometheus مع اسم المقياس والعتبة و استعلام PromQL، والتي سيتم استخدامها. استعلام PromQL - sum(rate(http_requests[2m])).
  3. وفق pollingIntervalتطلب KEDA هدفًا من Prometheus كل خمس عشرة ثانية. واحد على الأقل تحت (minReplicaCount)، ولا يتجاوز الحد الأقصى لعدد القرون maxReplicaCount (في هذا المثال - عشرة).

يمكن تركيبها minReplicaCount يساوي الصفر. في هذه الحالة، تقوم KEDA بتنشيط النشر صفر إلى واحد ثم تعرض HPA لمزيد من القياس التلقائي. الترتيب العكسي ممكن أيضًا، أي القياس من واحد إلى الصفر. في المثال، لم نحدد الصفر لأن هذه خدمة HTTP وليست نظامًا حسب الطلب.

السحر داخل القياس التلقائي

يتم استخدام العتبة كمحفز لتوسيع نطاق النشر. في مثالنا، استعلام PromQL sum(rate (http_requests [2m])) إرجاع معدل طلب HTTP المجمع (الطلبات في الثانية)، والذي تم قياسه خلال الدقيقتين الأخيرتين.

وبما أن قيمة العتبة هي ثلاثة، فهذا يعني أنه سيكون هناك واحد أقل من القيمة sum(rate (http_requests [2m])) أقل من ثلاثة. إذا زادت القيمة، يتم إضافة فرع إضافي في كل مرة sum(rate (http_requests [2m])) يزيد بمقدار ثلاثة. على سبيل المثال، إذا كانت القيمة من 12 إلى 14، فإن عدد القرون هو أربعة.

الآن دعونا نحاول إعداده!

الإعداد المسبق

كل ما تحتاجه هو مجموعة Kubernetes وأداة مساعدة تم تكوينها kubectl. يستخدم هذا المثال كتلة minikube، ولكن يمكنك أن تأخذ أي واحد آخر. لتثبيت مجموعة هناك توجيه.

قم بتثبيت أحدث إصدار على نظام Mac:

curl -Lo minikube 
https://storage.googleapis.com/minikube/releases/latest/minikube-linux-amd64 
&& chmod +x minikube
sudo mkdir -p /usr/local/bin/
sudo install minikube /usr/local/bin/

ضبط kubectlللوصول إلى مجموعة Kubernetes.

قم بتثبيت أحدث إصدار على نظام Mac:

curl -LO 
"https://storage.googleapis.com/kubernetes-release/release/$(curl -s
https://storage.googleapis.com/kubernetes-release/release/stable.txt)/bin/darwin/amd64/kubectl"
chmod +x ./kubectl
sudo mv ./kubectl /usr/local/bin/kubectl
kubectl version

تركيب كده

يمكنك نشر KEDA بعدة طرق، وهي مدرجة في توثيق. أنا أستخدم YAML متجانسة:

kubectl apply -f
https://raw.githubusercontent.com/kedacore/keda/master/deploy/KedaScaleController.yaml

يتم تثبيت KEDA ومكوناته في مساحة الاسم keda. أمر بالتحقق:

kubectl get pods -n keda

انتظر حتى يبدأ مشغل KEDA وانتقل إلى Running State. وبعد ذلك، استمر.

تثبيت Redis باستخدام Helm

إذا لم يكن Helm مثبتًا لديك، فاستخدم هذا قيادة. أمر التثبيت على نظام Mac:

brew install kubernetes-helm
helm init --history-max 200

helm init تهيئة واجهة سطر الأوامر المحلية وتثبيتها أيضًا Tiller إلى مجموعة Kubernetes.

kubectl get pods -n kube-system | grep tiller

انتظر حتى تدخل جراب Tiller في حالة التشغيل.

ملاحظة المترجم: يستخدم المؤلف Helm@2، الأمر الذي يتطلب تثبيت مكون خادم Tiller. أصبح Helm@3 الآن ذا صلة، ولا يتطلب جزءًا من الخادم.

بعد تثبيت Helm، يكفي أمر واحد لبدء تشغيل Redis:

helm install --name redis-server --set cluster.enabled=false --set 
usePassword=false stable/redis

تحقق من بدء تشغيل Redis بنجاح:

kubectl get pods/redis-server-master-0

انتظر حتى يدخل Redis إلى الحالة Running.

نشر التطبيق

أمر النشر:

kubectl apply -f go-app.yaml

//output
deployment.apps/go-prom-app created
service/go-prom-app-service created

تأكد من أن كل شيء قد بدأ:

kubectl get pods -l=app=go-prom-app

انتظر حتى يدخل Redis إلى الحالة Running.

نشر خادم بروميثيوس

يستخدم بيان بروميثيوس اكتشاف خدمة Kubernetes لـ Prometheus. فهو يسمح بالاكتشاف الديناميكي لكبسولات التطبيق بناءً على ملصق الخدمة.

kubernetes_sd_configs:
   - role: service
   relabel_configs:
   - source_labels: [__meta_kubernetes_service_label_run]
     regex: go-prom-app-service
     action: keep

لنشر:

kubectl apply -f prometheus.yaml

//output
clusterrole.rbac.authorization.k8s.io/prometheus created
serviceaccount/default configured
clusterrolebinding.rbac.authorization.k8s.io/prometheus created
configmap/prom-conf created
deployment.extensions/prometheus-deployment created
service/prometheus-service created

تأكد من أن كل شيء قد بدأ:

kubectl get pods -l=app=prometheus-server

انتظر حتى يدخل بروميثيوس إلى الولاية Running.

استخدم kubectl port-forward للوصول إلى واجهة مستخدم Prometheus (أو خادم API) على http://localhost:9090.

kubectl port-forward service/prometheus-service 9090

نشر تكوين القياس التلقائي لـ KEDA

أمر بالإنشاء ScaledObject:

kubectl apply -f keda-prometheus-scaledobject.yaml

تحقق من سجلات مشغل KEDA:

KEDA_POD_NAME=$(kubectl get pods -n keda 
-o=jsonpath='{.items[0].metadata.name}')
kubectl logs $KEDA_POD_NAME -n keda

النتيجة تبدو مثل هذا:

time="2019-10-15T09:38:28Z" level=info msg="Watching ScaledObject:
default/prometheus-scaledobject"
time="2019-10-15T09:38:28Z" level=info msg="Created HPA with 
namespace default and name keda-hpa-go-prom-app"

تحقق تحت التطبيقات. يجب تشغيل مثيل واحد بسبب minReplicaCount يساوي 1:

kubectl get pods -l=app=go-prom-app

تحقق من إنشاء مورد HPA بنجاح:

kubectl get hpa

يجب أن ترى شيئًا مثل:

NAME                   REFERENCE                TARGETS     MINPODS   MAXPODS   REPLICAS   AGE
keda-hpa-go-prom-app   Deployment/go-prom-app   0/3 (avg)   1         10        1          45s

فحص الصحة: ​​الوصول إلى التطبيق

للوصول إلى نقطة نهاية REST لتطبيقنا، قم بتشغيل:

kubectl port-forward service/go-prom-app-service 8080

يمكنك الآن الوصول إلى تطبيق Go الخاص بك باستخدام العنوان http://localhost:8080. للقيام بذلك، قم بتشغيل الأمر:

curl http://localhost:8080/test

النتيجة تبدو مثل هذا:

Accessed on 2019-10-21 11:29:10.560385986 +0000 UTC 
m=+406004.817901246
Access count 1

عند هذه النقطة أيضًا تحقق من Redis. سترى أن المفتاح access_count ارتفع إلى 1:

kubectl exec -it redis-server-master-0 -- redis-cli get access_count
//output
"1"

تأكد من أن قيمة المقياس هي http_requests نفس الشيء:

curl http://localhost:8080/metrics | grep http_requests
//output
# HELP http_requests number of http requests
# TYPE http_requests counter
http_requests 1

إنشاء التحميل

سوف نستخدم مهلا - فائدة لتوليد الحمل:

curl -o hey https://storage.googleapis.com/hey-release/hey_darwin_amd64 
&& chmod a+x hey

يمكنك أيضًا تنزيل الأداة المساعدة لـ لينكس أو Windows.

شغلها:

./hey http://localhost:8080/test

بشكل افتراضي، ترسل الأداة المساعدة 200 طلب. يمكنك التحقق من ذلك باستخدام مقاييس Prometheus وكذلك Redis.

curl http://localhost:8080/metrics | grep http_requests
//output
# HELP http_requests number of http requests
# TYPE http_requests counter
http_requests 201
kubectl exec -it redis-server-master-0 -- redis-cli get access_count
//output
201

التحقق من صحة قيمة المقياس الفعلي (الذي يتم إرجاعه بواسطة استعلام PromQL):

curl -g 
'http://localhost:9090/api/v1/query?query=sum(rate(http_requests[2m]))'
//output
{"status":"success","data":{"resultType":"vector","result":[{"metric":{},"value":[1571734214.228,"1.686057971014493"]}]}}

وفي هذه الحالة تكون النتيجة الفعلية 1,686057971014493 ويتم عرضها في الميدان value. وهذا لا يكفي للقياس، حيث أن العتبة التي حددناها هي 3.

المزيد من الحمل!

في المحطة الجديدة، راقب عدد حجرات التطبيق:

kubectl get pods -l=app=go-prom-app -w

دعونا نزيد الحمل باستخدام الأمر:

./hey -n 2000 http://localhost:8080/test

بعد فترة من الوقت، سترى HPA تقوم بتوسيع نطاق النشر وإطلاق كبسولات جديدة. تحقق من HPA الخاص بك للتأكد من:

kubectl get hpa
NAME                   REFERENCE                TARGETS         MINPODS   MAXPODS   REPLICAS   AGE
keda-hpa-go-prom-app   Deployment/go-prom-app   1830m/3 (avg)   1         10        6          4m22s

إذا كان التحميل غير متناسق، فسيتم تقليل النشر إلى النقطة التي يتم فيها تشغيل حجرة واحدة فقط. إذا كنت تريد التحقق من المقياس الفعلي (الذي تم إرجاعه بواسطة استعلام PromQL)، فاستخدم الأمر:

curl -g 
'http://localhost:9090/api/v1/query?query=sum(rate(http_requests[2m]))'

تنظيف

//Delete KEDA
kubectl delete namespace keda
//Delete the app, Prometheus server and KEDA scaled object
kubectl delete -f .
//Delete Redis
helm del --purge redis-server

اختتام

تتيح لك KEDA إمكانية توسيع نطاق عمليات نشر Kubernetes تلقائيًا (من/إلى الصفر) بناءً على بيانات من مقاييس خارجية. على سبيل المثال، استنادًا إلى مقاييس Prometheus، وطول قائمة الانتظار في Redis، وزمن استجابة المستهلك في موضوع Kafka.

تتكامل KEDA مع مصدر خارجي وتوفر أيضًا مقاييسها من خلال Metrics Server إلى Horizontal Pod Autoscaler.

حظا سعيدا!

ماذا تقرأ:

  1. أفضل الممارسات وأفضل الممارسات لتشغيل الحاويات و Kubernetes في بيئات الإنتاج.
  2. أكثر من 90 أداة مفيدة لـ Kubernetes: النشر والإدارة والمراقبة والأمان والمزيد.
  3. قناتنا حول Kubernetes في Telegram.

المصدر: www.habr.com

إضافة تعليق