הגדרת זמינות גבוהה גמישה בין אזורים

במאמר הזה מוסבר איך להגדיר זמינות גבוהה גמישה בכמה אזורים לעומסי עבודה של הסקת AI, באמצעות שער להסקת נתונים בכמה אשכולות ב-Google Kubernetes Engine ‏ (GKE) והתכונה "התאמה אוטומטית לעומס" ב-GKE. ההגדרה הזו מאפשרת לכם לאזן עומסים של עומסי עבודה בצורה חכמה בין כמה אשכולות GKE באזורים שונים.

מידע נוסף על GKE Multi-Cluster Inference Gateway זמין במאמר מידע על GKE Multi-Cluster Inference Gateway.

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

  1. מפעילים את Google Kubernetes Engine API.

    הפעלת Google Kubernetes Engine API

  2. אם אתם מתכוונים להשתמש ב-Google Cloud CLI למשימה הזו, אתם צריכים להתקין ולהפעיל אותו.

  3. מוודאים שיש בפרויקט מכסה מספקת לשימוש במעבדי H100 GPU. למידע נוסף, קראו את המאמרים מכסות GPU והקצאת משאבים.

  4. משתמשים בגרסה 1.34.1-gke.1127000 או בגרסה חדשה יותר של GKE.

  5. צריך להשתמש ב-CLI של gcloud בגרסה 480.0.0 ואילך.

  6. מוודאים שלחשבון השירות שבו משתמשים הצמתים יש את ההרשאות roles/monitoring.metricWriter ו-roles/stackdriver.resourceMetadata.writer.

  7. מוודאים שיש לכם תפקידים ב-IAM (המערכת לניהול הזהויות והרשאות הגישה) roles/container.admin וroles/iam.serviceAccountAdmin בפרויקט.

  8. מבצעים את הפעולות הבאות ב-Hugging Face:

    1. יוצרים חשבון Hugging Face.
    2. שולחים בקשה ומקבלים אישור לגישה למודל Llama 3.1 ב-Hugging Face.
    3. חותמים על הסכם הרישיון בדף של המודל ב-Hugging Face.
    4. יוצרים אסימון גישה ל-Hugging Face עם הרשאות קריאה לפחות.

יצירת אשכולות ומאגרי צמתים

