
Scalability مطلبًا أساسيًا للتطبيقات السحابية. باستخدام Kubernetes ، يكون قياس التطبيق سهلاً مثل زيادة عدد النسخ المتماثلة للنشر المناسب ، أو
ReplicaSet- لكنها عملية يدوية.
يسمح Kubernetes للتطبيقات بالتدرج التلقائي (أي Pods قيد النشر أو
ReplicaSet) بطريقة توضيحية باستخدام مواصفات Horizontal Pod Autoscaler. المعيار الافتراضي للقياس التلقائي هو مقاييس استخدام وحدة المعالجة المركزية (مقاييس الموارد) ، ولكن يمكن دمج المقاييس المخصصة والمقاييس المتوفرة خارجيًا.
فريق Kubernetes aaS من Mail.ruترجمة مقال عن كيفية استخدام المقاييس الخارجية لتوسيع نطاق تطبيق Kubernetes الخاص بك تلقائيًا. لإظهار كيفية عمل كل شيء ، يستخدم المؤلف مقاييس طلب وصول HTTP ، ويتم جمعها باستخدام بروميثيوس.
بدلاً من القياس التلقائي للقرون الأفقية ، فإن Kubernetes Event Driven Autoscaling (KEDA) هو مشغل Kubernetes مفتوح المصدر. إنه يتكامل أصلاً مع مقياس البودات الأوتوماتيكي الأفقي لتوفير قياس تلقائي سلس (بما في ذلك من / إلى الصفر) لأحمال العمل التي تحركها الأحداث. الكود متاح على جيثب .
موجز تشغيل النظام
يوضح الرسم البياني وصفًا موجزًا لكيفية عمل كل شيء:
- يوفر التطبيق مقاييس لعدد طلبات HTTP بتنسيق Prometheus.
- تم تعيين بروميثيوس لجمع هذه المقاييس.
- تم تكوين قشارة Prometheus في KEDA لتوسيع نطاق التطبيق تلقائيًا بناءً على عدد طلبات HTTP.
الآن سوف أخبرك بالتفصيل عن كل عنصر.
كيدا وبروميثيوس
بروميثيوس عبارة عن مجموعة أدوات مراقبة وتنبيه نظام مفتوح المصدر ، وهي جزء من Cloud Native Computing Foundation . يجمع المقاييس من مصادر مختلفة ويحفظها كبيانات سلاسل زمنية. لتصور البيانات ، يمكنك استخدام Grafana أو أدوات التمثيل المرئي الأخرى التي تعمل مع Kubernetes API.
يدعم KEDA مفهوم قشارة - يعمل كجسر بين KEDA والنظام الخارجي. يكون تنفيذ المتسلق محددًا لكل نظام مستهدف ويستخرج البيانات منه. ثم يستخدمهم KEDA للتحكم في القياس التلقائي.
تدعم أدوات القياس مصادر بيانات متعددة مثل كافكا وريديس وبروميثيوس. أي أنه يمكن استخدام KEDA لتوسيع نطاق عمليات نشر Kubernetes تلقائيًا باستخدام مقاييس بروميثيوس كمعايير.
تطبيق الاختبار
يوفر تطبيق اختبار Golang وصول HTTP ويؤدي وظيفتين مهمتين:
- يستخدم مكتبة عميل Prometheus Go لأداة التطبيق وتوفير http_requests مقياس يحتوي على عداد دخول. توجد نقطة النهاية التي تتوفر لها مقاييس بروميثيوس بواسطة URI
/metrics.
var httpRequestsCounter = promauto.NewCounter(prometheus.CounterOpts{ Name: "http_requests", Help: "number of http requests", }) - استجابةً للطلب ، يقوم
GETالتطبيق بزيادة قيمة المفتاح (access_count) في Redis. هذه طريقة سهلة لإنجاز المهمة كجزء من معالج HTTP ، وكذلك التحقق من مقاييس Prometheus. يجب أن تكون قيمة المقياس مماثلة للقيمةaccess_countفي Redis.
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تتيح لخادم بروميثيوس تلقي مقاييس التطبيق.
هنا بيان النشر للتطبيق .
خادم بروميثيوس
يتكون بيان نشر بروميثيوس من:
ConfigMap- لنقل تهيئة بروميثيوس ؛Deployment- لنشر بروميثيوس في مجموعة Kubernetes ؛ClusterIP- خدمة الوصول إلى UI Prometheus ؛ClusterRole،ClusterRoleBindingوServiceAccount- لصناعة السيارات في الكشف عن الخدمات في Kubernetes (التلقائي اكتشاف).
هنا هو البيان لتشغيل بروميثيوس .
كيدا بروميثيوس 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]))
ضع في اعتبارك النقاط التالية:
- يشير إلى
Deploymentباسمgo-prom-app. - نوع الزناد -
Prometheus. تم ذكر عنوان خادم Prometheus جنبًا إلى جنب مع اسم المقياس والعتبة وطلب PromQL المراد استخدامه. طلب PromQL -sum(rate(http_requests[2m])). - وفقًا لـ
pollingIntervalKEDA ، فإنها تطلب هدفًا من بروميثيوس كل خمس عشرة ثانية.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تهيئة CLI المحلي وتثبيته أيضًا Tillerفي مجموعة Kubernetes.
kubectl get pods -n kube-system | grep 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
انتظر حتى يذهب ريديس إلى الحالة
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.
نشر خادم بروميثيوس
يستخدم Prometheus Manifest يستخدم Kubernetes Service Discovery لـ 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"
تحقق تحت التطبيقات. يجب تشغيل مثيل واحد لأنه
minReplicaCount1:
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
يمكنك أيضًا تنزيل الأداة المساعدة لنظامي التشغيل Linux أو 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 تلقائيًا (من / إلى الصفر) استنادًا إلى البيانات من المقاييس الخارجية. على سبيل المثال ، استنادًا إلى مقاييس بروميثيوس ، وطول قائمة الانتظار في Redis ، ووقت استجابة المستهلك في سمة كافكا.
تتكامل KEDA مع مصدر خارجي وتوفر أيضًا مقاييس من خلال Metrics Server لـ Horizontal Pod Autoscaler.
حظا سعيدا!
ماذا تقرأ: