במאמר הזה מתואר איך להגדיר את שער ההסקה (Inference Gateway) של Google Kubernetes Engine (GKE) בכמה אשכולות כדי לבצע איזון עומסים חכם של עומסי העבודה של הסקת מסקנות מ-AI/ML בכמה אשכולות GKE, שיכולים להיות באזורים שונים. ההגדרה הזו משתמשת ב-Gateway API, ב-Multi Cluster Ingress ובמשאבים מותאמים אישית כמו InferencePool ו-InferenceObjective כדי לשפר את יכולת ההתאמה לגודל, להבטיח זמינות גבוהה ולייעל את ניצול המשאבים בפריסות של מודלים.
כדי להבין את המסמך הזה, צריך להכיר את המושגים הבאים:
- תזמור של AI/ML ב-GKE.
- טרמינולוגיה של AI גנרטיבי.
- מושגים של רשתות GKE, כולל:
- איזון עומסים ב-Google Cloud, במיוחד איך מאזני עומסים פועלים עם GKE.
המסמך הזה מיועד לאנשים עם התפקידים הבאים:
- מהנדסי למידת מכונה (ML), מנהלי פלטפורמה ומפעילים, או מומחי נתונים ו-AI שרוצים להשתמש ביכולות של GKE לניהול קונטיינרים כדי להפעיל עומסי עבודה של AI/ML.
- אדריכלי ענן או מומחי רשתות שיוצרים אינטראקציה עם רשתות GKE.
מידע נוסף על תפקידים נפוצים ומשימות לדוגמה שמוזכרים בGoogle Cloud תוכן זמין במאמר תפקידים נפוצים של משתמשים ומשימות ב-GKE Enterprise.
לפני שמתחילים
לפני שמתחילים, חשוב לוודא שביצעתם את הפעולות הבאות:
- מפעילים את ממשק Google Kubernetes Engine API. הפעלת Google Kubernetes Engine API
- כדי להשתמש ב-CLI של Google Cloud למשימה הזו, צריך להתקין ואז לאתחל את ה-CLI של gcloud. אם התקנתם בעבר את ה-CLI של gcloud, מריצים את הפקודה
gcloud components updateכדי לקבל את הגרסה העדכנית. יכול להיות שגרסאות קודמות של ה-CLI של gcloud לא יתמכו בהרצת הפקודות שמופיעות במסמך הזה.
מפעילים את Compute Engine API, Kubernetes Engine API, הגנה מוגברת על המודל ו-Network Services API.
עוברים אל הפעלת גישה לממשקי API ופועלים לפי ההוראות.
מפעילים את Autoscaling API.
עוברים אל Autoscaling API ופועלים לפי ההוראות.
מפעילים את GKE Hub API.
עוברים אל GKE Hub API ופועלים לפי ההוראות.
אפשר גם להשתמש ב-Google Cloud CLI:
gcloud services enable gkehub.googleapis.com --project=PROJECT_IDדרישות מוקדמות ל-Hugging Face:
- אם עדיין אין לכם חשבון, יוצרים חשבון ב-Hugging Face.
- שולחים בקשה ומקבלים אישור לגישה למודל Qwen3-32B ב-Hugging Face.
- חותמים על הסכם הרישיון בדף של המודל ב-Hugging Face.
- יוצרים טוקן גישה ל-Hugging Face עם הרשאות
Readלפחות.
דרישות
- מוודאים שיש בפרויקט מכסה מספקת לשימוש במעבדי GPU מדגם H100. מידע נוסף זמין במאמרים בנושא תכנון מכסת GPU ומכסות הקצאה.
- משתמשים בגרסה 1.34.1-gke.1127000 של GKE ואילך.
- משתמשים ב-CLI של gcloud בגרסה 480.0.0 ואילך.
- לחשבונות השירות של הצמתים צריכות להיות הרשאות לכתיבת מדדים ל-Autoscaling API.
- אתם צריכים את תפקידי ה-IAM הבאים בפרויקט:
roles/container.adminו-roles/iam.serviceAccountAdmin. - כל האשכולות שאתם רושמים ל-Fleet, כולל אשכול ההגדרות, צריכים להיות באותה רשת VPC. שערי Multi-cluster לא תומכים באיזון עומסים בין אשכולות ברשתות VPC שונות.
מגבלות על NEG ועל מספר יציאות
כשפורסים משאבי InferencePool מרובי-יציאות בהגדרה מרובת-אשכולות, כדאי לקחת בחשבון את Google Cloud המגבלה של NEG של שירות קצה עורפי. כל יציאה בכל אזור יוצרת NEG ייעודי. לדוגמה, באשכול אזורי עם שלושה אזורים ו-InferencePool שהוגדר עם שמונה יציאות, נעשה שימוש ב-24 NEGs. מכיוון ששירות Backend מוגבל ל-50 קבוצות NEG, אפשר לצבור את InferencePool הספציפי הזה רק מ-2 אשכולות לכל היותר לפני שמגיעים למגבלה.
הגדרת שער הסקה מרובה אשכולות
כדי להגדיר את שער ההסקה של GKE מרובה-אשכולות, מבצעים את השלבים הבאים:
יצירת אשכולות ומאגרי צמתים
כדי לארח את עומסי העבודה של מסקנות AI/ML ולאפשר איזון עומסים בין אזורים, צריך ליצור שני אשכולות GKE באזורים שונים, שלכל אחד מהם יש מאגר צמתים של GPU מסוג H100.
יוצרים את האשכול הראשון:
gcloud container clusters create CLUSTER_1_NAME \ --region LOCATION \ --project=PROJECT_ID \ --gateway-api=standard \ --release-channel "rapid" \ --cluster-version=GKE_VERSION \ --machine-type="MACHINE_TYPE" \ --disk-type="DISK_TYPE" \ --enable-managed-prometheus --monitoring=SYSTEM,DCGM \ --hpa-profile=performance \ --async # Allows the command to return immediatelyמחליפים את מה שכתוב בשדות הבאים:
-
CLUSTER_1_NAME: השם של האשכול הראשון, למשלgke-west. -
LOCATION: האזור של האשכול הראשון, למשלeurope-west3. PROJECT_ID: מזהה הפרויקט.-
GKE_VERSION: גרסת GKE לשימוש, לדוגמה1.34.1-gke.1127000. -
MACHINE_TYPE: סוג המכונה של צמתי האשכול, לדוגמהc2-standard-16. -
DISK_TYPE: סוג הדיסק של צמתי האשכול, לדוגמהpd-standard.
-
יוצרים מאגר צמתים מסוג H100 עבור האשכול הראשון:
gcloud container node-pools create NODE_POOL_NAME \ --accelerator "type=nvidia-h100-80gb,count=2,gpu-driver-version=latest" \ --project=PROJECT_ID \ --location=CLUSTER_1_ZONE \ --node-locations=CLUSTER_1_ZONE \ --cluster=CLUSTER_1_NAME \ --machine-type=NODE_POOL_MACHINE_TYPE \ --num-nodes=NUM_NODES \ --spot \ --async # Allows the command to return immediatelyמחליפים את מה שכתוב בשדות הבאים:
-
NODE_POOL_NAME: השם של מאגר הצמתים, למשלh100. PROJECT_ID: מזהה הפרויקט.-
CLUSTER_1_ZONE: האזור של האשכול הראשון, למשלeurope-west3-c. -
CLUSTER_1_NAME: השם של האשכול הראשון, למשלgke-west. -
NODE_POOL_MACHINE_TYPE: סוג המכונה של מאגר הצמתים, לדוגמהa3-highgpu-2g. -
NUM_NODES: מספר הצמתים במאגר הצמתים, לדוגמה3.
-
מקבלים את פרטי הכניסה:
gcloud container clusters get-credentials CLUSTER_1_NAME \ --location CLUSTER_1_ZONE \ --project=PROJECT_IDמחליפים את מה שכתוב בשדות הבאים:
PROJECT_ID: מזהה הפרויקט.-
CLUSTER_1_NAME: השם של האשכול הראשון, למשלgke-west. -
CLUSTER_1_ZONE: האזור של האשכול הראשון, למשלeurope-west3-c.
בקטע הראשון, יוצרים סוד לאסימון Hugging Face:
kubectl create secret generic hf-token \ --from-literal=token=HF_TOKENמחליפים את
HF_TOKENבטוקן הגישה שלכם ל-Hugging Face.יוצרים את האשכול השני באזור אחר מהאזור של האשכול הראשון:
gcloud container clusters create gke-east --region LOCATION \ --project=PROJECT_ID \ --gateway-api=standard \ --release-channel "rapid" \ --cluster-version=GKE_VERSION \ --machine-type="MACHINE_TYPE" \ --disk-type="DISK_TYPE" \ --enable-managed-prometheus \ --monitoring=SYSTEM,DCGM \ --hpa-profile=performance \ --async # Allows the command to return immediately while the cluster is created in the background.מחליפים את מה שכתוב בשדות הבאים:
-
LOCATION: האזור של האשכול השני. האזור הזה צריך להיות שונה מהאזור של האשכול הראשון. לדוגמה,us-east4. PROJECT_ID: מזהה הפרויקט.-
GKE_VERSION: גרסת GKE לשימוש, לדוגמה1.34.1-gke.1127000. -
MACHINE_TYPE: סוג המכונה של צמתי האשכול, לדוגמהc2-standard-16. -
DISK_TYPE: סוג הדיסק של צמתי האשכול, לדוגמהpd-standard.
-
יוצרים מאגר צמתים מסוג H100 עבור האשכול השני:
gcloud container node-pools create h100 \ --accelerator "type=nvidia-h100-80gb,count=2,gpu-driver-version=latest" \ --project=PROJECT_ID \ --location=CLUSTER_2_ZONE \ --node-locations=CLUSTER_2_ZONE \ --cluster=CLUSTER_2_NAME \ --machine-type=NODE_POOL_MACHINE_TYPE \ --num-nodes=NUM_NODES \ --spot \ --async # Allows the command to return immediatelyמחליפים את מה שכתוב בשדות הבאים:
PROJECT_ID: מזהה הפרויקט.-
CLUSTER_2_ZONE: האזור של האשכול השני, לדוגמהus-east4-a. -
CLUSTER_2_NAME: השם של האשכול השני, למשלgke-east. -
NODE_POOL_MACHINE_TYPE: סוג המכונה של מאגר הצמתים, לדוגמהa3-highgpu-2g. -
NUM_NODES: מספר הצמתים במאגר הצמתים, לדוגמה3.
עבור האשכול השני, מקבלים פרטי כניסה ויוצרים Secret לטוקן של Hugging Face:
gcloud container clusters get-credentials CLUSTER_2_NAME \ --location CLUSTER_2_ZONE \ --project=PROJECT_ID kubectl create secret generic hf-token --from-literal=token=HF_TOKENמחליפים את מה שכתוב בשדות הבאים:
-
CLUSTER_2_NAME: השם של האשכול השני, למשלgke-east. -
CLUSTER_2_ZONE: האזור של האשכול השני, לדוגמהus-east4-a. PROJECT_ID: מזהה הפרויקט.-
HF_TOKEN: טוקן הגישה שלכם ל-Hugging Face.
-
רישום אשכולות ב-Fleet
כדי להפעיל יכולות של כמה אשכולות, כמו GKE Inference Gateway מרובה אשכולות, צריך לרשום את האשכולות ל-Fleet.
כדי למנוע בעיות ב-mTLS במהלך הרישום, צריך להגדיר את שינוי ברירת המחדל של נקודת קצה ל-API.
gcloud config set api_endpoint_overrides/container https://container.googleapis.com/רושמים את שני האשכולות ב-Fleet של הפרויקט:
gcloud container fleet memberships register CLUSTER_1_NAME \ --gke-cluster CLUSTER_1_ZONE/CLUSTER_1_NAME \ --location=global \ --project=PROJECT_ID gcloud container fleet memberships register CLUSTER_2_NAME \ --gke-cluster CLUSTER_2_ZONE/CLUSTER_2_NAME \ --location=global \ --project=PROJECT_IDמחליפים את מה שכתוב בשדות הבאים:
-
CLUSTER_1_NAME: השם של האשכול הראשון, למשלgke-west. -
CLUSTER_1_ZONE: האזור של האשכול הראשון, למשלeurope-west3-c. PROJECT_ID: מזהה הפרויקט.-
CLUSTER_2_NAME: השם של האשכול השני, למשלgke-east. -
CLUSTER_2_ZONE: האזור של האשכול השני, לדוגמהus-east4-a.
-
כדי לאפשר לשער יחיד לנהל תנועה בכמה אשכולות, צריך להפעיל את התכונה multi-cluster Ingress (כניסה מרובת אשכולות) ולהגדיר אשכול תצורה:
gcloud container fleet ingress enable \ --config-membership=projects/PROJECT_ID/locations/global/memberships/CLUSTER_1_NAMEמחליפים את מה שכתוב בשדות הבאים:
PROJECT_ID: מזהה הפרויקט.-
CLUSTER_1_NAME: השם של האשכול הראשון, למשלgke-west.
יצירת רשתות משנה לשרתי proxy בלבד
בשביל שער פנימי, יוצרים תת-רשת של proxy בלבד בכל אזור. שערי Envoy פנימיים משתמשים בתת-רשתות הייעודיות האלה כדי לטפל בתעבורה בתוך רשת ה-VPC.
אזהרה: Google Cloud אפשר להשתמש רק בתת-רשת אחת של שרת proxy בלבד לכל אזור בכל רשת VPC. אם אזור היעד כבר מכיל תת-רשת של שרת proxy בלבד עם הגדרה של purpose=REGIONAL_MANAGED_PROXY, יצירת תת-הרשת GLOBAL_MANAGED_PROXY תיכשל. קודם צריך למחוק את רשת המשנה הקיימת של פרוקסי אזורי בלבד. מחיקה של רשת משנה אזורית מסוג proxy-only משפיעה על כל מאזני העומסים האזוריים שמבוססים על Envoy באותו אזור שמשתמשים בה, ולכן חשוב לתכנן את השינוי בהתאם.
יוצרים רשת משנה באזור של האשכול הראשון:
gcloud compute networks subnets create CLUSTER_1_REGION-subnet \ --purpose=GLOBAL_MANAGED_PROXY \ --role=ACTIVE \ --region=CLUSTER_1_REGION \ --network=default \ --range=10.0.0.0/23 \ --project=PROJECT_IDיוצרים תת-רשת באזור של האשכול השני:
gcloud compute networks subnets create CLUSTER_2_REGION-subnet \ --purpose=GLOBAL_MANAGED_PROXY \ --role=ACTIVE \ --region=CLUSTER_2_REGION \ --network=default \ --range=10.5.0.0/23 \ --project=PROJECT_IDמחליפים את מה שכתוב בשדות הבאים:
PROJECT_ID: מזהה הפרויקט.-
CLUSTER_1_REGION: האזור של האשכול הראשון, לדוגמהeurope-west3. -
CLUSTER_2_REGION: האזור של האשכול השני, לדוגמהus-east4.
התקנה של CustomResourceDefinitions הנדרשים
GKE Inference Gateway עם כמה אשכולות משתמש במשאבים בהתאמה אישית, כמו InferencePool ו-InferenceObjective. בקר ה-GKE Gateway API מנהל את InferencePool CustomResourceDefinition. עם זאת, צריך להתקין באופן ידני את InferenceObjective CustomResourceDefinition, שנמצא בשלב אלפא, באשכולות.
מגדירים משתני הקשר עבור האשכולות:
CLUSTER1_CONTEXT="gke_PROJECT_ID_CLUSTER_1_ZONE_CLUSTER_1_NAME" CLUSTER2_CONTEXT="gke_PROJECT_ID_CLUSTER_2_ZONE_CLUSTER_2_NAME"מחליפים את מה שכתוב בשדות הבאים:
PROJECT_ID: מזהה הפרויקט.-
CLUSTER_1_ZONE: האזור של האשכול הראשון, למשלeurope-west3-c. -
CLUSTER_1_NAME: השם של האשכול הראשון, לדוגמהgke-west. -
CLUSTER_2_ZONE: האזור של האשכול השני, לדוגמהus-east4-a. -
CLUSTER_2_NAME: השם של האשכול השני, למשלgke-east.
מתקינים את InferenceObjective CustomResourceDefinition בשני האשכולות:
kubectl apply -f https://raw.githubusercontent.com/kubernetes-sigs/gateway-api-inference-extension/v1.5.0/config/crd/bases/inference.networking.x-k8s.io_inferenceobjectives.yaml --context=$CLUSTER1_CONTEXT kubectl apply -f https://raw.githubusercontent.com/kubernetes-sigs/gateway-api-inference-extension/v1.5.0/config/crd/bases/inference.networking.x-k8s.io_inferenceobjectives.yaml --context=$CLUSTER2_CONTEXT
פריסת משאבים באשכולות היעד
כדי להפוך את עומסי העבודה של ההסקות של ה-AI/ML לזמינים בכל אשכול, צריך לפרוס את המשאבים הנדרשים, כמו שרתי המודלים ומשאבי InferenceObjective בהתאמה אישית.
הערה: בדוגמאות שבמאמר הזה נעשה שימוש ב-vLLM, אבל שער ההסקה מרובה האשכולות הוא בלתי תלוי בפלטפורמת שרת המודלים, והוא פועל גם עם שרתי מודלים אחרים, כמו SGLang. אם משתמשים בשרת מודלים אחר, צריך לשנות את ההגדרות הבאות:
- יציאת ההצגה. מגדירים את
InferencePoolיציאת היעד, את יציאתHealthCheckPolicyואת יציאת נקודת הקצהAutoscalingMetricליציאת ההגשה של שרת המודל. לדוגמה, SGLang פועל ביציאה30000כברירת מחדל במקום ביציאה8000. - שמות המדדים. שמות המדדים הם ספציפיים לכל שרת מודלים. לדוגמה, SGLang מדווח על השימוש במטמון KV כמדד
sglang:token_usageבמקום כמדדvllm:kv_cache_usage_perc. ממפים את המדד של שרת המודל לkv-cacheשם הייצוא במשאבAutoscalingMetric. כדי לחלץ מדדים בהתאמה אישית משרתי מודלים שאינם vLLM, צריך תמונה תואמת של Endpoint Picker (EPP). מומלץ להשתמש בגרסה הנתמכת האחרונה של התרשים. - פרסום מודלים מרובי-צמתים אם עותק של מודל משתרע על כמה צמתים (לדוגמה, כשמשתמשים ב-
LeaderWorkerSetAPI כדי להפעיל מודל גדול), רק ה-Pod הראשי (בדרגה 0) מפעיל את ה-API. מגדירים את הבוררInferencePoolmodelServers.matchLabelsכך שיתאים רק ל-Pods של מובילים – למשל, על ידי הוספת התוויתapps.kubernetes.io/pod-index: "0". אם הסלקטור תואם גם ל-Pods של העובדים, השער ינתב בקשות ל-Pods שלא יכולים לטפל בהן, והבקשות האלה ייכשלו עם קוד סטטוס404 Not Foundשל HTTP.
פורסים את שרתי המודלים בשני האשכולות:
kubectl apply -f https://raw.githubusercontent.com/kubernetes-sigs/gateway-api-inference-extension/v1.5.0/config/manifests/vllm/gpu-deployment.yaml --context=$CLUSTER1_CONTEXT kubectl apply -f https://raw.githubusercontent.com/kubernetes-sigs/gateway-api-inference-extension/v1.5.0/config/manifests/vllm/gpu-deployment.yaml --context=$CLUSTER2_CONTEXTפורסים את משאבי InferenceObjective בשני האשכולות. שומרים את קובץ המניפסט לדוגמה הבא בקובץ בשם
inference-objective.yaml:apiVersion: inference.networking.x-k8s.io/v1alpha2 kind: InferenceObjective metadata: name: food-review spec: priority: 10 poolRef: name: vllm-qwen3-32b group: "inference.networking.k8s.io"מחילים את המניפסט על שני האשכולות:
kubectl apply -f inference-objective.yaml --context=$CLUSTER1_CONTEXT kubectl apply -f inference-objective.yaml --context=$CLUSTER2_CONTEXTמחליפים את מה שכתוב בשדות הבאים:
- $CLUSTER1_CONTEXT: ההקשר של האשכול הראשון, לדוגמה
gke_my-project_europe-west3-c_gke-west. - $CLUSTER2_CONTEXT: ההקשר של האשכול השני, לדוגמה
gke_my-project_us-east4-a_gke-east.
- $CLUSTER1_CONTEXT: ההקשר של האשכול הראשון, לדוגמה
פורסים את משאבי InferencePool לשני האשכולות באמצעות Helm:
helm install vllm-qwen3-32b \ --kube-context $CLUSTER1_CONTEXT \ --set inferencePool.modelServers.matchLabels.app=vllm-qwen3-32b \ --set provider.name=gke \ --set inferenceExtension.monitoring.gke.enabled=true \ --version v1.5.0 \ oci://registry.k8s.io/gateway-api-inference-extension/charts/inferencepoolhelm install vllm-qwen3-32b \ --kube-context $CLUSTER2_CONTEXT \ --set inferencePool.modelServers.matchLabels.app=vllm-qwen3-32b \ --set provider.name=gke \ --set inferenceExtension.monitoring.gke.enabled=true \ --version v1.5.0 \ oci://registry.k8s.io/gateway-api-inference-extension/charts/inferencepoolהפקודות הקודמות משתמשות בגרסה
v1.5.0של תרשים Helm כי זו גרסה מומלצת להגדרה הזו. תרשים Helm גם מתקין משאב מותאם אישיתGCPBackendPolicyומשאב מותאם אישיתHealthCheckPolicyשמיועדים לשימוש באשכול יחיד.בגרסה
v1.1.0של תרשים HelmInferencePool, יכול להיות שהמערכת תתעלם מהדגל--set inferencePool.targetPortNumber, ויציאת היעד תוגדר כברירת מחדל ל-8000. אם שרת המודל שלכם מאזין ליציאה אחרת (לדוגמה, SGLang מוגדר כברירת מחדל לפעול ביציאה30000), צריך לאמת את היציאה אחרי ההתקנה:kubectl get inferencepool POOL_NAME -o jsonpath='{.spec.targetPorts}' \ --context=CLUSTER_CONTEXTאם היציאה שגויה, צריך לתקן את
InferencePoolהמשאב המותאם אישית לפני שמייצאים אותו:kubectl patch inferencepool POOL_NAME --type=merge \ -p '{"spec":{"targetPorts":[{"number":TARGET_PORT}]}}' \ --context=CLUSTER_CONTEXTמסמנים את משאבי InferencePool כמיוצאים בשני האשכולות. ההערה הזו מאפשרת לייבא את InferencePool על ידי אשכול ההגדרות, וזה שלב חובה לניתוב מרובה אשכולות.
kubectl annotate inferencepool vllm-qwen3-32b networking.gke.io/export="True" \ --context=$CLUSTER1_CONTEXTkubectl annotate inferencepool vllm-qwen3-32b networking.gke.io/export="True" \ --context=$CLUSTER2_CONTEXT
פריסת משאבים באשכול התצורה
כדי להגדיר איך תעבורת הנתונים מנותבת ואיך מתבצע איזון עומסים בין משאבי InferencePool בכל האשכולות הרשומים, פורסים את המשאבים Gateway, HTTPRoute ו-HealthCheckPolicy. אתם פורסים את המשאבים האלה רק באשכול ההגדרות הייעודי, שהוא gke-west במסמך הזה.
יוצרים קובץ בשם
mcig.yamlעם התוכן הבא:--- apiVersion: gateway.networking.k8s.io/v1 kind: Gateway metadata: name: cross-region-gateway namespace: default spec: gatewayClassName: gke-l7-cross-regional-internal-managed-mc addresses: - type: networking.gke.io/ephemeral-ipv4-address/europe-west3 value: "europe-west3" - type: networking.gke.io/ephemeral-ipv4-address/us-east4 value: "us-east4" listeners: - name: http protocol: HTTP port: 80 --- apiVersion: gateway.networking.k8s.io/v1 kind: HTTPRoute metadata: name: vllm-qwen3-32b-default spec: parentRefs: - name: cross-region-gateway kind: Gateway rules: - backendRefs: - group: networking.gke.io kind: GCPInferencePoolImport name: vllm-qwen3-32b --- apiVersion: networking.gke.io/v1 kind: HealthCheckPolicy metadata: name: health-check-policy namespace: default spec: targetRef: group: "networking.gke.io" kind: GCPInferencePoolImport name: vllm-qwen3-32b default: config: type: HTTP httpHealthCheck: requestPath: /health port: 8000החלת המניפסט:
kubectl apply -f mcig.yaml --context=$CLUSTER1_CONTEXT
הפעלת דיווח על מדדים מותאמים אישית
כדי להפעיל דיווח על מדדים מותאמים אישית ולעזור לשפר את איזון העומסים בין אזורים, צריך לייצא את מדדי השימוש במטמון KV מכל האשכולות. מאזן העומסים משתמש בנתוני השימוש במטמון KV שיוצאו כאות עומס מותאם אישית. השימוש באותות טעינה מותאמים אישית מאפשר לקבל החלטות חכמות יותר לגבי איזון עומסים על סמך עומס העבודה בפועל בכל אשכול.
יוצרים קובץ בשם
metrics.yamlעם התוכן הבא:apiVersion: autoscaling.gke.io/v1beta1 kind: AutoscalingMetric metadata: name: gpu-cache namespace: default spec: selector: matchLabels: app: vllm-qwen3-32b endpoints: - port: 8000 path: /metrics metrics: - name: vllm:kv_cache_usage_perc # For vLLM versions v0.10.2 and newer exportName: kv-cache - name: vllm:gpu_cache_usage_perc # For vLLM versions v0.6.2 and newer exportName: kv-cache-oldמחילים את הגדרת המדדים על שני האשכולות:
kubectl apply -f metrics.yaml --context=$CLUSTER1_CONTEXT kubectl apply -f metrics.yaml --context=$CLUSTER2_CONTEXT
הגדרת מדיניות איזון העומסים
כדי לבצע אופטימיזציה של אופן חלוקת הבקשות להסקת מסקנות של AI/ML בין אשכולות GKE, צריך להגדיר מדיניות של איזון עומסים. מצב איזון מתאים עוזר להבטיח ניצול יעיל של המשאבים, מונע עומס יתר על אשכולות בודדים ועוזר לשפר את הביצועים ואת מהירות התגובה של שירותי ההסקה.
הגדרת פסק זמן
אם הבקשות צפויות להימשך זמן רב, צריך להגדיר זמן קצוב לתפוגה ארוך יותר למאזן העומסים (LB). ב-GCPBackendPolicy, מגדירים את השדה timeoutSec לערך שהוא לפחות פי שניים ממה שמוערך כחביון של בקשת P99. לעומסי עבודה של הסקת מסקנות בהקשר ארוך עם מספר גבוה של בקשות בו-זמניות, יכול להיות שתצטרכו הגדרת זמן קצוב לתפוגה של עד 3600 שניות.
לדוגמה, במניפסט הבא מוגדר זמן קצוב לתפוגה של מאזן העומסים ל-600 שניות.
apiVersion: networking.gke.io/v1
kind: GCPBackendPolicy
metadata:
name: my-backend-policy
spec:
targetRef:
group: "networking.gke.io"
kind: GCPInferencePoolImport
name: vllm-qwen3-32b
default:
timeoutSec: 600
balancingMode: CUSTOM_METRICS
trafficDuration: LONG
customMetrics:
- name: gke.named_metrics.kv-cache
dryRun: false
maxUtilizationPercent: 60
מידע נוסף זמין במאמר בנושא מגבלות של שערים מרובי-אשכולות.
מצבי איזון העומסים Custom metrics ו-In-flight requests הם בלעדיים, ולכן צריך להגדיר רק אחד מהם ב-GCPBackendPolicy.
בוחרים מצב איזון עומסים לפריסה.
מדדים מותאמים אישית
כדי להשיג איזון עומסים אופטימלי, מתחילים עם ניצול יעד של 60%. כדי להשיג את היעד הזה, צריך להגדיר את maxUtilizationPercent: 60 בהגדרות של GCPBackendPolicy customMetrics.
יוצרים קובץ בשם
backend-policy.yamlעם התוכן הבא כדי להפעיל איזון עומסים על סמך המדד המותאם אישיתkv-cache:apiVersion: networking.gke.io/v1 kind: GCPBackendPolicy metadata: name: my-backend-policy spec: targetRef: group: "networking.gke.io" kind: GCPInferencePoolImport name: vllm-qwen3-32b default: balancingMode: CUSTOM_METRICS trafficDuration: LONG customMetrics: - name: gke.named_metrics.kv-cache dryRun: false maxUtilizationPercent: 60החלת המדיניות החדשה:
kubectl apply -f backend-policy.yaml --context=$CLUSTER1_CONTEXT
בקשות במהלך הטיסה
כדי להשתמש במצב איזון בזמן העברת נתונים, צריך להעריך את מספר הבקשות בזמן העברת נתונים שכל בק-אנד יכול לטפל בהן ולהגדיר במפורש ערך קיבולת.
כדי להפעיל איזון עומסים על סמך מספר הבקשות הפעילות, יוצרים קובץ בשם
backend-policy.yamlעם התוכן הבא:kind: GCPBackendPolicy apiVersion: networking.gke.io/v1 metadata: name: my-backend-policy spec: targetRef: group: "networking.gke.io" kind: GCPInferencePoolImport name: vllm-qwen3-32b default: balancingMode: IN_FLIGHT trafficDuration: LONG maxInFlightRequestsPerEndpoint: 1000 dryRun: falseהחלת המדיניות החדשה:
kubectl apply -f backend-policy.yaml --context=$CLUSTER1_CONTEXT
אימות הפריסה
כדי לאמת את מאזן העומסים הפנימי, צריך לשלוח בקשות מתוך רשת ה-VPC, כי מאזני עומסים פנימיים משתמשים בכתובות IP פרטיות. מריצים Pod זמני באחד מהאשכולות כדי לשלוח בקשות מרשת ה-VPC ולאמת את מאזן העומסים הפנימי:
במעטפת החדשה, מקבלים את כתובת ה-IP של השער:
GW_IP=$(kubectl get gateway/cross-region-gateway -n default --context=$CLUSTER1_CONTEXT -o jsonpath='{.status.addresses[0].value}')שליחת בקשת בדיקה מ-Pod זמני בתוך האשכול:
kubectl run -it --rm --image=curlimages/curl curly --context=$CLUSTER1_CONTEXT -- \ curl -i -X POST ${GW_IP}:80/v1/completions -H 'Content-Type: application/json' -d '{ "model": "Qwen/Qwen3-32B", "prompt": "What is the best pizza in the world?", "max_tokens": 100, "temperature": 0 }'
המאמרים הבאים
- מידע נוסף על GKE Gateway API
- מידע נוסף על GKE Inference Gateway עם כמה אשכולות
- מידע נוסף על Multi Cluster Ingress