כדי ליצור שני אשכולות GKE באזורים שונים ולהגדיר את מאגרי הצמתים שלהם, פועלים לפי השלבים הבאים:

  1. יוצרים את האשכול הראשון:

    gcloud container clusters create gke-west --zone \
        CLUSTER_1_ZONE \
        --project=PROJECT_ID \
        --gateway-api=standard \
        --cluster-version=GKE_VERSION \
        --machine-type="MACHINE_TYPE" \
        --disk-type="DISK_TYPE" \
        --enable-managed-prometheus --monitoring=SYSTEM,DCGM \
        --hpa-profile=performance \
        --workload-pool=PROJECT_ID.s3ns.svc.id.goog \
        --async
    

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

    • ‫PROJECT_ID: מזהה הפרויקט
    • ‫CLUSTER_1_ZONE: האזור של האשכול הראשון, לדוגמה europe-west3-c
    • ‫GKE_VERSION: גרסת GKE לשימוש, לדוגמה 1.34.1-gke.1127000
    • ‫MACHINE_TYPE: סוג המכונה של צמתי האשכול, לדוגמה c2-standard-16
    • ‫DISK_TYPE: סוג הדיסק של צמתי האשכול, לדוגמה pd-standard
  2. יוצרים מאגר צמתים של H100 באשכול הראשון:

    gcloud container node-pools create h100 \
        --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 \
        --min-nodes=MIN_NUM_NODES \
        --max-nodes=MAX_NUM_NODES \
        --enable-autoscaling \
        --async
    

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

    • ‫PROJECT_ID: מזהה הפרויקט
    • ‫CLUSTER_1_ZONE: האזור של האשכול הראשון, לדוגמה europe-west3-c
    • ‫CLUSTER_1_NAME: השם של האשכול הראשון, למשל gke-west
    • ‫NODE_POOL_MACHINE_TYPE: סוג המכונה של מאגר הצמתים, לדוגמה a3-highgpu-2g
    • ‫NUM_NODES: מספר הצמתים במאגר הצמתים, לדוגמה 3
    • ‫MIN_NUM_NODES: מספר הצמתים המינימלי להתאמה אוטומטית לעומס במאגר הצמתים, לדוגמה 1
    • ‫MAX_NUM_NODES: המספר המקסימלי של הצמתים להתאמה אוטומטית לעומס במאגר הצמתים, לדוגמה 10
  3. מקבלים פרטי כניסה ויוצרים סוד של טוקן Hugging Face באשכול הראשון:

    gcloud container clusters get-credentials CLUSTER_1_NAME \
        --location CLUSTER_1_ZONE \
        --project=PROJECT_ID
    
    kubectl create secret generic hf-token \
        --from-literal=token=HF_TOKEN
    

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

    • ‫PROJECT_ID: מזהה הפרויקט
    • ‫CLUSTER_1_NAME: השם של האשכול הראשון, למשל gke-west
    • ‫CLUSTER_1_ZONE: האזור של האשכול הראשון, לדוגמה europe-west3-c
    • ‫HF_TOKEN: טוקן הגישה שלכם ל-Hugging Face
  4. יוצרים את האשכול השני באזור אחר מהאזור של האשכול הראשון:

    gcloud container clusters create gke-east --zone CLUSTER_2_ZONE \
        --project=PROJECT_ID \
        --gateway-api=standard \
        --cluster-version=GKE_VERSION \
        --machine-type="MACHINE_TYPE" \
        --disk-type="DISK_TYPE" \
        --enable-managed-prometheus \
        --monitoring=SYSTEM,DCGM \
        --hpa-profile=performance \
        --workload-pool=PROJECT_ID.s3ns.svc.id.goog \
        --async
    

    מחליפים את CLUSTER_2_ZONE באזור של האשכול השני, לדוגמה us-east4-a.

  5. יוצרים מאגר צמתים מסוג 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 \
        --min-nodes=MIN_NUM_NODES \
        --max-nodes=MAX_NUM_NODES \
        --enable-autoscaling \
        --async
    

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

    • ‫PROJECT_ID: מזהה הפרויקט
    • ‫CLUSTER_2_ZONE: האזור של האשכול השני, למשל us-east4-a
    • ‫CLUSTER_2_NAME: השם של האשכול השני, למשל gke-east
    • ‫NODE_POOL_MACHINE_TYPE: סוג המכונה של מאגר הצמתים, לדוגמה a3-highgpu-2g
    • ‫NUM_NODES: מספר הצמתים במאגר הצמתים, לדוגמה 3
    • ‫MIN_NUM_NODES: מספר הצמתים המינימלי להתאמה אוטומטית לעומס במאגר הצמתים, לדוגמה 1
    • ‫MAX_NUM_NODES: המספר המקסימלי של הצמתים להתאמה אוטומטית לעומס במאגר הצמתים, לדוגמה 10
  6. מקבלים פרטי כניסה ויוצרים סוד לטוקן 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
    

    מחליפים את הפרטים הבאים. הגדרות של משתנים אחרים מפורטות בשלבים הקודמים:

    • ‫HF_TOKEN: טוקן הגישה שלכם ל-Hugging Face

רישום אשכולות ב-Fleet

  1. רישום האשכולות ל-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_2_NAME: השם של האשכול השני, למשל gke-east
  2. מפעילים את התכונה 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 בלבד

