אופטימיזציה של התאמה אוטומטית של קבוצות Pod לעומס על סמך מדדים

במדריך הזה מוסבר איך לשנות את גודל עומסי העבודה ב-Google Kubernetes Engine ‏ (GKE) באופן אוטומטי על סמך מדדים שזמינים ב-Cloud Monitoring.

במדריך הזה תוכלו להגדיר שינוי גודל אוטומטי על סמך אחד מהמדדים הבאים:

Pub/Sub

Pub/Sub backlog

שינוי קנה המידה על סמך מדד חיצוני שמדווח על מספר ההודעות שלא אושרו שנותרו במינוי Pub/Sub. השיטה הזו יכולה לצמצם את זמן האחזור לפני שהוא הופך לבעיה, אבל היא עשויה להשתמש ביותר משאבים יחסית בהשוואה להתאמה אוטומטית לעומס שמבוססת על ניצול המעבד.

מדד מותאם אישית

מדד Prometheus מותאם אישית

שינוי קנה מידה על סמך מדד מותאם אישית שהוגדר על ידי המשתמש, ומיוצא בפורמט Prometheus דרך Google Managed Prometheus. מדד Prometheus צריך להיות מסוג Gauge.

התאמה אוטומטית לעומס (autoscaling) מבוססת על מציאת איזון מקובל בין עלות לבין זמן אחזור. כדאי לנסות שילוב של המדדים האלה ועוד כדי למצוא מדיניות שמתאימה לכם.

מטרות

במדריך הזה מוסבר איך לבצע את הפעולות הבאות:

  1. איך פורסים את Custom Metrics Adapter.
  2. איך מייצאים מדדים מתוך קוד האפליקציה.
  3. איך רואים את המדדים בממשק של Cloud Monitoring.
  4. איך פורסים משאב HorizontalPodAutoscaler (HPA) כדי לשנות את קנה המידה של האפליקציה על סמך מדדים של Cloud Monitoring.

עלויות

במסמך הזה משתמשים ברכיבים הבאים של Google Cloud, והשימוש בהם כרוך בתשלום:

כדי ליצור הערכת עלויות בהתאם לשימוש החזוי, אפשר להשתמש במחשבון התמחור.

יכול להיות שמשתמשים חדשים ב- Google Cloud זכאים לתקופת ניסיון בחינם.

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

לפני שמתחילים

כדי להפעיל את Kubernetes Engine API:
  1. נכנסים ל דף Kubernetes Engine במסוף Google Cloud .
  2. יוצרים או בוחרים פרויקט.
  3. מחכים עד שממשק ה-API והשירותים הקשורים מופעלים. הפעולה יכולה להימשך כמה דקות.
  4. Verify that billing is enabled for your Google Cloud project.

אפשר לפעול לפי ההוראות במדריך הזה באמצעות Cloud Shell, שמותקנים בו מראש כלי שורת הפקודה gcloud ו-kubectl שמשמשים במדריך הזה. אם אתם משתמשים ב-Cloud Shell, אתם לא צריכים להתקין את כלי שורת הפקודה האלה בתחנת העבודה שלכם.

כדי להשתמש ב-Cloud Shell:

  1. עוברים אל Google Cloud המסוף.
  2. לוחצים על הלחצן Activate Cloud Shell כפתור ההפעלה של Shell בחלק העליון של חלון המסוף. Google Cloud

    בחלק התחתון של מסוף Google Cloud ייפתח סשן של Cloud Shell בתוך מסגרת חדשה, ותופיע הודעה של שורת הפקודה.

    סשן Cloud Shell

