התאמה אישית של ההגדרה של GKE Inference Gateway

בדף הזה מוסבר איך להתאים אישית את הפריסה של GKE Inference Gateway.

הדף הזה מיועד למומחי רשתות שאחראים על ניהול התשתית של GKE, ולאדמינים של פלטפורמות שמנהלים עומסי עבודה של AI.

כדי לנהל ולבצע אופטימיזציה של עומסי עבודה של הסקת מסקנות, צריך להגדיר תכונות מתקדמות של GKE Inference Gateway.

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

הגדרת בדיקות אבטחה ובטיחות של AI

‫GKE Inference Gateway משתלב עם Model Armor כדי לבצע בדיקות בטיחות בהנחיות ובתשובות של אפליקציות שמשתמשות במודלים גדולים של שפה (LLM). השילוב הזה מספק שכבת אבטחה נוספת ברמת התשתית, שמשלימה את אמצעי האבטחה ברמת האפליקציה. ההגדרה הזו מאפשרת להחיל מדיניות באופן מרכזי על כל התנועה של מודלים גדולים של שפה (LLM). אפשר גם להשתמש ב-NVIDIA NeMo Guardrails לביצוע בדיקות בטיחות.

בתרשים הבא מוצגת דוגמה לאינטגרציה של Model Armor עם GKE Inference Gateway באשכול GKE:

 ‫Cloud de Confiance by S3NS שילוב של הגנה מוגברת על המודל באשכול GKE
איור: שילוב של Model Armor באשכול GKE