אזהרה: Cloud de Confiance by S3NS מאפשרת לכל רשת VPC להכיל רק רשת משנה אחת של פרוקסי בלבד לכל אזור. אם אזור היעד כבר מכיל רשת משנה מסוג proxy-only עם הגדרה purpose=REGIONAL_MANAGED_PROXY, יצירת רשת המשנה GLOBAL_MANAGED_PROXY תיכשל. קודם צריך למחוק את רשת המשנה האזורית הקיימת שמשמשת רק לשרתי proxy. מחיקה של רשת משנה אזורית שמשמשת רק כשרת proxy משפיעה על כל מאזני העומסים האזוריים שמבוססים על Envoy באותו אזור שמשתמשים בה, ולכן חשוב לתכנן את השינוי בהתאם.

  1. יוצרים רשת משנה באזור של האשכול הראשון:

    gcloud compute networks subnets create CLUSTER_1_REGION-subnet \
        --purpose=GLOBAL_MANAGED_PROXY \
        --role=ACTIVE \
        --region=CLUSTER_1_REGION \
        --network=default \
        --range=SUBNET_RANGE_1 \
        --project=PROJECT_ID
    

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

    • ‫PROJECT_ID: מזהה הפרויקט
    • ‫CLUSTER_1_REGION: האזור של האשכול הראשון, למשל europe-west3
    • ‫SUBNET_RANGE_1: טווח כתובות ה-IP של רשת המשנה של הפרוקסי באזור של האשכול הראשון, לדוגמה 10.0.0.0/23
  2. יוצרים רשת משנה באזור של האשכול השני:

    gcloud compute networks subnets create CLUSTER_2_REGION-subnet \
        --purpose=GLOBAL_MANAGED_PROXY \
        --role=ACTIVE \
        --region=CLUSTER_2_REGION \
        --network=default \
        --range=SUBNET_RANGE_2 \
        --project=PROJECT_ID
    

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

    • ‫PROJECT_ID: מזהה הפרויקט
    • ‫CLUSTER_2_REGION: האזור של האשכול השני, למשל us-east4
    • ‫SUBNET_RANGE_2: טווח כתובות ה-IP של רשת המשנה של הפרוקסי באזור של האשכול השני, לדוגמה 10.5.0.0/23

התקנת המשאבים המותאמים אישית הנדרשים

  1. מגדירים משתני הקשר עבור האשכולות:

    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
  2. מתקינים את המשאב המותאם אישית InferencePool ואת המשאב המותאם אישית InferenceObjective בשני האשכולות:

    kubectl apply -f https://github.com/kubernetes-sigs/gateway-api-inference-extension/releases/download/v1.0.1/manifests.yaml --context=$CLUSTER1_CONTEXT
    
    kubectl apply -f https://github.com/kubernetes-sigs/gateway-api-inference-extension/releases/download/v1.0.1/manifests.yaml --context=$CLUSTER2_CONTEXT
    

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

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

    kubectl apply -f \
    https://raw.githubusercontent.com/kubernetes-sigs/gateway-api-inference-extension/release-1.0/config/manifests/vllm/gpu-deployment.yaml \
    --context=$CLUSTER1_CONTEXT
    
    kubectl apply -f \
    https://raw.githubusercontent.com/kubernetes-sigs/gateway-api-inference-extension/release-1.0/config/manifests/vllm/gpu-deployment.yaml \
    --context=$CLUSTER2_CONTEXT
    
  2. שומרים את קובץ המניפסט הבא בשם inference-objective.yaml:

    apiVersion: inference.networking.x-k8s.io/v1alpha2
    kind: InferenceObjective
    metadata:
      name: food-review
    spec:
      priority: 10
      poolRef:
        name: llama3-8b-instruct
        group: "inference.networking.k8s.io"
    
  3. מחילים את קובץ המניפסט על שני האשכולות:

    kubectl apply -f inference-objective.yaml --context=$CLUSTER1_CONTEXT
    kubectl apply -f inference-objective.yaml --context=$CLUSTER2_CONTEXT
    
  4. פורסים את משאבי InferencePool לשני האשכולות באמצעות Helm:

    helm install vllm-llama3-8b-instruct \
      --kube-context $CLUSTER1_CONTEXT \
      --set inferencePool.modelServers.matchLabels.app=vllm-llama3-8b-instruct \
      --set provider.name=gke \
      --set inferenceExtension.monitoring.gke.enabled=true \
      --version v1.0.1 \
      oci://registry.k8s.io/gateway-api-inference-extension/charts/inferencepool
    
    helm install vllm-llama3-8b-instruct \
      --kube-context $CLUSTER2_CONTEXT \
      --set inferencePool.modelServers.matchLabels.app=vllm-llama3-8b-instruct \
      --set provider.name=gke \
      --set inferenceExtension.monitoring.gke.enabled=true \
      --version v1.0.1 \
      oci://registry.k8s.io/gateway-api-inference-extension/charts/inferencepool
    
  5. בשני האשכולות, מסמנים את המשאבים InferencePool כמיוצאים בשני האשכולות:

    kubectl annotate inferencepool vllm-llama3-8b-instruct networking.gke.io/export="True" \
        --context=$CLUSTER1_CONTEXT
    
    kubectl annotate inferencepool vllm-llama3-8b-instruct networking.gke.io/export="True" \
        --context=$CLUSTER2_CONTEXT
    