הגדרת הסביבה

  1. מגדירים את אזור ברירת המחדל ל-Google Cloud CLI:

    gcloud config set compute/zone zone
    

    מחליפים את מה שכתוב בשדות הבאים:

    • zone: בוחרים את האזור שהכי קרוב אליכם. מידע נוסף זמין במאמר אזורים ותחומים.
  2. מגדירים את משתני הסביבה PROJECT_ID ו-PROJECT_NUMBER למזהה הפרויקט ומספר הפרויקטGoogle Cloud :

    export PROJECT_ID=project-id
    export PROJECT_NUMBER=$(gcloud projects describe $PROJECT_ID --format 'get(projectNumber)')
    
  3. מגדירים את אזור ברירת המחדל ל-Google Cloud CLI:

    gcloud config set project $PROJECT_ID
    
  4. יצירת אשכול GKE

    שיטה מומלצת:

    כדי לשפר את האבטחה כשניגשים לשירותים, מומלץ להפעיל את איחוד זהויות של עומסי עבודה ל-GKE באשכול. Google Cloud בדף הזה יש דוגמאות לשימוש בשיטה מדור קודם (עם השבתה של איחוד שירותי אימות הזהות של עומסי עבודה ב-GKE), אבל הפעלת השיטה משפרת את ההגנה.

    Workload Identity

    כדי ליצור אשכול עם איחוד זהויות של עומסי עבודה ל-GKE מופעל, מריצים את הפקודה הבאה:

    gcloud container clusters create metrics-autoscaling --workload-pool=$PROJECT_ID.svc.id.goog
    

    אימות מדור קודם

    כדי ליצור אשכול עם איחוד זהויות של עומסי עבודה ל-GKE מושבת, מריצים את הפקודה הבאה:

    gcloud container clusters create metrics-autoscaling
    

פריסת המתאם של מדדים מותאמים אישית

Custom Metrics Adapter מאפשר לאשכול לשלוח ולקבל מדדים באמצעות Cloud Monitoring.

Pub/Sub

התהליך להתקנת Custom Metrics Adapter שונה באשכולות שמופעל בהם איחוד זהויות של עומסי עבודה ל-GKE ובאשכולות שלא מופעל בהם איחוד זהויות של עומסי עבודה ל-GKE. בוחרים את האפשרות שמתאימה להגדרה שבחרתם כשיצרתם את האשכול.

Workload Identity

נותנים למשתמש את היכולת ליצור תפקידי הרשאה נדרשים:

kubectl create clusterrolebinding cluster-admin-binding \
    --clusterrole cluster-admin --user "$(gcloud config get-value account)"

פורסים את המתאם של המדדים המותאמים אישית באשכול:

kubectl apply -f https://raw.githubusercontent.com/GoogleCloudPlatform/k8s-stackdriver/master/custom-metrics-stackdriver-adapter/deploy/production/adapter_new_resource_model.yaml

המתאם משתמש בחשבון השירות custom-metrics-stackdriver-adapter Kubernetes במרחב השמות custom-metrics. כדי לאפשר לחשבון השירות הזה לקרוא מדדים של Cloud Monitoring, צריך להקצות לו את התפקיד Monitoring Viewer:

gcloud projects add-iam-policy-binding projects/$PROJECT_ID \
  --role roles/monitoring.viewer \
  --member=principal://iam.googleapis.com/projects/$PROJECT_NUMBER/locations/global/workloadIdentityPools/$PROJECT_ID.svc.id.goog/subject/ns/custom-metrics/sa/custom-metrics-stackdriver-adapter

אימות מדור קודם

נותנים למשתמש את היכולת ליצור תפקידי הרשאה נדרשים:

kubectl create clusterrolebinding cluster-admin-binding \
    --clusterrole cluster-admin --user "$(gcloud config get-value account)"

פורסים את המתאם של המדדים המותאמים אישית באשכול:

kubectl apply -f https://raw.githubusercontent.com/GoogleCloudPlatform/k8s-stackdriver/master/custom-metrics-stackdriver-adapter/deploy/production/adapter_new_resource_model.yaml

מדד מותאם אישית

התהליך להתקנת Custom Metrics Adapter שונה באשכולות שמופעל בהם איחוד זהויות של עומסי עבודה ל-GKE ובאשכולות שלא מופעל בהם איחוד זהויות של עומסי עבודה ל-GKE. בוחרים את האפשרות שמתאימה להגדרה שבחרתם כשיצרתם את האשכול.

Workload Identity

נותנים למשתמש את היכולת ליצור תפקידי הרשאה נדרשים:

kubectl create clusterrolebinding cluster-admin-binding \
    --clusterrole cluster-admin --user "$(gcloud config get-value account)"

פורסים את המתאם של המדדים המותאמים אישית באשכול:

kubectl apply -f https://raw.githubusercontent.com/GoogleCloudPlatform/k8s-stackdriver/master/custom-metrics-stackdriver-adapter/deploy/production/adapter_new_resource_model.yaml

המתאם משתמש בחשבון השירות custom-metrics-stackdriver-adapter Kubernetes במרחב השמות custom-metrics. כדי לאפשר לחשבון השירות הזה לקרוא מדדים של Cloud Monitoring, צריך להקצות לו את התפקיד Monitoring Viewer:

gcloud projects add-iam-policy-binding projects/$PROJECT_ID \
  --role roles/monitoring.viewer \
  --member=principal://iam.googleapis.com/projects/$PROJECT_NUMBER/locations/global/workloadIdentityPools/$PROJECT_ID.svc.id.goog/subject/ns/custom-metrics/sa/custom-metrics-stackdriver-adapter

אימות מדור קודם

נותנים למשתמש את היכולת ליצור תפקידי הרשאה נדרשים:

kubectl create clusterrolebinding cluster-admin-binding \
    --clusterrole cluster-admin --user "$(gcloud config get-value account)"

פורסים את המתאם של המדדים המותאמים אישית באשכול:

kubectl apply -f https://raw.githubusercontent.com/GoogleCloudPlatform/k8s-stackdriver/master/custom-metrics-stackdriver-adapter/deploy/production/adapter_new_resource_model.yaml

פריסת אפליקציה עם מדדים

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

Pub/Sub

git clone https://github.com/GoogleCloudPlatform/kubernetes-engine-samples.git
cd kubernetes-engine-samples/databases/cloud-pubsub

מדד מותאם אישית

git clone https://github.com/GoogleCloudPlatform/kubernetes-engine-samples.git
cd kubernetes-engine-samples/observability/custom-metrics-autoscaling/google-managed-prometheus

המאגר מכיל קוד שמייצא מדדים ל-Cloud Monitoring:

Pub/Sub

האפליקציה הזו מבצעת סקר במינוי Pub/Sub כדי לבדוק אם יש הודעות חדשות, ומאשרת את קבלתן כשהן מגיעות. מדדי המינויים ל-Pub/Sub נאספים באופן אוטומטי על ידי Cloud Monitoring.

from google import auth
from google.cloud import pubsub_v1


def main():
    """Continuously pull messages from subsciption"""

    # read default project ID
    _, project_id = auth.default()
    subscription_id = 'echo-read'

    subscriber = pubsub_v1.SubscriberClient()
    subscription_path = subscriber.subscription_path(
        project_id, subscription_id)

    def callback(message: pubsub_v1.subscriber.message.Message) -> None:
        """Process received message"""
        print(f"Received message: ID={message.message_id} Data={message.data}")
        print(f"[{datetime.datetime.now()}] Processing: {message.message_id}")
        time.sleep(3)
        print(f"[{datetime.datetime.now()}] Processed: {message.message_id}")
        message.ack()

    streaming_pull_future = subscriber.subscribe(
        subscription_path, callback=callback)
    print(f"Pulling messages from {subscription_path}...")

    with subscriber:
        try:
            streaming_pull_future.result()
        except Exception as e:
            print(e)

מדד מותאם אישית

האפליקציה הזו מגיבה לכל בקשת אינטרנט לנתיב /metrics עם מדד ערך קבוע בפורמט Prometheus.

metric := prometheus.NewGauge(
	prometheus.GaugeOpts{
		Name: *metricName,
		Help: "Custom metric",
	},
)
prometheus.MustRegister(metric)
metric.Set(float64(*metricValue))

http.Handle("/metrics", promhttp.Handler())
log.Printf("Starting to listen on :%d", *port)
err := http.ListenAndServe(fmt.Sprintf(":%d", *port), nil)