כדי להגדיר בדיקות בטיחות של AI, פועלים לפי השלבים הבאים:

  1. דרישות מוקדמות

    1. מפעילים את שירות הגנה מוגברת על המודל בפרויקט ב- Cloud de Confiance by S3NS .
    2. יוצרים את תבניות Model Armor באמצעות מסוף Model Armor,‏ Google Cloud CLI או API. הפקודה הבאה יוצרת תבנית בשם llm שמתעדת פעולות ומסננת תוכן פוגעני.

      # Set environment variables
      PROJECT_ID=$(gcloud config get-value project)
      # Replace <var>CLUSTER_LOCATION<var> with the location of your GKE cluster. For example, `us-central1`.
      LOCATION="CLUSTER_LOCATION"
      MODEL_ARMOR_TEMPLATE_NAME=llm
      
      # Set the regional API endpoint
      gcloud config set api_endpoint_overrides/modelarmor \
        "https://modelarmor.$LOCATION.rep.googleapis.com/"
      
      # Create the template
      gcloud model-armor templates create $MODEL_ARMOR_TEMPLATE_NAME \
        --location $LOCATION \
        --pi-and-jailbreak-filter-settings-enforcement=enabled \
        --pi-and-jailbreak-filter-settings-confidence-level=MEDIUM_AND_ABOVE \
        --rai-settings-filters='[{ "filterType": "HATE_SPEECH", "confidenceLevel": "MEDIUM_AND_ABOVE" },{ "filterType": "DANGEROUS", "confidenceLevel": "MEDIUM_AND_ABOVE" },{ "filterType": "HARASSMENT", "confidenceLevel": "MEDIUM_AND_ABOVE" },{ "filterType": "SEXUALLY_EXPLICIT", "confidenceLevel": "MEDIUM_AND_ABOVE" }]' \
        --template-metadata-log-sanitize-operations \
        --template-metadata-log-operations
      
  2. מתן הרשאות IAM

    לחשבון השירות של Service Extensions נדרשות הרשאות גישה למשאבים הדרושים. מריצים את הפקודות הבאות כדי להקצות את התפקידים הנדרשים:

    PROJECT_NUMBER=$(gcloud projects describe $PROJECT_ID --format 'get(projectNumber)')
    
    gcloud projects add-iam-policy-binding $PROJECT_ID \
        --member=serviceAccount:service-$PROJECT_NUMBER@gcp-sa-dep.iam.s3ns-system.iam.gserviceaccount.com \
        --role=roles/container.admin
    
    gcloud projects add-iam-policy-binding $PROJECT_ID \
        --member=serviceAccount:service-$PROJECT_NUMBER@gcp-sa-dep.iam.s3ns-system.iam.gserviceaccount.com \
        --role=roles/modelarmor.calloutUser
    
    gcloud projects add-iam-policy-binding $PROJECT_ID \
        --member=serviceAccount:service-$PROJECT_NUMBER@gcp-sa-dep.iam.s3ns-system.iam.gserviceaccount.com \
        --role=roles/serviceusage.serviceUsageConsumer
    
    gcloud projects add-iam-policy-binding $PROJECT_ID \
        --member=serviceAccount:service-$PROJECT_NUMBER@gcp-sa-dep.iam.s3ns-system.iam.gserviceaccount.com \
        --role=roles/modelarmor.user
    
  3. הגדרת GCPTrafficExtension

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

    1. שומרים את קובץ המניפסט לדוגמה הבא בשם gcp-traffic-extension.yaml:

      kind: GCPTrafficExtension
      apiVersion: networking.gke.io/v1
      metadata:
      name: my-model-armor-extension
      spec:
      targetRefs:
      - group: "gateway.networking.k8s.io"
        kind: Gateway
        name: GATEWAY_NAME
      extensionChains:
      - name: my-model-armor-chain1
        matchCondition:
          celExpressions:
            - celMatcher: request.path.startsWith("/")
        extensions:
        - name: my-model-armor-service
          supportedEvents:
          - RequestHeaders
          - RequestBody
          - RequestTrailers
          - ResponseHeaders
          - ResponseBody
          - ResponseTrailers
          timeout: 1s
          failOpen: false
          googleAPIServiceName: "modelarmor.${LOCATION}.rep.googleapis.com"
          metadata:
            model_armor_settings: '[{"model": "${MODEL}","model_response_template_id": "projects/${PROJECT_ID}/locations/${LOCATION}/templates/${MODEL_ARMOR_TEMPLATE_NAME}","user_prompt_template_id": "projects/${PROJECT_ID}/locations/${LOCATION}/templates/${MODEL_ARMOR_TEMPLATE_NAME}"}]'
      

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

      • GATEWAY_NAME: השם של השער.
      • MODEL_ARMOR_TEMPLATE_NAME: השם של תבנית Model Armor.

      קובץ gcp-traffic-extension.yaml כולל את ההגדרות הבאות:

      • targetRefs: מציין את שער הכניסה שהתוסף הזה חל עליו.
      • extensionChains: מגדיר שרשרת של תוספים שיחולו על התנועה.
      • matchCondition: מגדיר את התנאים שבהם התוספים חלים.
      • extensions: מגדיר את התוספים שיחולו.
      • supportedEvents: מציין את האירועים שבמהלכם ההרחבה מופעלת.
      • timeout: מציין את הזמן הקצוב לתפוגה של התוסף.
      • googleAPIServiceName: מציין את שם השירות של התוסף.
      • metadata: מציין את המטא-נתונים של התוסף, כולל extensionPolicy וההגדרות של ניקוי ההנחיה או התגובה.
    2. מחילים את קובץ המניפסט לדוגמה על האשכול:

      export GATEWAY_NAME="your-gateway-name"
      export MODEL="google/gemma-3-1b-it" # Or your specific model
      envsubst < gcp-traffic-extension.yaml | kubectl apply -f -
      

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

הגדרת Apigee לאימות ולניהול API

‫GKE Inference Gateway משתלב עם Apigee כדי לספק אימות, הרשאה וניהול API לעומסי העבודה של ההסקות. למידע נוסף על היתרונות של השימוש ב-Apigee, אפשר לעיין במאמר היתרונות העיקריים של השימוש ב-Apigee.

אפשר לשלב את GKE Inference Gateway עם Apigee כדי לשפר את GKE Inference Gateway באמצעות תכונות כמו אבטחת API, הגבלת קצב, מכסות, ניתוח נתונים ומונטיזציה.

דרישות מוקדמות

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

  • אשכול GKE שפועלת בו גרסה 1.34.* ואילך.
  • אשכול GKE עם GKE Inference Gateway שנפרס.
  • מופע Apigee שנוצר באותו אזור כמו אשכול GKE.
  • ה-Apigee APIM Operator ו-CRD שלו מותקנים באשכול GKE. הוראות מפורטות מופיעות במאמר התקנת האופרטור של Apigee APIM.
  • kubectl מוגדר להתחבר לאשכול GKE.
  • Google Cloud CLI מותקן ומאומת.

יצירת ApigeeBackendService