פריסת שער היקשים חוצה אזורים

  1. שומרים את קובץ המניפסט הבא בשם mygateway.yaml:

    ---
    kind: Gateway
    apiVersion: gateway.networking.k8s.io/v1beta1
    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
        allowedRoutes:
          kinds:
          -   kind: HTTPRoute
          namespaces:
            from: All
    ---
    apiVersion: gateway.networking.k8s.io/v1beta1
    kind: HTTPRoute
    metadata:
      name: vllm-llama3-8b-instruct-default
    spec:
      parentRefs:
      -   name: cross-region-gateway
        kind: Gateway
      rules:
      -   backendRefs:
        -   group: networking.gke.io
          kind: GCPInferencePoolImport
          name: vllm-llama3-8b-instruct
    ---
    kind: HealthCheckPolicy
    apiVersion: networking.gke.io/v1
    metadata:
      name: health-check-policy
      namespace: default
    spec:
      targetRef:
        group: "networking.gke.io"
        kind: GCPInferencePoolImport
        name: vllm-llama3-8b-instruct
      default:
        config:
          type: HTTP
          httpHealthCheck:
              requestPath: /health
              port: 8000
    
  2. מחילים את המניפסט על אשכול ההגדרות:

    kubectl apply -f mygateway.yaml --context=CLUSTER1_CONTEXT
    

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

    • ‫CLUSTER1_CONTEXT: ההקשר של האשכול הראשון, לדוגמה gke_my-project_europe-west3-c_gke-west

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

  1. יוצרים קובץ בשם metrics.yaml עם התוכן הבא:

    apiVersion: autoscaling.gke.io/v1beta1
    kind: AutoscalingMetric
    metadata:
      name: gpu-cache
      namespace: default
    spec:
      selector:
        matchLabels:
          app: vllm-llama3-8b-instruct
      endpoints:
      -   port: 8000
        path: /metrics
        metrics:
        -   name: vllm:kv_cache_usage_perc
          exportName: kv-cache
        -   name: vllm:gpu_cache_usage_perc
          exportName: kv-cache-old
    
  2. בכל אשכול, מחילים את הגדרת המדדים:

    kubectl apply -f metrics.yaml --context=CLUSTER1_CONTEXT
    kubectl apply -f metrics.yaml --context=CLUSTER2_CONTEXT
    

    ההגדרות של CLUSTER1_CONTEXT ו-CLUSTER2_CONTEXT מפורטות במאמר התקנת המשאבים הנדרשים בהתאמה אישית.

הגדרת מדיניות איזון העומסים

בקטע הזה מוסבר איך להגדיר את מדיניות איזון העומסים. במדיניות הזו מוגדרת שיטת חלוקת התנועה בין מאגרי ההסקה על סמך מדדים מותאמים אישית והעדפות אזוריות. ההגדרה הבאה קובעת את us-east4 כאזור המועדף. התנועה עוברת לאזורים אחרים רק כשהמדד המותאם אישית gke.named_metrics.kv-cache באזור us-east4 מגיע ל-80% ניצול.

  • בגרסאות vLLM‏ v0.10.2 ואילך, משתמשים במדד gke.named_metrics.kv-cache.
  • בגרסאות קודמות, משתמשים במדד gke.named_metrics.kv-cache-old.
  1. יוצרים קובץ בשם 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-llama3-8b-instruct
      default:
        timeoutSec: 600
        balancingMode: CUSTOM_METRICS
        trafficDuration: LONG
        customMetrics:
        -   name: gke.named_metrics.kv-cache
          maxUtilizationPercent: 80
          dryRun: false
        scopes:
        -   selector:
            gke.io/region: "us-east4"
          backendPreference: PREFERRED
    
  2. החלת המדיניות החדשה:

    kubectl apply -f backend-policy.yaml --context=CLUSTER1_CONTEXT
    

    מחליפים את CLUSTER1_CONTEXT בהקשר של האשכול הראשון, לדוגמה gke_my-project_europe-west3-c_gke-west.

