במדריך הזה נסביר איך להקטין את עומסי העבודה ב-GKE עד לאפס Pods באמצעות KEDA. הגדלת הפריסות לאפס Pods חוסכת משאבים בתקופות של חוסר פעילות (כמו סופי שבוע ושעות לא פעילות), או עבור עומסי עבודה לסירוגין כמו משימות תקופתיות.
מטרות
במדריך הזה נסביר על תרחישי השימוש הבאים:
- התאמת עומס העבודה ב-Pub/Sub לאפס: התאמת מספר ה-Pods באופן יחסי למספר ההודעות שנמצאות בתור בנושא Pub/Sub. כשהתור ריק, עומס העבודה מצטמצם אוטומטית לאפס פודים.
- התאמת עומס העבודה של מודל LLM לאפס. פריסת שרתי מודלים של LLM בצמתים עם GPU. כשהשירות לא פעיל, עומס העבודה מצטמצם אוטומטית לאפס Pods.
עלויות
במסמך הזה משתמשים ברכיבים הבאים של Google Cloud, והשימוש בהם כרוך בתשלום:
- GKE
- GPU resources used by GKE
- Pub/Sub
כדי להעריך את ההוצאות בהתאם לתחזית השימוש שלכם, אתם יכולים להיעזר במחשבון העלויות.
כשמסיימים את המשימות שמתוארות במסמך הזה אפשר למחוק את המשאבים שיצרתם כדי להימנע מחיובים נוספים. מידע נוסף זמין בקטע הסרת המשאבים.
לפני שמתחילים
במדריך הזה משתמשים ב-Cloud Shell כדי להריץ פקודות. Cloud Shell היא סביבת מעטפת לניהול משאבים שמתארחים ב- Google Cloud. הוא מגיע עם כלי שורת הפקודה Google Cloud CLI, kubectl, Helm ו-Terraform. אם אתם לא משתמשים ב-Cloud Shell, אתם צריכים להתקין את Google Cloud CLI ואת Helm.
-
כדי להריץ את הפקודות שבדף הזה, צריך להגדיר את ה-CLI של gcloud באחת מסביבות הפיתוח הבאות:
Cloud Shell
כדי להשתמש בטרמינל אונליין שכבר מוגדר בו ה-CLI של gcloud, צריך להפעיל את Cloud Shell:
בחלק התחתון של הדף הזה מתחיל סשן של Cloud Shell ומופיעה הודעה של שורת הפקודה. הסשן יופעל תוך כמה שניות.
מעטפת מקומית
כדי להשתמש בסביבת פיתוח מקומית:
- נכנסים לחשבון Google Cloud . אם אתם משתמשים חדשים ב- Google Cloud, צרו חשבון כדי שתוכלו להעריך את הביצועים של המוצרים שלנו בתרחישים מהעולם האמיתי. לקוחות חדשים מקבלים בחינם גם קרדיט בשווי 300$ להרצה, לבדיקה ולפריסה של עומסי העבודה.
-
In the Google Cloud console, on the project selector page, select or create a Google Cloud project.
Roles required to select or create a project
- Select a project: Selecting a project doesn't require a specific IAM role—you can select any project that you've been granted a role on.
-
Create a project: To create a project, you need the Project Creator role
(
roles/resourcemanager.projectCreator), which contains theresourcemanager.projects.createpermission. Learn how to grant roles.
-
Verify that billing is enabled for your Google Cloud project.
Enable the Resource Manager, Compute Engine, GKE, Pub/Sub APIs.
Roles required to enable APIs
To enable APIs, you need the Service Usage Admin IAM role (
roles/serviceusage.serviceUsageAdmin), which contains theserviceusage.services.enablepermission. Learn how to grant roles.-
In the Google Cloud console, on the project selector page, select or create a Google Cloud project.
Roles required to select or create a project
- Select a project: Selecting a project doesn't require a specific IAM role—you can select any project that you've been granted a role on.
-
Create a project: To create a project, you need the Project Creator role
(
roles/resourcemanager.projectCreator), which contains theresourcemanager.projects.createpermission. Learn how to grant roles.
-
Verify that billing is enabled for your Google Cloud project.
Enable the Resource Manager, Compute Engine, GKE, Pub/Sub APIs.
Roles required to enable APIs
To enable APIs, you need the Service Usage Admin IAM role (
roles/serviceusage.serviceUsageAdmin), which contains theserviceusage.services.enablepermission. Learn how to grant roles.
הגדרת הסביבה
.כדי להגדיר את הסביבה באמצעות Cloud Shell:
הגדרת משתני סביבה:
export PROJECT_ID=PROJECT_ID export PROJECT_NUMBER=$(gcloud projects describe $PROJECT_ID --format 'get(projectNumber)') export LOCATION=LOCATIONמחליפים את
PROJECT_IDבמזהה הפרויקט ואתLOCATIONבאזורים או בתחומים שבהם צריך ליצור את אשכול GKE. Google Cloudאם לא תפעלו לפי כל ההוראות במדריך במהלך סשן אחד, או אם משתני הסביבה לא מוגדרים מסיבה כלשהי, הקפידו להריץ את הפקודה הזו שוב כדי להגדיר את המשתנים מחדש.
יוצרים אשכול GKE רגיל עם התאמה אוטומטית לעומס ועם איחוד זהויות של עומסי עבודה ל-GKE:
gcloud container clusters create scale-to-zero \ --project=${PROJECT_ID} --location=${LOCATION} \ --machine-type=n1-standard-2 \ --enable-autoscaling --min-nodes=1 --max-nodes=5 \ --workload-pool=${PROJECT_ID}.svc.id.goog
התקנת KEDA
KEDA הוא רכיב שמשלים את התכונה Horizontal Pod Autoscaler ב-Kubernetes. באמצעות KEDA, אפשר לשנות את קנה המידה של פריסה לאפס Pods ומאפס Pods ל-Pod אחד. פריסה היא אובייקט Kubernetes API שמאפשר להפעיל כמה רפליקות של Pods שמפוזרות בין הצמתים באשכול. האלגוריתם הרגיל של Horizontal Pod Autoscaler מופעל אחרי ש-GKE יוצר לפחות Pod אחד.
אחרי ש-GKE משנה את קנה המידה של ה-Deployment לאפס Pods, לא ניתן להסתמך על מדדי Pods כמו ניצול CPU לצורך התאמה אוטומטית לעומס, כי לא פועלים Pods. כתוצאה מכך, KEDA מאפשרת אחזור מדדים שמקורם מחוץ לאשכול באמצעות הטמעה של External Metrics API של Kubernetes. אתם יכולים להשתמש ב-API הזה כדי להגדיר שינוי אוטומטי של קנה מידה על סמך מדדים כמו מספר ההודעות שלא נשלחו במינוי Pub/Sub. במסמכי העזרה של KEDA מופיעה רשימה של כל מקורות המדדים הנתמכים.
מתקינים את KEDA באשכול באמצעות Helm או באמצעות kubectl.
Helm
מריצים את הפקודות הבאות כדי להוסיף את מאגר KEDA Helm, להתקין את תרשים KEDA Helm ולהעניק לחשבון השירות של KEDA גישת קריאה ל-Cloud Monitoring:
helm repo add kedacore https://kedacore.github.io/charts
helm repo update
helm install keda kedacore/keda --create-namespace --namespace keda
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/keda/sa/keda-operator
שימו לב שהפקודה הזו מגדירה גם כללי הרשאה שמחייבים הגדרה של איחוד זהויות של עומסי עבודה ל-GKE באשכול.
kubectl
מריצים את הפקודות הבאות כדי להתקין את KEDA באמצעות kubectl apply וכדי לתת לחשבון השירות של KEDA גישת קריאה ל-Cloud Monitoring:
kubectl apply --server-side -f https://github.com/kedacore/keda/releases/download/v2.15.1/keda-2.15.1.yaml
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/keda/sa/keda-operator
שימו לב שהפקודה הזו מגדירה גם כללי הרשאה שמחייבים הגדרה של איחוד זהויות של עומסי עבודה ל-GKE באשכול.
מוודאים שכל משאבי KEDA מופיעים במרחב השמות keda:
kubectl get all -n keda
מידע נוסף על העיצוב והמשאבים של KEDA זמין במסמכי התיעוד של KEDA.
התאמת העומס של Pub/Sub לאפס
בקטע הזה מתואר עומס עבודה שמעבד הודעות ממינוי ל-Pub/Sub, מטפל בכל הודעה ומאשר את השלמתה. עומס העבודה משתנה באופן דינמי: ככל שמספר ההודעות שלא אושרו גדל, התכונה 'התאמה אוטומטית לעומס' יוצרת עוד יחידות Pod כדי להבטיח עיבוד בזמן.
הגדרה של קנה מידה לאפס מבטיחה שלא יופעלו אף Pods אם לא התקבלו הודעות במשך זמן מה. כך חוסכים במשאבים כי אף תרמיל לא נשאר במצב סרק למשך תקופות ארוכות.
פריסת עומס עבודה של Pub/Sub
פריסת עומס עבודה לדוגמה שמבצע עיבוד של הודעות בתור בנושא Pub/Sub. כדי לדמות עומס עבודה מציאותי, תוכנית הדוגמה הזו ממתינה שלוש שניות לפני שהיא מאשרת קבלת הודעה. עומס העבודה מוגדר להפעלה בחשבון השירות keda-pubsub-sa.
מריצים את הפקודות הבאות כדי ליצור את הנושא והמינוי ב-Pub/Sub, להגדיר את ההרשאה שלהם וליצור את הפריסה שמתחילה את עומס העבודה במרחב השמות keda-pubsub.
gcloud pubsub topics create keda-echo
gcloud pubsub subscriptions create keda-echo-read --topic=keda-echo
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/keda-pubsub/sa/keda-pubsub-sa
kubectl apply -f https://raw.githubusercontent.com/GoogleCloudPlatform/kubernetes-engine-samples/refs/heads/main/cost-optimization/gke-keda/cloud-pubsub/deployment/keda-pubsub-with-workload-identity.yaml
הגדרת צמצום הפעולה לאפס
כדי להגדיר את עומס העבודה של Pub/Sub כך שניתן יהיה להקטין אותו לאפס, צריך להשתמש ב-KEDA כדי להגדיר משאב ScaledObject ולציין איך הפריסה צריכה להתרחב.
לאחר מכן, KEDA ייצור וינהל באופן אוטומטי את אובייקט HorizontalPodAutoscaler (HPA) הבסיסי.
יוצרים את המשאב
ScaledObjectכדי לתאר את ההתנהגות הצפויה של התאמה לעומס:curl https://raw.githubusercontent.com/GoogleCloudPlatform/kubernetes-engine-samples/refs/heads/main/cost-optimization/gke-keda/cloud-pubsub/deployment/keda-pubsub-scaledobject.yaml | envsubst | kubectl apply -f -ייווצר האובייקט הבא:
apiVersion: keda.sh/v1alpha1 kind: ScaledObject metadata: name: keda-pubsub namespace: keda-pubsub spec: maxReplicaCount: 5 scaleTargetRef: name: keda-pubsub triggers: - type: gcp-pubsub authenticationRef: name: keda-auth metadata: subscriptionName: "projects/${PROJECT_ID}/subscriptions/keda-echo-read"בודקים את אובייקט
HorizontalPodAutoscaler(HPA) שנוצר על ידי KEDA על סמך אובייקטScaledObject:kubectl get hpa keda-hpa-keda-pubsub -n keda-pubsub -o yamlמידע נוסף על מידרוג אוטומטי זמין במסמכי Kubernetes.
מחכים עד ש-KEDA מאשר שהמינוי ל-Pub/Sub ריק, ומקטין את מספר הרפליקות של הפריסה לאפס.
בודקים את המידרוג האוטומטי של עומס העבודה:
kubectl describe hpa keda-hpa-keda-pubsub -n keda-pubsubשימו לב שבתשובה לפקודה, התנאי
ScalingActiveהוא false. ההודעה שמשויכת ל-Horizontal Pod Autoscaler מציינת שהוא מזהה ש-KEDA שינה את קנה המידה של הפריסה לאפס, ובשלב הזה הוא מפסיק לפעול עד שהפריסה תגדל בחזרה ל-Pod אחד.Name: keda-hpa-keda-pubsub Namespace: keda-pubsub Metrics: ( current / target ) "s0-gcp-ps-projects-[...]]" (target average value): 0 / 10 Min replicas: 1 Max replicas: 5 Deployment pods: 5 current / 5 desired Conditions: Type Status Reason Message ---- ------ ------ ------- AbleToScale True ScaleDownStabilized recent recommendations were higher than current one [...] ScalingActive False ScalingDisabled scaling is disabled since the replica count of the target is zero ScalingLimited True TooManyReplicas the desired replica count is more than the maximum replica count
הפעלת ההרחבה
כדי לעודד את הפריסה להתרחב:
הוספת הודעות לתור בנושא Pub/Sub:
for num in {1..20} do gcloud pubsub topics publish keda-echo --project=${PROJECT_ID} --message="Test" doneמוודאים שהפריסה מתרחבת:
kubectl get deployments -n keda-pubsubבפלט, אפשר לראות שבעמודה 'מוכן' מופיעה רפליקה אחת:
NAME READY UP-TO-DATE AVAILABLE AGE keda-pubsub 1/1 1 1 2d
KEDA מגדיל את הפריסה אחרי שהוא מזהה שהתור לא ריק.
הקטנת עומס העבודה של מודל שפה גדול (LLM) לאפס
בקטע הזה מתואר עומס עבודה של מודל שפה גדול (LLM) שפורס שרת Ollama עם GPU מצורף. Ollama מאפשרת להריץ מודלים פופולריים של LLM כמו Gemma ו-Llama 2, והיא חושפת את התכונות שלה בעיקר דרך HTTP.
התקנת התוסף KEDA-HTTP
הקטנת קנה מידה של שירות HTTP לאפס פודים בתקופות של חוסר פעילות גורמת לכשלים בבקשות, כי אין בק-אנד לטיפול בבקשות.
בקטע הזה נסביר איך לפתור את הבעיה באמצעות התוסף KEDA-HTTP. KEDA-HTTP מפעיל שרת proxy של HTTP שמקבל בקשות משתמשים ומעביר אותן לשירותים שהוגדרו לצמצום הפעולה לאפס. אם לשירות אין אף Pod, שרת ה-proxy מפעיל את השירות כדי להגדיל את הקיבולת שלו, ומאחסן את הבקשה במאגר עד שהקיבולת של השירות תגדל לפחות ל-Pod אחד.
מתקינים את התוסף KEDA-HTTP באמצעות Helm. מידע נוסף מופיע במאמרי העזרה בנושא KEDA-HTTP.
helm repo add ollama-helm https://otwld.github.io/ollama-helm/
helm repo update
# Set the proxy timeout to 120s, giving Ollama time to start.
helm install http-add-on kedacore/keda-add-ons-http \
--create-namespace --namespace keda \
--set interceptor.responseHeaderTimeout=120s
פריסת עומס עבודה של Ollama LLM
כדי לפרוס עומס עבודה של LLM של Ollama:
יוצרים מאגר צמתים שמכיל
g2-standard-4צמתים עם מעבדי GPU מצורפים, ומגדירים את שינוי הגודל האוטומטי של האשכול כך שיספק בין אפס לשני צמתים:gcloud container node-pools create gpu --machine-type=g2-standard-4 \ --location=${LOCATION} --cluster=scale-to-zero \ --min-nodes 0 --max-nodes 2 --num-nodes=1 --enable-autoscalingמוסיפים את מאגר התרשימים הרשמי של Ollama Helm ומעדכנים את המאגר של לקוח Helm המקומי:
helm repo add ollama-helm https://otwld.github.io/ollama-helm/ helm repo updateפורסים את שרת Ollama באמצעות תרשים Helm:
helm install ollama ollama-helm/ollama --create-namespace --namespace ollama \ -f https://raw.githubusercontent.com/GoogleCloudPlatform/kubernetes-engine-samples/refs/heads/main/cost-optimization/gke-keda/ollama/helm-values-ollama.yamlההגדרה
helm-values-ollama.yamlמציינת את מודלי ה-LLM לטעינה, את דרישות ה-GPU ואת יציאת ה-TCP של שרת Ollama.
הגדרת צמצום הפעולה לאפס
כדי להגדיר את עומס העבודה של Ollama כך שניתן יהיה להקטין אותו לאפס, KEDA-HTTP משתמש בHTTPScaledObject.
יוצרים את המשאב
HTTPScaledObjectכדי לתאר את ההתנהגות הצפויה של התאמה לעומס:kubectl apply -f https://raw.githubusercontent.com/GoogleCloudPlatform/kubernetes-engine-samples/refs/heads/main/cost-optimization/gke-keda/ollama/keda-ollama-httpscaledobject.yamlהפעולה הזו יוצרת את האובייקט
HTTPScaledObjectשמגדיר את השדות הבאים:-
scaleTargetRef: מציין את השירות שאליו KEDA-HTTP צריך להעביר את הבקשות. בדוגמה הזו, כל הבקשות עם המארחollama.ollamaמופנות לשרת Ollama. -
scaledownPeriod: מציין (בשניות) את מהירות ההקטנה כשלא מתקבלות בקשות. -
replicas: מציין את מספר ה-Pods המינימלי והמקסימלי שצריך לשמור עבור פריסת Ollama. -
scalingMetric: מציין את המדדים שמשמשים להגדרה אוטומטית של קנה מידה, כמו קצב הבקשות בדוגמה הזו. אפשרויות נוספות למדדים מפורטות במאמרי העזרה בנושא KEDA-HTTP.
kind: HTTPScaledObject apiVersion: http.keda.sh/v1alpha1 metadata: namespace: ollama name: ollama spec: hosts: - ollama.ollama scaleTargetRef: name: ollama kind: Deployment apiVersion: apps/v1 service: ollama port: 11434 replicas: min: 0 max: 2 scaledownPeriod: 3600 scalingMetric: requestRate: targetValue: 20-
מריצים את הפקודה הבאה כדי לוודא ש-KEDA-HTTP עיבד בהצלחה את
HTTPScaledObjectשנוצר בשלב הקודם:kubectl get hpa,scaledobject -n ollamaהפלט מציג את המשאבים
HorizontalPodAutoscaler(שנוצר על ידי KEDA) ו-ScaledObject(שנוצר על ידי KEDA-HTTP):NAME REFERENCE TARGETS MINPODS MAXPODS REPLICAS AGE horizontalpodautoscaler.autoscaling/keda-hpa-ollama Deployment/ollama 0/100 (avg) 1 2 1 2d NAME SCALETARGETKIND SCALETARGETNAME MIN MAX TRIGGERS AUTHENTICATION READY ACTIVE FALLBACK PAUSED AGE scaledobject.keda.sh/ollama apps/v1.Deployment ollama 0 2 external-push True False False Unknown 2dמוודאים שהפריסה מצטמצמת לאפס Pods.
מחכים את פרק הזמן שמוגדר בשדה
scaledownPeriodומריצים את הפקודה:kubectl get deployments -n ollamaבפלט אפשר לראות ש-KEDA הקטין את הפריסה של Ollama, ושלא פועלים פודים:
NAME READY UP-TO-DATE AVAILABLE AGE ollama 0/0 0 0 2d
הפעלת ההרחבה
כדי לעודד את הפריסה להתרחב, קוראים לשירות Ollama באמצעות ה-proxy שהוגדר על ידי התוסף KEDA-HTTP. כתוצאה מכך, הערך של מדד קצב הבקשות עולה, ומופעלת יצירה של פוד ראשון.
משתמשים ביכולות העברת הפורטים של kubectl כדי לגשת לשרת ה-proxy, כי ה-proxy לא חשוף חיצונית.
kubectl port-forward svc/keda-add-ons-http-interceptor-proxy -n keda 8080:8080 &
# Set the 'Host' HTTP header so that the proxy routes requests to the Ollama server.
curl -H "Host: ollama.ollama" \
http://localhost:8080/api/generate \
-d '{ "model": "gemma:7b", "prompt": "Hello!" }'
הפקודה curl שולחת את ההנחיה 'שלום!' למודל Gemma. בודקים את טוקני התשובה שמוחזרים בתגובה. למפרט של ה-API, ראו מדריך Ollama.
הסרת המשאבים
כדי להימנע מחיובים בחשבון Google Cloud בגלל השימוש במשאבים שנעשה במסגרת המדריך הזה, אפשר למחוק את הפרויקט שמכיל את המשאבים, או להשאיר את הפרויקט ולמחוק את המשאבים בנפרד.
מנקים את המינוי והנושא ב-Pub/Sub:
gcloud pubsub subscriptions delete keda-echo-read gcloud pubsub topics delete keda-echoמחיקת אשכול GKE:
gcloud container clusters delete scale-to-zero --location=${LOCATION}