קודם כול, יוצרים משאב ApigeeBackendService. ‫GKE Inference Gateway משתמש בזה כדי ליצור מעבד של Apigee Extension.

  1. שומרים את קובץ המניפסט הבא בשם my-apigee-backend-service.yaml:

    apiVersion: apim.googleapis.com/v1
    kind: ApigeeBackendService
    metadata:
      name: my-apigee-backend-service
    spec:
      apigeeEnv: "APIGEE_ENVIRONMENT_NAME"  # optional field
      defaultSecurityEnabled: true # optional field
      locations:
        name: "LOCATION"
        network: "CLUSTER_NETWORK"
        subnetwork: "CLUSTER_SUBNETWORK"
    

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

    • APIGEE_ENVIRONMENT_NAME: השם של סביבת Apigee. הערה: לא צריך להגדיר את השדה הזה אם apigee-apim-operator מותקן עם הדגל generateEnv=TRUE. אם לא, יוצרים סביבת Apigee לפי ההוראות במאמר יצירת סביבה.
    • LOCATION: המיקום של מכונת Apigee.
    • CLUSTER_NETWORK: הרשת של אשכול GKE.
    • CLUSTER_SUBNETWORK: רשת המשנה של אשכול GKE.
  2. מחילים את המניפסט על האשכול:

    kubectl apply -f my-apigee-backend-service.yaml
    
  3. מוודאים שהסטטוס השתנה לCREATED:

    kubectl wait --for=jsonpath='{.status.currentState}'="CREATED" -f my-apigee-backend-service.yaml --timeout=5m
    

הגדרת GKE Inference Gateway

מגדירים את GKE Inference Gateway כדי להפעיל את Apigee Extension Processor כתוסף תעבורה של מאזן עומסים.

  1. שומרים את קובץ המניפסט הבא בשם my-apigee-traffic-extension.yaml:

    kind: GCPTrafficExtension
    apiVersion: networking.gke.io/v1
    metadata:
      name: my-apigee-traffic-extension
    spec:
      targetRefs:
      - group: "gateway.networking.k8s.io"
        kind: Gateway
        name: GATEWAY_NAME
      extensionChains:
      - name: my-traffic-extension-chain
        matchCondition:
          celExpressions:
            - celMatcher: request.path.startsWith("/")
        extensions:
        - name: my-apigee-extension
          metadata:
            # The value for `apigee-extension-processor` must match the name of the `ApigeeBackendService` resource that was applied earlier.
            apigee-extension-processor: my-apigee-backend-service
          failOpen: false
          timeout: 1s
          supportedEvents:
          - RequestHeaders
          - ResponseHeaders
          - ResponseBody
          backendRef:
            group: apim.googleapis.com
            kind: ApigeeBackendService
            name: my-apigee-backend-service
            port: 443
    

    מחליפים את GATEWAY_NAME בשם השער.

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

    kubectl apply -f my-apigee-traffic-extension.yaml
    
  3. ממתינים עד שהסטטוס של GCPTrafficExtension יהפוך לProgrammed:

    kubectl wait --for=jsonpath='{.status.ancestors[0].conditions[?(@.type=="Programmed")].status}'=True -f my-apigee-traffic-extension.yaml --timeout=5m
    

שליחת בקשות מאומתות באמצעות מפתחות API

  1. כדי למצוא את כתובת ה-IP של GKE Inference Gateway, בודקים את סטטוס השער:

    GW_IP=$(kubectl get gateway/GATEWAY_NAME -o jsonpath='{.status.addresses[0].value}')
    

    מחליפים את GATEWAY_NAME בשם השער.

  2. בדיקת בקשה ללא אימות. צריך לדחות את הבקשה הזו:

    curl -i ${GW_IP}/v1/completions -H 'Content-Type: application/json' -d '{
    "model": "food-review",
    "prompt": "Write as if you were a critic: San Francisco",
    "max_tokens": 100,
    "temperature": 0
    }'
    

    תופיע תגובה שדומה לתגובה הבאה, שמציינת שהתוסף Apigee פועל:

    {"fault":{"faultstring":"Raising fault. Fault name : RF-insufficient-request-raise-fault","detail":{"errorcode":"steps.raisefault.RaiseFault"}}}
    
  3. נכנסים לממשק המשתמש של Apigee ויוצרים מפתח API. הוראות מפורטות זמינות במאמר בנושא יצירת מפתח API.

  4. שליחת מפתח ה-API בכותרת הבקשה של ה-HTTP:

    curl -i ${GW_IP}/v1/completions -H 'Content-Type: application/json' -H 'x-api-key: API_KEY' -d '{
    "model": "food-review",
    "prompt": "Write as if you were a critic: San Francisco",
    "max_tokens": 100,
    "temperature": 0
    }'
    

    מחליפים את הערך API_KEY במפתח ה-API שלכם.