הגדרת התאמה אוטומטית לעומס

כדי לוודא שכל אשכול יכול להתמודד עם עומס גדל והולך לפני שהתנועה עוברת לאזורים אחרים, צריך להגדיר את הכלי Horizontal-Pod-Autoscaler ‏ (HPA) לפריסות של שרת המודל.

עקרונות מרכזיים להגדרה

  • שימוש באותם מדדים בהתאמה אישית: צריך להגדיר את ה-HPA כך שישנה את קנה המידה על סמך אותם מדדים בהתאמה אישית שבהם אתם משתמשים ב-GCPBackendPolicy בשביל Multi-Cluster Inference Gateway (לדוגמה, vllm:kv_cache_usage_perc). הגישה הזו עוזרת לוודא שההחלטות לגבי איזון העומסים ושינוי קנה המידה מבוססות על אותו אות משרתי ההסקה. המדדים שבוחרים צריכים להיות בעלי ערך בין 0 ל-1 כדי לייצג את רמת הניצול. אם ערך המדד גדול מ-1, הוא מתפרש כניצול של 100% על ידי מאזן העומסים, וזה עלול לגרום להתנהגויות לא צפויות של ניתוב.

  • הגדרת יעד HPA נמוך יותר: ערך היעד של המדד בהגדרת ה-HPA צריך להיות נמוך יותר מההגדרה של maxUtilizationPercent שמוגדרת ב-GCPBackendPolicy. אם מגדירים את יעד הניצול של HPA לערך נמוך יותר (לדוגמה, HPA מבצע מידרוג ב-50% ניצול ממוצע), מאפשרים לאשכול להוסיף עוד רפליקות לפני שמגיעים לסף של מאזן העומסים (לדוגמה, 80% ניצול). הגישה הזו עוזרת למקסם את הקיבולת באזור המועדף. הגדרת יעד ניצול נמוך יותר עוזרת גם למנוע מעבר תנועה מוקדם מדי, כי היא מאפשרת לשמור את הזמינות הגבוהה האלסטית בין אזורים למקרים שבהם האזור הנוכחי באמת מתקרב למגבלות שלו.

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

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

    המשתנים CLUSTER1_CONTEXT ו-CLUSTER2_CONTEXT מוגדרים בקטע התקנת המשאבים הנדרשים בהתאמה אישית.

  2. מחילים את המניפסט על כל אשכול:

    kubectl apply -f https://raw.githubusercontent.com/GoogleCloudPlatform/k8s-stackdriver/master/custom-metrics-stackdriver-adapter/deploy/production/adapter_new_resource_model.yaml --context=CLUSTER1_CONTEXT
    
    kubectl apply -f https://raw.githubusercontent.com/GoogleCloudPlatform/k8s-stackdriver/master/custom-metrics-stackdriver-adapter/deploy/production/adapter_new_resource_model.yaml --context=CLUSTER2_CONTEXT
    
  3. מתן הרשאה לחשבון השירות custom-metrics-stackdriver-adapter לקרוא מדדים של Cloud Monitoring:

    PROJECT_NUMBER=$(gcloud projects describe PROJECT_ID --format="value(projectNumber)")
    
    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.s3ns.svc.id.goog/subject/ns/custom-metrics/sa/custom-metrics-stackdriver-adapter
    

    מחליפים את PROJECT_ID במזהה הפרויקט.

  4. שומרים את קובץ המניפסט הבא בשם pod-monitoring.yaml:

    apiVersion: monitoring.googleapis.com/v1
    kind: PodMonitoring
    metadata:
      name: inference-server-podmon
    spec:
      selector:
        matchLabels:
          app: vllm-llama3-8b-instruct
      endpoints:
      -   port: 8000
        path: /metrics
        interval: 5s
    
  5. מחילים את קובץ המניפסט על שני האשכולות:

    kubectl apply -f pod-monitoring.yaml --context=CLUSTER1_CONTEXT
    kubectl apply -f pod-monitoring.yaml --context=CLUSTER2_CONTEXT
    
  6. שומרים את קובץ המניפסט הבא בשם hpa.yaml:

    apiVersion: autoscaling/v2
    kind: HorizontalPodAutoscaler
    metadata:
      name: inference-server-hpa
    spec:
      scaleTargetRef:
        apiVersion: apps/v1
        kind: Deployment
        name: vllm-llama3-8b-instruct
      minReplicas: 1
      maxReplicas: 10
      metrics:
      -   type: Pods
        pods:
          metric:
            name: prometheus.googleapis.com|vllm:gpu_cache_usage_perc|gauge
          target:
            type: AverageValue
            averageValue: "0.5"
    
  7. מחילים את קובץ המניפסט על שני האשכולות:

    kubectl apply -f hpa.yaml --context=CLUSTER1_CONTEXT
    kubectl apply -f hpa.yaml --context=CLUSTER2_CONTEXT
    