המאגר מכיל גם מניפסט של Kubernetes לפריסת האפליקציה באשכול. פריסה היא אובייקט Kubernetes API שמאפשר להפעיל כמה רפליקות של Pods שמפוזרות בין הצמתים באשכול.

Pub/Sub

המאניפסט שונה באשכולות שמופעל בהם איחוד זהויות של עומסי עבודה ל-GKE ובאשכולות שלא מופעל בהם איחוד זהויות של עומסי עבודה ל-GKE. בוחרים את האפשרות שמתאימה להגדרה שבחרתם כשיצרתם את האשכול.

Workload Identity

apiVersion: apps/v1
kind: Deployment
metadata:
  name: pubsub
spec:
  selector:
    matchLabels:
      app: pubsub
  template:
    metadata:
      labels:
        app: pubsub
    spec:
      serviceAccountName: pubsub-sa
      containers:
      - name: subscriber
        image: us-docker.pkg.dev/google-samples/containers/gke/pubsub-sample:v2

אימות מדור קודם

apiVersion: apps/v1
kind: Deployment
metadata:
  name: pubsub
spec:
  selector:
    matchLabels:
      app: pubsub
  template:
    metadata:
      labels:
        app: pubsub
    spec:
      volumes:
      - name: google-cloud-key
        secret:
          secretName: pubsub-key
      containers:
      - name: subscriber
        image: us-docker.pkg.dev/google-samples/containers/gke/pubsub-sample:v2
        volumeMounts:
        - name: google-cloud-key
          mountPath: /var/secrets/google
        env:
        - name: GOOGLE_APPLICATION_CREDENTIALS
          value: /var/secrets/google/key.json

מדד מותאם אישית

apiVersion: apps/v1
kind: Deployment
metadata:
  labels:
    run: custom-metrics-gmp
  name: custom-metrics-gmp
  namespace: default
spec:
  replicas: 1
  selector:
    matchLabels:
      run: custom-metrics-gmp
  template:
    metadata:
      labels:
        run: custom-metrics-gmp
    spec:
      containers:
      # sample container generating custom metrics
      - name: prometheus-dummy-exporter
        image: us-docker.pkg.dev/google-samples/containers/gke/prometheus-dummy-exporter:v0.2.0
        command: ["./prometheus-dummy-exporter"]
        args:
        - --metric-name=custom_prometheus
        - --metric-value=40
        - --port=8080

באמצעות המשאב PodMonitoring, השירות המנוהל של Google Cloud ל-Prometheus מייצא את מדדי Prometheus אל Cloud Monitoring:

apiVersion: monitoring.googleapis.com/v1
kind: PodMonitoring
metadata:
  name: "custom-metrics-exporter"
spec:
  selector:
    matchLabels:
      run: custom-metrics-gmp
  endpoints:
  - port: 8080
    path: /metrics
    interval: 15s

החל מגרסה 1.27 של GKE Standard או מגרסה 1.25 של GKE Autopilot, השירות המנוהל של Google Cloud ל-Prometheus מופעל. כדי להפעיל את השירות המנוהל של Google Cloud ל-Prometheus באשכולות בגרסאות קודמות, אפשר לעיין במאמר בנושא הפעלת איסוף מנוהל.

פורסים את האפליקציה באשכול:

Pub/Sub

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

Workload Identity

  1. מפעילים את Pub/Sub API בפרויקט:

    gcloud services enable cloudresourcemanager.googleapis.com pubsub.googleapis.com
    
  2. יצירת נושא ומינוי ב-Pub/Sub:

    gcloud pubsub topics create echo
    gcloud pubsub subscriptions create echo-read --topic=echo
    
  3. פורסים את האפליקציה באשכול:

    kubectl apply -f deployment/pubsub-with-workload-identity.yaml
    
  4. האפליקציה הזו מגדירה חשבון שירות של Kubernetes‏ pubsub-sa. מקצים לו את התפקיד מנוי ב-Pub/Sub כדי שהאפליקציה תוכל לפרסם הודעות בנושא ב-Pub/Sub.

    gcloud projects add-iam-policy-binding projects/$PROJECT_ID \
      --role=roles/pubsub.subscriber \
      --member=principal://iam.googleapis.com/projects/$PROJECT_NUMBER/locations/global/workloadIdentityPools/$PROJECT_ID.svc.id.goog/subject/ns/default/sa/pubsub-sa
    

    הפקודה הקודמת משתמשת במזהה חשבון משתמש, שמאפשר ל-IAM להתייחס ישירות לחשבון שירות של Kubernetes.

    שיטה מומלצת:

    משתמשים במזהי Principal, אבל כדאי לקחת בחשבון את המגבלה שמופיעה בתיאור של שיטה חלופית.