מידע מפורט יותר על הגדרת מדיניות Apigee זמין במאמר שימוש במדיניות לניהול API עם Apigee APIM Operator ל-Kubernetes.

הגדרת ניראות (observability)

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

‫Cloud de Confiance by S3NS מספק את לוחות הבקרה הבאים של Cloud Monitoring שמציעים יכולות תצפית על מסקנות ל-GKE Inference Gateway:

  • לוח הבקרה של GKE Inference Gateway: כולל מדדים חשובים להצגת מודלים גדולים של שפה (LLM), כמו נפח בקשות וטוקנים, זמן אחזור, שגיאות וניצול מטמון עבור InferencePool. כדי לראות את הרשימה המלאה של המדדים הזמינים של GKE Inference Gateway, אפשר לעיין במאמר בנושא מדדים שנחשפים.
  • מרכזי בקרה של AI/ML לצפייה: מרכזי הבקרה מספקים נתונים על השימוש בתשתית, מדדי DCGM ומדדי ביצועים של מודל vLLM.
  • לוח הבקרה של שרת המודל: לוח בקרה שבו מוצגים אותות הזהב של שרת המודל. כך אפשר לעקוב אחרי העומס והביצועים של שרתי המודלים, כמו KVCache Utilization ו-Queue length.
  • מרכז הבקרה של מאזן העומסים: מציג מדדים ממאזן העומסים, כמו בקשות לשנייה, חביון של בקשות מקצה לקצה וקודי סטטוס של בקשות ותגובות. המדדים האלה עוזרים לכם להבין את הביצועים של שירות הבקשות מקצה לקצה ולזהות שגיאות.
  • מדדים של Data Center GPU Manager‏ (DCGM): מספק מדדים של DCGM, כמו הביצועים והניצול של מעבדים גרפיים של NVIDIA. אפשר להגדיר מדדי DCGM ב-Cloud Monitoring. מידע נוסף זמין במאמר איסוף מדדים של DCGM והצגתם.

הצגת מרכז הבקרה של GKE Inference Gateway

כדי לראות את מרכז הבקרה של GKE Inference Gateway, מבצעים את השלבים הבאים:

  1. נכנסים לדף Monitoring במסוף Cloud de Confiance .

    מעבר למעקב

  2. בחלונית הניווט, בוחרים באפשרות מרכזי בקרה.

  3. בקטע Integrations, בוחרים באפשרות GMP.

  4. בדף Cloud Monitoring Dashboard Templates, מחפשים את Gateway.

  5. צפייה בלוח הבקרה של GKE Inference Gateway.

אפשר גם לפעול לפי ההוראות שבמאמר לוח בקרה של מעקב.

הצגת לוחות בקרה של יכולת התבוננות במודלים של AI/ML

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

  1. במסוף Cloud de Confiance , נכנסים לדף Deployed Models.

    מעבר אל 'מודלים שנפרסו'

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

  3. בדף פרטי המודל, לוחצים על הכרטיסייה Observability כדי להציג את לוחות הבקרה הבאים. אם מופיעה בקשה, לוחצים על הפעלה כדי להפעיל את מרכז הבקרה.

    • בלוח הבקרה Infrastructure usage מוצגים מדדי השימוש.
    • בלוח הבקרה DCGM מוצגים מדדי DCGM.
    • אם אתם משתמשים ב-vLLM, לוח הבקרה Model performance זמין ומציג מדדים של ביצועי מודל vLLM.

הגדרת לוח בקרה לניראות (observability) של שרת המודל

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

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

  1. נכנסים לדף Monitoring במסוף Cloud de Confiance .

    מעבר למעקב

  2. בחלונית הניווט, בוחרים באפשרות מרכזי בקרה.

  3. בקטע Integrations (שילובים), בוחרים באפשרות GMP. יוצגו לוחות הבקרה של השילובים המתאימים.

    תצוגה של לוחות הבקרה של השילובים
    איור: לוחות בקרה של שילובים

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