אימות הפריסה

  1. מאתרים את כתובת ה-IP של השער:

    export GW_IP=$(kubectl get gateway/cross-region-gateway -n default --context=CLUSTER1_CONTEXT -o jsonpath='{.status.addresses[0].value}')
    
    echo ${GW_IP}
    

    המשתנה CLUSTER1_CONTEXT מוגדר בקטע התקנת משאבים מותאמים אישית נדרשים.

  2. איך מתחילים סשן אינטראקטיבי של sh ב-Pod זמני:

    kubectl run -it --rm --image=curlimages/curl curly --context=CLUSTER1_CONTEXT -- /bin/sh
    

    המשתנה CLUSTER1_CONTEXT מוגדר בקטע התקנת משאבים מותאמים אישית נדרשים.

  3. מתוך ה-Pod של curly, שולחים בקשת בדיקה:

    curl -i -X POST <var>GW_IP</var>:80/v1/completions \
    -H 'Content-Type: application/json' \
    -d '{
      "model": "food-review-1",
      "prompt": "What is the best pizza in the world?",
      "max_tokens": 100,
      "temperature": 0
    }'
    

    מחליפים את GW_IP בכתובת ה-IP של השער מהשלב הקודם.

בדיקת עומס של השער

  1. מפעילים עומס מתמשך על כתובת ה-IP של שער הרשת באמצעות מחולל עומסים באותה רשת VPC.

  2. מתחילים בעומס מתון שהאזור המועדף (us-east4) אמור להתמודד איתו.

  3. הגדילו בהדרגה את קצב הבקשות או את מספר הבקשות בו-זמנית בבדיקת העומס.

  4. בזמן שבדיקת העומס פועלת, עוקבים אחרי המערכת במסוף Cloud de Confiance או באמצעות kubectl:

    • שינוי קנה מידה של Pod (HPA): בודקים את מספר ה-Pods בפריסת vllm-llama3-8b-instruct בשני האשכולות.
    • שינוי גודל הצמתים (Cluster Autoscaler): מעקב אחרי מספר הצמתים ב-h100 מאגרי הצמתים בשני האשכולות.
    • מדדים בהתאמה אישית: עוקבים אחרי המדד vllm:kv_cache_usage_perc (לגרסת vllm‏ v0.10.2 ואילך) או המדד vllm:gpu_cache_usage_perc (לגרסת vllm נמוכה מ-v.0.10.2) ב-Monitoring לפריסות של שרת המודל בשני האשכולות.
    • מדדים של מאזן עומסים: בודקים את המדדים של מאזן העומסים שמשויך ל-cross-region-gateway ב-Monitoring.

ככל שתגדילו את העומס, רמת הניצול ב-us-east4 תעלה. כשה-HPA באשכול gke-east מתרחב אופקית בהתאם לעומס (scale out) והניצול הממוצע מתקרב לערך maxUtilization (80%) שמוגדר ב-GCPBackendPolicy, מאזן העומסים מתחיל לנתב בקשות לאשכול gke-west ב-europe-west3.

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