אימות מדור קודם

  1. מפעילים את Pub/Sub API בפרויקט:

    gcloud services enable cloudresourcemanager.googleapis.com pubsub.googleapis.com
    
  2. יצירת נושא ומינוי ב-Pub/Sub:

    gcloud pubsub topics create echo
    gcloud pubsub subscriptions create echo-read --topic=echo
    
  3. יוצרים חשבון שירות עם גישה ל-Pub/Sub:

    gcloud iam service-accounts create autoscaling-pubsub-sa
    gcloud projects add-iam-policy-binding $PROJECT_ID \
      --member "serviceAccount:autoscaling-pubsub-sa@$PROJECT_ID.iam.gserviceaccount.com" \
      --role "roles/pubsub.subscriber"
    
  4. מורידים את קובץ המפתח של חשבון השירות:

    gcloud iam service-accounts keys create key.json \
      --iam-account autoscaling-pubsub-sa@$PROJECT_ID.iam.gserviceaccount.com
    
  5. מייבאים את המפתח של חשבון השירות לאשכול כסוד:

    kubectl create secret generic pubsub-key --from-file=key.json=./key.json
    
  6. פורסים את האפליקציה באשכול:

    kubectl apply -f deployment/pubsub-with-secret.yaml
    

מדד מותאם אישית

kubectl apply -f custom-metrics-gmp.yaml

אחרי שממתינים רגע עד שהאפליקציה נפרסת, כל ה-Pods מגיעים למצב Ready:

Pub/Sub

kubectl get pods

פלט:

NAME                     READY   STATUS    RESTARTS   AGE
pubsub-8cd995d7c-bdhqz   1/1     Running   0          58s

מדד מותאם אישית

kubectl get pods

פלט:

NAME                                  READY   STATUS    RESTARTS   AGE
custom-metrics-gmp-865dffdff9-x2cg9   1/1     Running   0          49s

הצגת מדדים ב-Cloud Monitoring

במהלך הפעלת האפליקציה, המדדים נכתבים ב-Cloud Monitoring.

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

  1. במסוף Google Cloud , עוברים לדף  Metrics explorer:

    כניסה אל Metrics Explorer

    אם משתמשים בסרגל החיפוש כדי למצוא את הדף הזה, בוחרים בתוצאה שכותרת המשנה שלה היא Monitoring.

  2. ברכיב Metric, מרחיבים את התפריט Select a metric ובוחרים סוג משאב וסוג מדד. לדוגמה, כדי ליצור תרשים של ניצול המעבד של מכונה וירטואלית, מבצעים את הפעולות הבאות:
    1. (אופציונלי) כדי לצמצם את האפשרויות בתפריט, מזינים חלק משם המדד בסרגל הסינון. בדוגמה הזו, מזינים utilization.
    2. בתפריט Active resources בוחרים באפשרות VM instance.
    3. בתפריט Active metric categories בוחרים באפשרות Instance.
    4. בתפריט Active metrics בוחרים באפשרות CPU utilization ואז לוחצים על Apply.
  3. כדי לסנן את סדרות הזמנים שמוצגות, משתמשים ברכיב Filter.

  4. כדי לשלב סדרות עיתיות, משתמשים בתפריטים ברכיב Aggregation. לדוגמה, כדי להציג את ניצול המעבד של המכונות הווירטואליות לפי האזור שלהן, מגדירים את התפריט הראשון לממוצע ואת התפריט השני לאזור.

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