הגדרת ההתראות של Cloud Monitoring

כדי להגדיר התראות Cloud Monitoring ל-GKE Inference Gateway:

  1. שומרים את קובץ המניפסט לדוגמה הבא בשם alerts.yaml ומשנים את ערכי הסף לפי הצורך:

    groups:
    - name: gateway-api-inference-extension
      rules:
      - alert: HighInferenceRequestLatencyP99
        annotations:
          title: 'High latency (P99) for model {{ $labels.model_name }}'
          description: 'The 99th percentile request duration for model {{ $labels.model_name }} and target model {{ $labels.target_model_name }} has been consistently above 10.0 seconds for 5 minutes.'
        expr: histogram_quantile(0.99, rate(inference_model_request_duration_seconds_bucket[5m])) > 10.0
        for: 5m
        labels:
          severity: 'warning'
      - alert: HighInferenceErrorRate
        annotations:
          title: 'High error rate for model {{ $labels.model_name }}'
          description: 'The error rate for model {{ $labels.model_name }} and target model {{ $labels.target_model_name }} has been consistently above 5% for 5 minutes.'
        expr: sum by (model_name) (rate(inference_model_request_error_total[5m])) / sum by (model_name) (rate(inference_model_request_total[5m])) > 0.05
        for: 5m
        labels:
          severity: 'critical'
          impact: 'availability'
      - alert: HighInferencePoolAvgQueueSize
        annotations:
          title: 'High average queue size for inference pool {{ $labels.name }}'
          description: 'The average number of requests pending in the queue for inference pool {{ $labels.name }} has been consistently above 50 for 5 minutes.'
        expr: inference_pool_average_queue_size > 50
        for: 5m
        labels:
          severity: 'critical'
          impact: 'performance'
      - alert: HighInferencePoolAvgKVCacheUtilization
        annotations:
          title: 'High KV cache utilization for inference pool {{ $labels.name }}'
          description: 'The average KV cache utilization for inference pool {{ $labels.name }} has been consistently above 90% for 5 minutes, indicating potential resource exhaustion.'
        expr: inference_pool_average_kv_cache_utilization > 0.9
        for: 5m
        labels:
          severity: 'critical'
          impact: 'resource_exhaustion'
    
  2. כדי ליצור כללי מדיניות להתראות, מריצים את הפקודה הבאה:

    gcloud monitoring policies migrate --policies-from-prometheus-alert-rules-yaml=alerts.yaml
    

    מדיניות חדשה לגבי התראות מופיעה בדף ההתראות.

שינוי ההתראות

רשימה מלאה של המדדים העדכניים זמינה במאגר GitHub של kubernetes-sigs/gateway-api-inference-extension. אפשר להוסיף התראות חדשות למניפסט באמצעות מדדים אחרים.

כדי לשנות את ההתראות לדוגמה, אפשר להשתמש בדוגמה הבאה:

  - alert: HighInferenceRequestLatencyP99
    annotations:
      title: 'High latency (P99) for model {{ $labels.model_name }}'
      description: 'The 99th percentile request duration for model {{ $labels.model_name }} and target model {{ $labels.target_model_name }} has been consistently above 10.0 seconds for 5 minutes.'
    expr: histogram_quantile(0.99, rate(inference_model_request_duration_seconds_bucket[5m])) > 10.0
    for: 5m
    labels:
      severity: 'warning'

ההתראה הזו מופעלת אם האחוזון ה-99 של משך הבקשה במהלך 5 דקות גבוה מ-10 שניות. אפשר לשנות את הסף בהתאם לדרישות שלכם בקטע expr של ההתראה.

הגדרת רישום ביומן עבור GKE Inference Gateway

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

כדי להגדיר רישום ביומן עבור GKE Inference Gateway, צריך להפעיל רישום ביומן של גישת HTTP לכל אחד מאובייקטי InferencePool.

  1. שומרים את קובץ המניפסט לדוגמה הבא בשם logging-backend-policy.yaml:

    apiVersion: networking.gke.io/v1
    kind: GCPBackendPolicy
    metadata:
      name: logging-backend-policy
      namespace: NAMESPACE_NAME
    spec:
      default:
        logging:
          enabled: true
          sampleRate: 500000
      targetRef:
        group: inference.networking.x-k8s.io
        kind: InferencePool
        name: INFERENCE_POOL_NAME
    

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

    • NAMESPACE_NAME: השם של מרחב השמות שבו InferencePool נפרס.
    • INFERENCE_POOL_NAME: השם של InferencePool.
  2. מחילים את קובץ המניפסט לדוגמה על האשכול:

    kubectl apply -f logging-backend-policy.yaml
    

