קנה מידה אוטומטי של יישומי Kubernetes באמצעות Prometheus ו-KEDA

קנה מידה אוטומטי של יישומי Kubernetes באמצעות Prometheus ו-KEDAאיש הבלונים מאת Cimuanos

מדרגיות היא דרישת מפתח עבור יישומי ענן. עם Kubernetes, שינוי קנה מידה של יישום הוא פשוט כמו הגדלת מספר העתקים לפריסה המתאימה או ReplicaSet - אבל זה תהליך ידני.

Kubernetes מאפשר שינוי קנה מידה אוטומטי של יישומים (כלומר Pods בפריסה או ReplicaSet) בצורה הצהרתית תוך שימוש במפרט Horizontal Pod Autoscaler. קריטריון ברירת המחדל עבור קנה מידה אוטומטי הוא מדדי שימוש במעבד (מדדי משאבים), אך ניתן לשלב מדדים מותאמים אישית ומסופקים חיצונית.

קבוצה Kubernetes aaS מ-Mail.ru תרגם מאמר על איך להשתמש במדדים חיצוניים כדי לשנות קנה מידה אוטומטי של יישום Kubernetes. כדי להראות איך הכל עובד, המחבר משתמש במדדי בקשת גישה ל-HTTP, שנאספים באמצעות Prometheus.

במקום קנה מידה אוטומטי אופקי של תרמילים, נעשה שימוש ב-Kubernetes Event Driven Autoscaling (KEDA), מפעיל קוד פתוח של Kubernetes. הוא משתלב באופן מקורי עם Horizontal Pod Autoscaler כדי לספק קנה מידה אוטומטי חלק (כולל עד/מאפס) לעומסי עבודה מונעי אירועים. קוד זמין ב GitHub.

סקירה קצרה של המערכת

קנה מידה אוטומטי של יישומי Kubernetes באמצעות Prometheus ו-KEDA

התרשים מציג תיאור קצר של איך הכל עובד:

  1. האפליקציה מספקת מדדי ספירת כניסות HTTP בפורמט Prometheus.
  2. פרומתאוס מוגדר לאסוף מדדים אלה.
  3. ה-Prometheus scaler ב-KEDA מוגדר לשינוי קנה מידה אוטומטי של האפליקציה בהתבסס על מספר כניסות HTTP.

עכשיו אני אספר לך בפירוט על כל אלמנט.

KEDA ופרומתאוס

Prometheus הוא ערכת כלים לניטור והתראה של מערכת קוד פתוח, חלק קרן מחשוב מקומית לענן. אוסף מדדים ממקורות שונים ומאחסן אותם כנתוני סדרות זמן. כדי להמחיש נתונים אתה יכול להשתמש גרפנה או כלי הדמיה אחרים שעובדים עם ה-API של Kubernetes.

KEDA תומך ברעיון של scaler - הוא משמש כגשר בין KEDA למערכת החיצונית. הטמעת scaler ספציפית לכל מערכת יעד ומחלצת ממנה נתונים. לאחר מכן KEDA משתמש בהם כדי לשלוט בקנה מידה אוטומטי.

סקולרים תומכים במקורות נתונים מרובים, למשל, Kafka, Redis, Prometheus. כלומר, ניתן להשתמש ב-KEDA לשינוי קנה מידה אוטומטי של פריסות Kubernetes באמצעות מדדי Prometheus כקריטריונים.

יישום בדיקה

אפליקציית הבדיקה של Golang מספקת גישה באמצעות HTTP ומבצעת שתי פונקציות חשובות:

  1. משתמש בספריית הלקוחות של Prometheus Go כדי להכשיר את האפליקציה ולספק את המדד http_requests, המכיל ספירת התאמות. נקודת הקצה שבה זמינים מדדי פרומתאוס ממוקמת ב-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 - לפריסת Prometheus באשכול Kubernetes;
  • ClusterIP - שירות לגישה לממשק המשתמש Prometheus;
  • ClusterRole, ClusterRoleBinding и ServiceAccount - לזיהוי אוטומטי של שירותים ב-Kubernetes (גילוי אוטומטי).

כאן מניפסט להפעלת פרומתאוס.

KEDA Prometheus ScaledObject

ה-scaler משמש כגשר בין KEDA למערכת החיצונית שממנה צריך לקבל מדדים. ScaledObject הוא משאב מותאם אישית שצריך לפרוס כדי לסנכרן את הפריסה עם מקור האירוע, במקרה זה Prometheus.

ScaledObject מכיל מידע על קנה מידה של פריסה, מטא נתונים של מקור אירועים (כגון סודות חיבור, שם תור), מרווח סקר, תקופת שחזור ונתונים אחרים. זה גורם למשאב קנה המידה האוטומטי המתאים (הגדרת HPA) כדי לשנות את קנה המידה של הפריסה.

כאשר חפץ ScaledObject נמחק, ההגדרה המתאימה של HPA נמחקת.

הנה ההגדרה ScaledObject עבור הדוגמה שלנו, הוא משתמש ב-scaler 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 מבקש מטרה מפרומתאוס כל חמש עשרה שניות. לפחות אחד מתחת (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/

להתקין קובקטלכדי לגשת לאשכול 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

אתה יכול לפרוס את KEDA בכמה דרכים, הם רשומים ב תיעוד. אני משתמש ב-YAML מונוליטי:

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

KEDA ורכיביו מותקנים במרחב השמות keda. פקודה לבדיקה:

kubectl get pods -n keda

המתן ל-KEDA Operator שיתחיל ויעבור אל 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 להיכנס למצב Running.

הערת המתרגם: המחבר משתמש ב- 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.

פריסת שרת פרומתאוס

מניפסט פרומתאוס משתמש גילוי שירות Kubernetes עבור פרומתאוס. הוא מאפשר גילוי דינמי של תרמילים של יישומים בהתבסס על תווית השירות.

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

אתה יכול גם להוריד את כלי השירות עבור 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 שלך (מאפס/מאפס) על סמך נתונים מדדים חיצוניים. לדוגמה, בהתבסס על מדדי Prometheus, אורך תור ברדיס, זמן חביון צרכני בנושא קפקא.

KEDA משתלב עם מקור חיצוני וגם מספק את המדדים שלו דרך שרת מדדים ל- Horizontal Pod Autoscaler.

מזל טוב!

מה עוד לקרוא:

  1. שיטות עבודה מומלצות ושיטות עבודה מומלצות להפעלת קונטיינרים ו-Kubernetes בסביבות ייצור.
  2. 90+ כלים שימושיים עבור Kubernetes: פריסה, ניהול, ניטור, אבטחה ועוד.
  3. הערוץ שלנו Around Kubernetes בטלגרם.

מקור: www.habr.com

קנה אירוח אמין לאתרים עם הגנת DDoS, שרתי VPS VDS 🔥 קנה אחסון אתרים אמין עם הגנת DDoS, שרתי VPS VDS | ProHoster