סוג המשאב והמדדים הם:

Pub/Sub

Metrics Explorer

סוג המשאב: pubsub_subscription

מדד: pubsub.googleapis.com/subscription/num_undelivered_messages

מדד מותאם אישית

Metrics Explorer

סוג המשאב: prometheus_target

מדד: prometheus.googleapis.com/custom_prometheus/gauge

יכול להיות שעדיין לא תראו הרבה פעילות ב-Metrics Explorer של Cloud Monitoring, בהתאם למדד. אל תתפלאו אם המדד לא מתעדכן.

יצירת אובייקט HorizontalPodAutoscaler

כשרואים את המדד ב-Cloud Monitoring, אפשר לפרוס HorizontalPodAutoscaler כדי לשנות את הגודל של הפריסה על סמך המדד.

Pub/Sub

apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
  name: pubsub
spec:
  minReplicas: 1
  maxReplicas: 5
  metrics:
  - external:
      metric:
       name: pubsub.googleapis.com|subscription|num_undelivered_messages
       selector:
         matchLabels:
           resource.labels.subscription_id: echo-read
      target:
        type: AverageValue
        averageValue: 2
    type: External
  scaleTargetRef:
    apiVersion: apps/v1
    kind: Deployment
    name: pubsub

מדד מותאם אישית

apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
  name: custom-metrics-gmp-hpa
  namespace: default
spec:
  scaleTargetRef:
    apiVersion: apps/v1
    kind: Deployment
    name: custom-metrics-gmp
  minReplicas: 1
  maxReplicas: 5
  metrics:
  - type: Pods
    pods:
      metric:
        name: prometheus.googleapis.com|custom_prometheus|gauge
      target:
        type: AverageValue
        averageValue: 20

פורסים את HorizontalPodAutoscaler באשכול:

Pub/Sub

kubectl apply -f deployment/pubsub-hpa.yaml

מדד מותאם אישית

kubectl apply -f custom-metrics-gmp-hpa.yaml

יצירת עומס

יכול להיות שתצטרכו ליצור עומס כדי לראות את ההתאמה האוטומטית לעומס בחלק מהמדדים:

Pub/Sub

מפרסמים 200 הודעות בנושא Pub/Sub:

for i in {1..200}; do gcloud pubsub topics publish echo --message="Autoscaling #${i}"; done

מדד מותאם אישית

לא רלוונטי: הקוד שמשמש בייצוא הנתונים לדוגמה הזה מייצא ערך קבוע של 40 למדד המותאם אישית. ה-HorizontalPodAutoscaler מוגדר עם ערך יעד של 20, ולכן הוא מנסה להגדיל את הפריסה באופן אוטומטי.

יכול להיות שתצטרכו לחכות כמה דקות עד שה-HorizontalPodAutoscaler יגיב לשינויים במדד.

מעקב אחרי הגדלת קנה המידה של HorizontalPodAutoscaler

כדי לבדוק את המספר הנוכחי של העותקים של הפריסה, מריצים את הפקודה:

kubectl get deployments

אחרי שנותנים למדד זמן להתפשט, הפריסה יוצרת חמישה פודים לטיפול בבקשות שלא טופלו.

אפשר גם לבדוק את המצב ואת הפעילות האחרונה של HorizontalPodAutoscaler על ידי הרצת הפקודה:

kubectl describe hpa

הסרת המשאבים

כדי לא לצבור חיובים לחשבון Google Cloud על המשאבים שבהם השתמשתם במדריך הזה, אתם יכולים למחוק את הפרויקט שמכיל את המשאבים או להשאיר את הפרויקט ולמחוק את המשאבים בנפרד.

Pub/Sub

  1. מנקים את המינוי והנושא ב-Pub/Sub:

    gcloud pubsub subscriptions delete echo-read
    gcloud pubsub topics delete echo
    
  2. מוחקים את אשכול GKE:

    gcloud container clusters delete metrics-autoscaling
    

מדד מותאם אישית

מוחקים את אשכול GKE:

 gcloud container clusters delete metrics-autoscaling

המאמרים הבאים