אחרי שמחילים את המניפסט הזה, GKE Inference Gateway מאפשר יומני גישה ל-HTTP עבור InferencePool שצוין. אתם יכולים לצפות ביומנים האלה ב-Cloud Logging. היומנים כוללים מידע מפורט על כל בקשה ותגובה, כמו כתובת ה-URL של הבקשה, הכותרות, קוד הסטטוס של התגובה וזמן האחזור.

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

אתם יכולים להשתמש במדדים מבוססי-יומנים כדי לנתח את יומני איזון העומסים ולחלץ פרטים על שגיאות. כל סוג של GKE Gateway, כמו הסוגים gke-l7-global-external-managed ו-gke-l7-regional-internal-managed, מגובה על ידי מאזן עומסים שונה. מידע נוסף זמין במאמר בנושא יכולות של GatewayClass.

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

כדי ליצור מדד מבוסס-יומנים לצפייה בפרטי השגיאה:

  1. יוצרים קובץ JSON בשם error_detail_metric.json עם ההגדרה הבאה של LogMetric. ההגדרה הזו יוצרת מדד שמחלץ את השדה proxyStatus מיומני מאזן העומסים.

    {
      "description": "Metric to extract error details from load balancer logs.",
      "filter": "resource.type=\"MONITORED_RESOURCE\"",
      "metricDescriptor": {
        "metricKind": "DELTA",
        "valueType": "INT64",
        "labels": [
          {
            "key": "error_detail",
            "valueType": "STRING",
            "description": "The detailed error string from the load balancer."
          }
        ]
      },
      "labelExtractors": {
        "error_detail": "EXTRACT(jsonPayload.proxyStatus)"
      }
    }
    

    מחליפים את MONITORED_RESOURCE במשאב במעקב של מאזן העומסים.

  2. פותחים את Cloud Shell או את הטרמינל המקומי שבו מותקן ה-CLI של gcloud.

  3. כדי ליצור את המדד, מריצים את הפקודה gcloud logging metrics create עם הדגל --config-from-file:

    gcloud logging metrics create error_detail_metric \
        --config-from-file=error_detail_metric.json
    

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

מידע נוסף על יצירת התראות ממדדים מבוססי-יומנים זמין במאמר בנושא יצירת מדיניות התראות על מדד של מונה.

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

התאמה אוטומטית לעומס משנה את הקצאת המשאבים בתגובה לשינויים בעומס, ושומרת על הביצועים ועל יעילות המשאבים על ידי הוספה או הסרה דינמית של Pods על סמך הביקוש. ב-GKE Inference Gateway, זה כולל התאמה אוטומטית אופקית של Pods בכל InferencePool. התכונה GKE Horizontal Pod Autoscaler ‏ (HPA) משנה את גודל קבוצות ה-Pod באופן אוטומטי על סמך מדדים של שרת המודל, כמו KVCache Utilization. הגישה הזו עוזרת לוודא ששירות ההסקה מטפל בעומסי עבודה שונים ובנפחי שאילתות שונים, תוך ניהול יעיל של השימוש במשאבים.

כדי להגדיר מופעים של InferencePool כך שהם יתבצעו באופן אוטומטי בהתאם למדדים שנוצרו על ידי GKE Inference Gateway, מבצעים את השלבים הבאים:

  1. פורסים אובייקט PodMonitoring באשכול כדי לאסוף מדדים שנוצרו על ידי GKE Inference Gateway. מידע נוסף זמין במאמר בנושא הגדרת יכולת התבוננות.

  2. פורסים את המתאם של מדדים מותאמים אישית של Stackdriver כדי להעניק ל-HPA גישה למדדים:

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

      apiVersion: v1
      kind: Namespace
      metadata:
        name: custom-metrics
      ---
      apiVersion: v1
      kind: ServiceAccount
      metadata:
        name: custom-metrics-stackdriver-adapter
        namespace: custom-metrics
      ---
      apiVersion: rbac.authorization.k8s.io/v1
      kind: ClusterRoleBinding
      metadata:
        name: custom-metrics:system:auth-delegator
      roleRef:
        apiGroup: rbac.authorization.k8s.io
        kind: ClusterRole
        name: system:auth-delegator
      subjects:
      - kind: ServiceAccount
        name: custom-metrics-stackdriver-adapter
        namespace: custom-metrics
      ---
      apiVersion: rbac.authorization.k8s.io/v1
      kind: RoleBinding
      metadata:
        name: custom-metrics-auth-reader
        namespace: kube-system
      roleRef:
        apiGroup: rbac.authorization.k8s.io
        kind: Role
        name: extension-apiserver-authentication-reader
      subjects:
      - kind: ServiceAccount
        name: custom-metrics-stackdriver-adapter
        namespace: custom-metrics
      ---
      apiVersion: rbac.authorization.k8s.io/v1
      kind: ClusterRole
      metadata:
        name: custom-metrics-resource-reader
      rules:
      - apiGroups:
        - ""
        resources:
        - pods
        - nodes
        - nodes/stats
        verbs:
        - get
        - list
        - watch
      ---
      apiVersion: rbac.authorization.k8s.io/v1
      kind: ClusterRoleBinding
      metadata:
        name: custom-metrics-resource-reader
      roleRef:
        apiGroup: rbac.authorization.k8s.io
        kind: ClusterRole
        name: custom-metrics-resource-reader
      subjects:
      - kind: ServiceAccount
        name: custom-metrics-stackdriver-adapter
        namespace: custom-metrics
      ---
      apiVersion: apps/v1
      kind: Deployment
      metadata:
        name: custom-metrics-stackdriver-adapter
        labels:
          run: custom-metrics-stackdriver-adapter
          k8s-app: custom-metrics-stackdriver-adapter
      spec:
        replicas: 1
        selector:
          matchLabels:
            run: custom-metrics-stackdriver-adapter
            k8s-app: custom-metrics-stackdriver-adapter
        template:
          metadata:
            labels:
              run: custom-metrics-stackdriver-adapter
              k8s-app: custom-metrics-stackdriver-adapter
              kubernetes.io/cluster-service: "true"
          spec:
            serviceAccountName: custom-metrics-stackdriver-adapter
            containers:
            - image: gcr.io/gke-release/custom-metrics-stackdriver-adapter:v0.15.2-gke.1
              imagePullPolicy: Always
              name: pod-custom-metrics-stackdriver-adapter
              command:
              - /adapter
              - --use-new-resource-model=true
              - --fallback-for-container-metrics=true
              resources:
                limits:
                  cpu: 250m
                  memory: 200Mi
                requests:
                  cpu: 250m
                  memory: 200Mi
      ---
      apiVersion: v1
      kind: Service
      metadata:
        labels:
          run: custom-metrics-stackdriver-adapter
          k8s-app: custom-metrics-stackdriver-adapter
          kubernetes.io/cluster-service: 'true'
          kubernetes.io/name: Adapter
        name: custom-metrics-stackdriver-adapter
        namespace: custom-metrics
      spec:
        ports:
        - port: 443
          protocol: TCP
          targetPort: 443
        selector:
          run: custom-metrics-stackdriver-adapter
          k8s-app: custom-metrics-stackdriver-adapter
        type: ClusterIP
      ---
      apiVersion: apiregistration.k8s.io/v1
      kind: APIService
      metadata:
        name: v1beta1.custom.metrics.k8s.io
      spec:
        insecureSkipTLSVerify: true
        group: custom.metrics.k8s.io
        groupPriorityMinimum: 100
        versionPriority: 100
        service:
          name: custom-metrics-stackdriver-adapter
          namespace: custom-metrics
        version: v1beta1
      ---
      apiVersion: apiregistration.k8s.io/v1
      kind: APIService
      metadata:
        name: v1beta2.custom.metrics.k8s.io
      spec:
        insecureSkipTLSVerify: true
        group: custom.metrics.k8s.io
        groupPriorityMinimum: 100
        versionPriority: 200
        service:
          name: custom-metrics-stackdriver-adapter
          namespace: custom-metrics
        version: v1beta2
      ---
      apiVersion: apiregistration.k8s.io/v1
      kind: APIService
      metadata:
        name: v1beta1.external.metrics.k8s.io
      spec:
        insecureSkipTLSVerify: true
        group: external.metrics.k8s.io
        groupPriorityMinimum: 100
        versionPriority: 100
        service:
          name: custom-metrics-stackdriver-adapter
          namespace: custom-metrics
        version: v1beta1
      ---
      apiVersion: rbac.authorization.k8s.io/v1
      kind: ClusterRole
      metadata:
        name: external-metrics-reader
      rules:
      - apiGroups:
        - "external.metrics.k8s.io"
        resources:
        - "*"
        verbs:
        - list
        - get
        - watch
      ---
      apiVersion: rbac.authorization.k8s.io/v1
      kind: ClusterRoleBinding
      metadata:
        name: external-metrics-reader
      roleRef:
        apiGroup: rbac.authorization.k8s.io
        kind: ClusterRole
        name: external-metrics-reader
      subjects:
      - kind: ServiceAccount
        name: horizontal-pod-autoscaler
        namespace: kube-system
      
    2. מחילים את קובץ המניפסט לדוגמה על האשכול:

      kubectl apply -f adapter_new_resource_model.yaml
      
  3. כדי לתת למתאם הרשאות לקרוא מדדים מהפרויקט, מריצים את הפקודה הבאה:

    $ PROJECT_ID=PROJECT_ID
    $ 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 במזהה הפרויקט ב- Cloud de Confiance .

  4. לכל InferencePool, פורסים HPA אחד שדומה לזה:

    apiVersion: autoscaling/v2
    kind: HorizontalPodAutoscaler
    metadata:
      name: INFERENCE_POOL_NAME
      namespace: INFERENCE_POOL_NAMESPACE
    spec:
      scaleTargetRef:
        apiVersion: apps/v1
        kind: Deployment
        name: INFERENCE_POOL_NAME
      minReplicas: MIN_REPLICAS
      maxReplicas: MAX_REPLICAS
      metrics:
      - type: External
        external:
          metric:
            name: prometheus.googleapis.com|inference_pool_average_kv_cache_utilization|gauge
            selector:
              matchLabels:
                metric.labels.name: INFERENCE_POOL_NAME
                resource.labels.cluster: CLUSTER_NAME
                resource.labels.namespace: INFERENCE_POOL_NAMESPACE
          target:
            type: AverageValue
            averageValue: TARGET_VALUE
    

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

    • INFERENCE_POOL_NAME: השם של InferencePool.
    • INFERENCE_POOL_NAMESPACE: מרחב השמות של InferencePool.
    • CLUSTER_NAME: שם האשכול.
    • MIN_REPLICAS: זמינות המינימום של InferencePool (קיבולת בסיסית). ה-HPA שומר על מספר העותקים הזה כשהשימוש נמוך מסף היעד של ה-HPA. עבור עומסי עבודה עם זמינות גבוהה, צריך להגדיר ערך גבוה מ-1 כדי להבטיח זמינות רציפה במהלך שיבושים ב-Pod.
    • MAX_REPLICAS: הערך שמגביל את מספר המאיצים שצריך להקצות לעומסי העבודה שמארחים ב-InferencePool. ה-HPA לא יגדיל את מספר הרפליקות מעבר לערך הזה. במהלך תקופות של תנועה גבוהה, כדאי לעקוב אחרי מספר הרפליקות כדי לוודא שהערך בשדה MAX_REPLICAS מספק מספיק מרווח כדי שעומס העבודה יוכל להתרחב ולשמור על מאפייני הביצועים שנבחרו.
    • TARGET_VALUE: הערך שמייצג את יעד KV-Cache Utilization שנבחר לכל שרת מודל. זהו מספר בין 0 ל-100, והוא תלוי מאוד בשרת המודל, במודל, במאיץ ובמאפיינים של התנועה הנכנסת. אפשר לקבוע את ערך היעד הזה באופן ניסיוני באמצעות בדיקות עומס ושרטוט של גרף של קצב העברת נתונים לעומת זמן האחזור. בוחרים מהגרף שילוב של קצב העברת נתונים וחביון, ומשתמשים בערך KV-Cache Utilization המתאים כיעד של ה-HPA. חשוב לשנות את הערך הזה ולעקוב אחריו בקפידה כדי להשיג את התוצאות הרצויות מבחינת יחס המחיר לביצועים. אפשר להשתמש במדריך להתחלה מהירה של GKE Inference כדי לקבוע את הערך הזה באופן אוטומטי.

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