הגדרת משאבי Gateway באמצעות מדיניות

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

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

אפשר להתאים אישית את המשאבים של Gateway כך שיתאימו לדרישות של התשתית או האפליקציה שלכם, על ידי צירוף של מדיניות ל-Gateways, לשירותים או ל-ServiceImports. אחרי שמחילים או משנים מדיניות, בקר השער מעבד אותה ומגדיר מחדש באופן אוטומטי את משאב איזון העומסים הבסיסי. כך אין צורך למחוק או ליצור מחדש את משאבי Gateway,‏ Route או Service.

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

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

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

  • מפעילים את ממשק Google Kubernetes Engine API.
  • הפעלת Google Kubernetes Engine API
  • כדי להשתמש ב-CLI של Google Cloud למשימה הזו, צריך להתקין ואז לאתחל את ה-CLI של gcloud. אם התקנתם בעבר את ה-CLI של gcloud, מריצים את הפקודה gcloud components update כדי לקבל את הגרסה העדכנית. יכול להיות שגרסאות קודמות של ה-CLI של gcloud לא יתמכו בהרצת הפקודות שמופיעות במסמך הזה.
  • מוודאים שיש לכם אשכול קיים במצב Autopilot או במצב Standard. כדי ליצור אשכול חדש, אפשר לעיין במאמר בנושא יצירת אשכול Autopilot.

דרישות של GKE Gateway Controller

  • ‫Gateway API נתמך רק באשכולות VPC-native.
  • אם אתם משתמשים ב-GatewayClasses אזוריים או חוצי-אזורים, אתם צריכים להפעיל רשת משנה ל-proxy בלבד.
  • צריך להפעיל את התוסף HttpLoadBalancing באשכול.
  • אם אתם משתמשים ב-Istio, אתם צריכים לשדרג את Istio לאחת מהגרסאות הבאות:
    • גרסה 1.15.2 ואילך
    • ‫1.14.5 ואילך
    • ‫1.13.9 ואילך.
  • אם משתמשים ב-VPC משותף, צריך להקצות את התפקיד Compute Network User לחשבון השירות של GKE בפרויקט המארח של פרויקט השירות.

הגבלות

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

  • אפשר לצרף משאבי GCPGatewayPolicy רק ל-gateway.networking.k8s.io Gateway.

  • משאבי GCPGatewayPolicy צריכים להיות באותו מרחב שמות כמו שער היעד.

  • כשמשתמשים בשער של אשכול יחיד, משאבי GCPBackendPolicy ו-HealthCheckPolicy צריכים להפנות למשאב Service.

  • כשמשתמשים ב-Gateway מרובה אשכולות, ב-GCPBackendPolicy וב-HealthCheckPolicy, המשאבים צריכים להפנות למשאב ServiceImport.

  • בכל רגע נתון אפשר לצרף רק מדיניות אחת של GCPBackendPolicy לשירות. כשיוצרים שתי מדיניות GCPBackendPolicy שמכוונות לאותו Service או ServiceImport, המדיניות הישנה יותר מקבלת עדיפות והמדיניות השנייה לא מצורפת.

  • אין תמיכה במדיניות היררכית ב-GKE Gateway.

  • משאבי HealthCheckPolicy ו-GCPBackendPolicy צריכים להיות באותו מרחב שמות כמו משאב היעד Service או ServiceImport.

  • משאבי GCPBackendPolicy ו-HealthCheckPolicy בנויים כך שהם יכולים להפנות רק לשירות קצה עורפי אחד.

  • ‫GCPBackendPolicy לא תומך באפשרויות HEADER_FIELD או HTTP_COOKIE של זיקה לסשן (session affinity). כדי להגדיר זיקה לסשן (session affinity) HEADER_FIELD או HTTP_COOKIE, צריך להשתמש במשאב GCPTrafficDistributionPolicy.

  • אל תשתמשו באותו שירות backend בשערים מסוגים שונים של GatewayClass (כמו Global לעומת Regional,‏ Internal לעומת External או Managed לעומת Classic) אם השערים האלה דורשים הגדרות לא תואמות. לדוגמה, אי אפשר להחיל GCPBackendPolicy שהוגדר עם תכונות שלא נתמכות על ידי GatewayClass מסוג Classic על שירות שמשמש גם שער מסוג Classic. כדי לוודא שההגדרה נכונה, יוצרים שירות נפרד לכל שער שנדרשות בו הגדרות מדיניות שונות.

  • זיקה לסשן (session affinity) שמוגדרת באמצעות GCPTrafficDistributionPolicy נתמכת רק בשערי כניסה (Gateways) של אשכול יחיד.

  • הזיקה לסשן של GCPTrafficDistributionPolicy לא תואמת למשאבי InferencePool כי הם משתמשים באלגוריתמים ייעודיים של איזון עומסים מקומי.

  • ‫GCPTrafficDistributionPolicy לא תומך בהגדרת מדיניות של שיוך סשן או של איזון עומסים מקומי עבור מאזן העומסים הקלאסי של אפליקציות.

  • כשמשתמשים בשער עם אשכול יחיד, משאבי GCPBackendPolicy ו-HealthCheckPolicy צריכים להפנות למשאב Service או InferencePool.

  • כשמשתמשים בשער מרובה אשכולות, משאבי GCPBackendPolicy ו-HealthCheckPolicy צריכים להתייחס למשאב ServiceImport או GCPInferencePoolImport.

  • בכל זמן נתון, אפשר לצרף רק מדיניות GCPBackendPolicy אחת למשאב יעד יחיד (Service, ‏ ServiceImport, ‏ InferencePool או GCPInferencePoolImport). כשיוצרים כמה משאבי GCPBackendPolicy שמכוונים לאותו משאב, המדיניות הישנה ביותר מקבלת עדיפות והמדיניות החדשה יותר לא מצורפת.

  • משאבי HealthCheckPolicy ו-GCPBackendPolicy חייבים להיות באותו מרחב שמות כמו משאב היעד Service,‏ ServiceImport,‏ InferencePool או GCPInferencePoolImport.

  • משאבי GCPBackendPolicy ו-HealthCheckPolicy יכולים להיות מכוונים רק למשאב יחיד (כמו Service או InferencePool).

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

הגדרת גישה גלובלית לשער פנימי אזורי

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

כדי להפעיל גישה גלובלית באמצעות שער פנימי, צריך לצרף מדיניות למשאב של השער.

מניפסט ה-GCPGatewayPolicy הבא מאפשר גישה גלובלית לשער פנימי אזורי:

apiVersion: networking.gke.io/v1
kind: GCPGatewayPolicy
metadata:
  name: my-gateway-policy
  namespace: default
spec:
  default:
    # Enable global access for the regional internal Application Load Balancer.
    allowGlobalAccess: true
  targetRef:
    group: gateway.networking.k8s.io
    kind: Gateway
    name: my-gateway
במהלך חלון זמן לתחזוקה כדי למנוע זמן השבתה של האפליקציה.

הגדרת האזור בשער מרובה אשכולות

בקטע הזה מתוארת פונקציונליות שזמינה באשכולות GKE בגרסה 1.30.3-gke.1225000 ואילך.

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

כדי להגדיר אזור לשער מרובה אשכולות, משתמשים בשדה region ב-GCPGatewayPolicy. בדוגמה הבאה, השער מוגדר באזור us-central1:

apiVersion: networking.gke.io/v1
kind: GCPGatewayPolicy
metadata:
  name: my-gateway-policy
  namespace: default
spec:
  default:
    region: us-central1
  targetRef:
    group: gateway.networking.k8s.io
    kind: Gateway
    name: my-regional-gateway

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

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

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

חשוב ליצור מדיניות SSL לפני שמפנים למדיניות במשאב GCPGatewayPolicy.

קובץ המניפסט הבא של GCPGatewayPolicy מציין מדיניות אבטחה בשם gke-gateway-ssl-policy:

apiVersion: networking.gke.io/v1
kind: GCPGatewayPolicy
metadata:
  name: my-gateway-policy
  namespace: team1
spec:
  default:
    sslPolicy: gke-gateway-ssl-policy
  targetRef:
    group: gateway.networking.k8s.io
    kind: Gateway
    name: my-gateway

הגדרת בדיקות תקינות

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

כברירת מחדל, בשירותי קצה עורפי שמשתמשים בפרוטוקולי האפליקציה HTTP או kubernetes.io/h2c, בדיקת תקינות היא מסוג HTTP. לפרוטוקול HTTPS, בדיקת בריאות ברירת המחדל היא מסוג HTTPS. לפרוטוקול HTTP2, בדיקת בריאות ברירת המחדל היא מסוג HTTP2.

אפשר להשתמש ב-HealthCheckPolicy כדי לשלוט בהגדרות של בדיקת התקינות של מאזן העומסים. לכל סוג של בדיקת תקינות (http, ‏https, ‏grpc, ‏http2 ו-tcp) יש פרמטרים שאפשר להגדיר. Google Cloud יוצר בדיקת תקינות ייחודית לכל שירות קצה עורפי עבור כל שירות GKE.

כדי שמאזן העומסים יפעל בצורה תקינה, יכול להיות שתצטרכו להגדיר HealthCheckPolicy מותאם אישית למאזן העומסים אם נתיב בדיקת התקינות הוא לא הנתיב הרגיל '/'. ההגדרה הזו נדרשת גם אם הנתיב דורש כותרות מיוחדות או אם צריך לשנות את הפרמטרים של בדיקת התקינות. לדוגמה, אם נתיב הבקשה שמוגדר כברירת מחדל הוא '/', אבל אי אפשר לגשת לשירות שלכם בנתיב הבקשה הזה, ובמקום זאת נעשה שימוש בנתיב '/health' כדי לדווח על מצב השירות, אתם צריכים להגדיר את requestPath בהתאם ב-HealthCheckPolicy.

במניפסט HealthCheckPolicy הבא מוצגים כל השדות שזמינים כשמגדירים מדיניות של בדיקת תקינות:

שירות

# Health check configuration for the load balancer. For more information
# about these fields, see https://cloud.google.com/compute/docs/reference/rest/v1/healthChecks.
apiVersion: networking.gke.io/v1
kind: HealthCheckPolicy
metadata:
  name: lb-healthcheck
  namespace: lb-service-namespace
spec:
  default:
    checkIntervalSec: INTERVAL  # The default value is 15 seconds.
    timeoutSec: TIMEOUT
    healthyThreshold: HEALTHY_THRESHOLD
    unhealthyThreshold: UNHEALTHY_THRESHOLD
    logConfig:
      enabled: true
    config:
      type: PROTOCOL
      httpHealthCheck:
        portSpecification: PORT_SPECIFICATION
        port: PORT
        host: HOST
        requestPath: REQUEST_PATH
        response: RESPONSE
        proxyHeader: PROXY_HEADER
      httpsHealthCheck:
        portSpecification: PORT_SPECIFICATION
        port: PORT
        host: HOST
        requestPath: REQUEST_PATH
        response: RESPONSE
        proxyHeader: PROXY_HEADER
      grpcHealthCheck:
        grpcServiceName: GRPC_SERVICE_NAME
        portSpecification: PORT_SPECIFICATION
        port: PORT
      http2HealthCheck:
        portSpecification: PORT_SPECIFICATION
        port: PORT
        host: HOST
        requestPath: REQUEST_PATH
        response: RESPONSE
        proxyHeader: PROXY_HEADER
      tcpHealthCheck:
        portSpecification: PORT_SPECIFICATION
        port: PORT
        portName: PORT_NAME
        request: REQUEST
        response: RESPONSE
        proxyHeader: PROXY_HEADER
  # Attach to a Service in the cluster.
  targetRef:
    group: ""
    kind: Service
    name: lb-service

שירות אשכול מרובה

apiVersion: networking.gke.io/v1
kind: HealthCheckPolicy
metadata:
  name: lb-healthcheck
  namespace: lb-service-namespace
spec:
  # The default and config fields control the health check configuration for the
  # load balancer. For more information about these fields, see
  # https://cloud.google.com/compute/docs/reference/rest/v1/healthChecks.
  default:
    checkIntervalSec: INTERVAL
    timeoutSec: TIMEOUT
    healthyThreshold: HEALTHY_THRESHOLD
    unhealthyThreshold: UNHEALTHY_THRESHOLD
    logConfig:
      enabled: ENABLED
    config:
      type: PROTOCOL
      httpHealthCheck:
        portSpecification: PORT_SPECIFICATION
        port: PORT
        host: HOST
        requestPath: REQUEST_PATH
        response: RESPONSE
        proxyHeader: PROXY_HEADER
      httpsHealthCheck:
        portSpecification: PORT_SPECIFICATION
        port: PORT
        host: HOST
        requestPath: REQUEST_PATH
        response: RESPONSE
        proxyHeader: PROXY_HEADER
      grpcHealthCheck:
        grpcServiceName: GRPC_SERVICE_NAME
        portSpecification: PORT_SPECIFICATION
        port: PORT
      http2HealthCheck:
        portSpecification: PORT_SPECIFICATION
        port: PORT
        host: HOST
        requestPath: REQUEST_PATH
        response: RESPONSE
        proxyHeader: PROXY_HEADER
      tcpHealthCheck:
        portSpecification: PORT_SPECIFICATION
        port: PORT
        portName: PORT_NAME
        request: REQUEST
        response: RESPONSE
        proxyHeader: PROXY_HEADER
  # Attach to a multi-cluster Service by referencing the ServiceImport.
  targetRef:
    group: net.gke.io
    kind: ServiceImport
    name: lb-service

InferencePool

apiVersion: networking.gke.io/v1
kind: HealthCheckPolicy
metadata:
  name: lb-healthcheck
  namespace: lb-service-namespace
spec:
  default:
    checkIntervalSec: INTERVAL  # The default value is 15 seconds.
    timeoutSec: TIMEOUT
    healthyThreshold: HEALTHY_THRESHOLD
    unhealthyThreshold: UNHEALTHY_THRESHOLD
    logConfig:
      enabled: true
    config:
      type: PROTOCOL
      httpHealthCheck:
        portSpecification: PORT_SPECIFICATION
        port: PORT
        host: HOST
        requestPath: REQUEST_PATH
        response: RESPONSE
        proxyHeader: PROXY_HEADER
      httpsHealthCheck:
        portSpecification: PORT_SPECIFICATION
        port: PORT
        host: HOST
        requestPath: REQUEST_PATH
        response: RESPONSE
        proxyHeader: PROXY_HEADER
      grpcHealthCheck:
        grpcServiceName: GRPC_SERVICE_NAME
        portSpecification: PORT_SPECIFICATION
        port: PORT
      http2HealthCheck:
        portSpecification: PORT_SPECIFICATION
        port: PORT
        host: HOST
        requestPath: REQUEST_PATH
        response: RESPONSE
        proxyHeader: PROXY_HEADER
      tcpHealthCheck:
        portSpecification: PORT_SPECIFICATION
        port: PORT
        portName: PORT_NAME
        request: REQUEST
        response: RESPONSE
        proxyHeader: PROXY_HEADER
  # Attach to an InferencePool in the cluster.
  targetRef:
    group: inference.networking.k8s.io
    kind: InferencePool
    name: my-inference-pool

Multi-cluster InferencePool

apiVersion: networking.gke.io/v1
kind: HealthCheckPolicy
metadata:
  name: lb-healthcheck
  namespace: lb-service-namespace
spec:
  default:
    checkIntervalSec: INTERVAL
    timeoutSec: TIMEOUT
    healthyThreshold: HEALTHY_THRESHOLD
    unhealthyThreshold: UNHEALTHY_THRESHOLD
    logConfig:
      enabled: true
    config:
      type: PROTOCOL
      httpHealthCheck:
        portSpecification: PORT_SPECIFICATION
        port: PORT
        host: HOST
        requestPath: REQUEST_PATH
        response: RESPONSE
        proxyHeader: PROXY_HEADER
      httpsHealthCheck:
        portSpecification: PORT_SPECIFICATION
        port: PORT
        host: HOST
        requestPath: REQUEST_PATH
        response: RESPONSE
        proxyHeader: PROXY_HEADER
      grpcHealthCheck:
        grpcServiceName: GRPC_SERVICE_NAME
        portSpecification: PORT_SPECIFICATION
        port: PORT
      http2HealthCheck:
        portSpecification: PORT_SPECIFICATION
        port: PORT
        host: HOST
        requestPath: REQUEST_PATH
        response: RESPONSE
        proxyHeader: PROXY_HEADER
      tcpHealthCheck:
        portSpecification: PORT_SPECIFICATION
        port: PORT
        portName: PORT_NAME
        request: REQUEST
        response: RESPONSE
        proxyHeader: PROXY_HEADER
  # Attach to a multi-cluster InferencePool.
  targetRef:
    group: networking.gke.io
    kind: GCPInferencePoolImport
    name: my-inference-pool-import

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

  • INTERVAL: מציין את check-interval, בשניות, לכל בודק בדיקות תקינות. זהו הזמן שחלף מתחילת הבדיקה של בודק אחד ועד לתחילת הבדיקה הבאה שלו. אם לא מציינים את הפרמטר הזה, Google Cloud ברירת המחדל היא 15 שניות אם לא מציינים HealthCheckPolicy, ו-5 שניות אם מציינים HealthCheckPolicy בלי ערך checkIntervalSec. מידע נוסף זמין במאמר בנושא בדיקות מרובות ותדירות.
  • TIMEOUT: מציין את משך הזמן שבוGoogle Cloud ממתין לתגובה לבקשה לבדיקת תקינות (probe). הערך של TIMEOUT חייב להיות קטן מהערך של INTERVAL או שווה לו. היחידות הן שניות. כל בדיקה דורשת קוד תגובה HTTP 200 (OK) לפני פסק הזמן של הבדיקה.
  • HEALTHY_THRESHOLD and UNHEALTHY_THRESHOLD: מציינים את מספר הניסיונות הרצופים ליצירת חיבור שצריכים להצליח או להיכשל, לפחות בבודק אחד, כדי לשנות את מצב התקינות ממצב תקין למצב לא תקין או ממצב לא תקין למצב תקין. אם משמיטים אחד מהפרמטרים האלה, ברירת Google Cloud המחדל היא 2.
  • PROTOCOL: מציין פרוטוקול שבו משתמשות מערכות בדיקה כדי לבדוק את תקינות השרת. מידע נוסף זמין במאמרים קריטריונים להצלחה עבור HTTP,‏ HTTPS ו-HTTP/2,‏ קריטריונים להצלחה עבור gRPC וקריטריונים להצלחה עבור TCP. חובה לכלול את הפרמטר הזה.
  • ENABLED: מציין אם הרישום ביומן מופעל או מושבת.
  • PORT_SPECIFICATION: מציין אם בדיקת תקינות משתמשת ביציאה קבועה (USE_FIXED_PORT), ביציאה עם שם (USE_NAMED_PORT) או ביציאת שרת (USE_SERVING_PORT). אם לא מצוין, בדיקת התקינות פועלת בהתאם להתנהגות שצוינה בשדה port. אם לא מציינים את port, ערך ברירת המחדל של השדה הזה הוא USE_SERVING_PORT.
  • PORT: HealthCheckPolicy תומך רק בציון היציאה של בדיקת התקינות של מאזן העומסים באמצעות מספר יציאה. אם לא מציינים את הפרמטר הזה, Google Cloud ברירת המחדל היא 80. מאזן העומסים שולח בדיקות לכתובת ה-IP של ה-Pod ישירות, ולכן צריך לבחור יציאה שתואמת ל-containerPort של קבוצות Pod שמספקות שירות, גם אם containerPort מפנה ל-targetPort של השירות. אתם לא מוגבלים ל-containerPorts שאליו מתייחס targetPort של שירות.
  • HOST: הערך של כותרת המארח בבקשת בדיקת תקינות. הערך הזה מוגדר לפי RFC 1123 , אבל אי אפשר להשתמש בכתובות IP מספריות. אם לא מציינים ערך או משאירים את השדה הזה ריק, כברירת מחדל הערך יהיה כתובת ה-IP של בדיקת תקינות.
  • REQUEST: מציין את נתוני האפליקציה שיישלחו אחרי יצירת חיבור TCP. אם לא מציינים ערך, ברירת המחדל היא ערך ריק. אם גם הבקשה וגם התשובה ריקות, הקישור שנוצר מעיד על תקינות. הנתונים בבקשה יכולים להיות רק בפורמט ASCII.
  • REQUEST_PATH: מציין את נתיב הבקשה של בקשת בדיקת תקינות. אם לא מציינים ערך או משאירים את השדה ריק, ברירת המחדל היא /.
  • RESPONSE: מציין את הבייטים שצריך להתאים לתחילת נתוני התגובה. אם לא מציינים ערך או משאירים את השדה ריק, מערכת GKE מפרשת כל תגובה כהתקינה. נתוני התגובה יכולים להיות רק ASCII.
  • PROXY_HEADER: מציין את סוג הכותרת של שרת ה-proxy. אפשר להשתמש ב-NONE או ב-PROXY_V1. ברירת המחדל היא NONE.
  • GRPC_SERVICE_NAME: שם אופציונלי של שירות gRPC. אם משמיטים את השדה הזה, המערכת מניחה שרוצים לציין את כל השירותים.

מידע נוסף על השדות של HealthCheckPolicy זמין healthChecks במאמר בנושא הפניה.

הגדרת מדיניות אבטחה לקצה העורפי ב-Cloud Armor כדי לאבטח את שירותי הקצה העורפי

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

כדי להגדיר את מדיניות האבטחה של הקצה העורפי ב-Cloud Armor, מוסיפים את שם מדיניות האבטחה אל GCPBackendPolicy כדי לאבטח את שירותי הקצה העורפי. כברירת מחדל, בשער לא מוגדרים ולא מצורפים כללי מדיניות אבטחה של Cloud Armor לשרת העורפי.

חשוב לוודא שיצרתם מדיניות אבטחה של קצה עורפי ב-Cloud Armor לפני שאתם מפנים למדיניות ב-GCPBackendPolicy. אם מפעילים שער אזורי, צריך ליצור כללי מדיניות אזוריים לאבטחת העורף (backend) ב-Cloud Armor.

במניפסט הבא של GCPBackendPolicy מוגדרת מדיניות אבטחה של קצה עורפי בשם example-security-policy:

שירות

apiVersion: networking.gke.io/v1
kind: GCPBackendPolicy
metadata:
  name: my-backend-policy
  namespace: lb-service-namespace
spec:
  default:
    # Apply a Cloud Armor security policy.
    securityPolicy: example-security-policy
  # Attach to a Service in the cluster.
  targetRef:
    group: ""
    kind: Service
    name: lb-service

שירות אשכול מרובה

apiVersion: networking.gke.io/v1
kind: GCPBackendPolicy
metadata:
  name: my-backend-policy
  namespace: lb-service-namespace
spec:
  default:
    # Apply a Cloud Armor security policy.
    securityPolicy: example-security-policy
  # Attach to a multi-cluster Service by referencing the ServiceImport.
  targetRef:
    group: net.gke.io
    kind: ServiceImport
    name: lb-service

InferencePool

apiVersion: networking.gke.io/v1
kind: GCPBackendPolicy
metadata:
  name: my-backend-policy
  namespace: lb-service-namespace
spec:
  default:
    securityPolicy: example-security-policy
  # Attach to an InferencePool in the cluster.
  targetRef:
    group: inference.networking.k8s.io
    kind: InferencePool
    name: my-inference-pool

Multi-cluster InferencePool

apiVersion: networking.gke.io/v1
kind: GCPBackendPolicy
metadata:
  name: my-backend-policy
  namespace: lb-service-namespace
spec:
  default:
    securityPolicy: example-security-policy
  # Attach to a multi-cluster InferencePool.
  targetRef:
    group: networking.gke.io
    kind: GCPInferencePoolImport
    name: my-inference-pool-import

הגדרת IAP

שרת proxy לאימות זהויות (IAP) אוכף מדיניות של בקרת גישה בשירותי בק-אנד שמשויכים ל-HTTPRoute. האכיפה הזו מאפשרת רק למשתמשים מאומתים או לאפליקציות עם תפקיד מתאים בניהול הזהויות והרשאות הגישה (IAM) לגשת לשירותי הקצה העורפי האלה.

כברירת מחדל, לא מוחל IAP על השירותים לקצה העורפי, ולכן צריך להגדיר IAP באופן מפורש ב-GCPBackendPolicy.

כדי להגדיר את IAP עם Gateway:

  1. מקבלים את מזהה הלקוח ואת סוד הלקוח של לקוח ה-OAuth. הסוד של הלקוח זמין רק כשיוצרים את לקוח OAuth. מידע נוסף מופיע במאמר בנושא ניהול לקוחות OAuth.
  2. הפעלת IAP ל-GKE

    לא צריך ליצור BackendConfig, כי BackendConfig הוא משאב הגדרות של Ingress.

  3. כדי לציין מדיניות IAP שמתייחסת ל-Secret:

    1. שומרים את מניפסט ה-GCPBackendPolicy הבא בשם backend-policy.yaml:

      שירות

      apiVersion: networking.gke.io/v1
      kind: GCPBackendPolicy
      metadata:
        name: backend-policy
      spec:
        default:
          # IAP OAuth2 settings. For more information about these fields,
          # see https://cloud.google.com/iap/docs/reference/rest/v1/IapSettings#oauth2.
          iap:
            enabled: true
            oauth2ClientSecret:
              name: CLIENT_SECRET
            clientID: CLIENT_ID
        # Attach to a Service in the cluster.
        targetRef:
          group: ""
          kind: Service
          name: SERVICE_NAME
      

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

      • CLIENT_SECRET: סוד הלקוח ב-OAuth.
      • CLIENT_ID: מזהה הלקוח ב-OAuth.
      • SERVICE_NAME: השם של השירות שמגדירים כמטרה ב-GCPBackendPolicy.

      שירות אשכול מרובה

      apiVersion: networking.gke.io/v1
      kind: GCPBackendPolicy
      metadata:
        name: backend-policy
      spec:
        default:
          # IAP OAuth2 settings. For more information about these fields,
          # see https://cloud.google.com/iap/docs/reference/rest/v1/IapSettings#oauth2.
          iap:
            enabled: true
            oauth2ClientSecret:
              name: CLIENT_SECRET
            clientID: CLIENT_ID
        # Attach to a multi-cluster Service by referencing the ServiceImport.
        targetRef:
          group: net.gke.io
          kind: ServiceImport
          name: SERVICEIMPORT_NAME
      

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

      • CLIENT_SECRET: סוד הלקוח ב-OAuth.
      • CLIENT_ID: מזהה הלקוח ב-OAuth.
      • SERVICEIMPORT_NAME: השם של ServiceImport שאליו רוצים לטרגט ב-GCPBackendPolicy.
    2. החלת המניפסט backend-policy.yaml:

      kubectl apply -f backend-policy.yaml
      
  4. אימות ההגדרה:

    1. מוודאים שהמדיניות הוחלה אחרי שיוצרים את GCPBackendPolicy באמצעות IAP:

      kubectl get gcpbackendpolicy
      

      הפלט אמור להיראות כך:

      NAME             AGE
      backend-policy   45m
      
    2. כדי לקבל פרטים נוספים, משתמשים בפקודה describe:

      kubectl describe gcpbackendpolicy
      

      הפלט אמור להיראות כך:

      Name:         backend-policy
      Namespace:    default
      Labels:       <none>
      Annotations:  <none>
      API Version:  networking.gke.io/v1
      Kind:         GCPBackendPolicy
      Metadata:
        Creation Timestamp:  2023-05-27T06:45:32Z
        Generation:          2
        Resource Version:    19780077
        UID:                 f4f60a3b-4bb2-4e12-8748-d3b310d9c8e5
      Spec:
        Default:
          Iap:
            Client ID:  441323991697-luotsrnpboij65ebfr13hlcpm5a4heke.apps.googleusercontent.com
            Enabled:    true
            oauth2ClientSecret:
              Name:  my-iap-secret
        Target Ref:
          Group:
          Kind:   Service
          Name:   lb-service
      Status:
        Conditions:
          Last Transition Time:  2023-05-27T06:48:25Z
          Message:
          Reason:                Attached
          Status:                True
          Type:                  Attached
      Events:
        Type     Reason  Age                 From                   Message
        ----     ------  ----                ----                   -------
        Normal   ADD     46m                 sc-gateway-controller  default/backend-policy
        Normal   SYNC    44s (x15 over 43m)  sc-gateway-controller  Application of GCPBackendPolicy "default/backend-policy" was a success
      

הגדרת זמן קצוב לתפוגה של שירות לקצה העורפי

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

במניפסט הבא של GCPBackendPolicy מוגדר זמן קצוב לתפוגה של שירות קצה עורפי של 40 שניות. ברירת המחדל של השדה timeoutSec היא 30 שניות.

שירות

apiVersion: networking.gke.io/v1
kind: GCPBackendPolicy
metadata:
  name: my-backend-policy
  namespace: lb-service-namespace
spec:
  default:
    # Backend service timeout, in seconds, for the load balancer. The default
    # value is 30.
    timeoutSec: 40
  # Attach to a Service in the cluster.
  targetRef:
    group: ""
    kind: Service
    name: lb-service

שירות אשכול מרובה

apiVersion: networking.gke.io/v1
kind: GCPBackendPolicy
metadata:
  name: my-backend-policy
  namespace: lb-service-namespace
spec:
  default:
    timeoutSec: 40
  # Attach to a multi-cluster Service by referencing the ServiceImport.
  targetRef:
    group: net.gke.io
    kind: ServiceImport
    name: lb-service

InferencePool

apiVersion: networking.gke.io/v1
kind: GCPBackendPolicy
metadata:
  name: my-backend-policy
  namespace: lb-service-namespace
spec:
  default:
    timeoutSec: 40
  # Attach to an InferencePool in the cluster.
  targetRef:
    group: inference.networking.k8s.io
    kind: InferencePool
    name: my-inference-pool

Multi-cluster InferencePool

apiVersion: networking.gke.io/v1
kind: GCPBackendPolicy
metadata:
  name: my-backend-policy
  namespace: lb-service-namespace
spec:
  default:
    timeoutSec: 40
  # Attach to a multi-cluster InferencePool.
  targetRef:
    group: networking.gke.io
    kind: GCPInferencePoolImport
    name: my-inference-pool-import

הגדרת בחירת קצה עורפי באמצעות GCPBackendPolicy

מצב האיזון CUSTOM_METRICS ב-GCPBackendPolicy מאפשר להגדיר מדדים מותאמים אישית ספציפיים שמשפיעים על האופן שבו שירותי ה-Backend של מאזני העומסים מחלקים את התנועה. מצב האיזון הזה מאפשר איזון עומסים על סמך מדדים מותאמים אישית שאתם מגדירים, ושמדווחים על ידי העורפים של האפליקציה.

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

המערך customMetrics[], בשדה backends[], מכיל את השדות הבאים:

  • name: מציין את השם שהמשתמש הגדיר למדד המותאם אישית.
  • maxUtilization: הגדרת יעד או ניצול מקסימלי למדד הזה. הטווח התקין הוא [0, 100].
  • dryRun: שדה בוליאני. אם הערך הוא true, נתוני המדדים מדווחים ל-Cloud Monitoring אבל לא משפיעים על החלטות איזון העומסים.

דוגמה

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

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

    kind: GCPBackendPolicy
    apiVersion: networking.gke.io/v1
    metadata:
      name: my-backend-policy
      namespace: team-awesome
    spec:
      # Attach to the super-service Service.
      targetRef:
        kind: Service
        name: super-service
      default:
        backends:
        # Configuration for all locations.
        - location: "*"
          # Use the rate balancing mode for the load balancer.
          balancingMode: RATE
          # Maximum number of requests per second for each endpoint.
          maxRatePerEndpoint: 9000
        # Configuration for us-central1-a
        - location: us-central1-a
          # maxRatePerEndpoint: 9000 inherited from the * configuration.
          # Use the custom metrics balancing mode for the load balancer.
          balancingMode: CUSTOM_METRICS
          # Configure the custom metrics for the load balancer to use.
          customMetrics:
          - name: gpu-load
            maxUtilizationPercent: 100 # value ranges from 0 to 100 and maps to the floating point range [0.0, 1.0]
            dryRun: false
    
  2. מחילים את המניפסט על האשכול:

    kubectl apply -f my-backend-policy.yaml
    

מאזן העומסים מחלק את התנועה על סמך מצב האיזון RATE והמדד המותאם אישית gpu-load.

הגדרת ניתוב ברמת נקודת הקצה באמצעות GCPTrafficDistributionPolicy

‫GCPTrafficDistributionPolicy API ב-Google Kubernetes Engine (GKE) Gateway מספק יכולות מתקדמות לניהול תנועת גולשים, שמאפשרות שליטה מדויקת באופן שבו תנועת הגולשים מופצת ל-pods של האפליקציה. המשאב המאוחד הזה, שפועל באופן מקורי ב-GKE, מפשט את הניהול של אלגוריתמים לאיזון עומסים והגדרות של זיקה לסשן (session affinity).

ה-GCPTrafficDistributionPolicy מאפשר לכם להגדיר:

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

    • WEIGHTED_ROUND_ROBIN: כשבוחרים באלגוריתם הזה, מאזן העומסים משתמש במדדים מותאמים אישית כדי לחשב משקלים ולחלק את התנועה על סמך המדדים המדווחים האלה. המערך customMetrics[] בהגדרות של GCPTrafficDistributionPolicy כולל את השדות הבאים:

      • name: מציין את השם שהמשתמש הגדיר למדד המותאם אישית.
      • dryRun: אם true, נתוני המדדים מדווחים ל-Cloud Monitoring אבל לא משפיעים על איזון העומסים.
  • RING_HASH: האלגוריתם הזה מועיל לשירותים שרגישים לביצועי מטמון. הוא משתמש בגיבוב עקבי כדי לצמצם את המיפוי מחדש של הבקשות כשמוסיפים או מסירים תרמילים של קצה עורפי, וכך עוזר לשמור על יציבות במהלך אירועי שינוי גודל. הגדרת השדה minimumHashRingSize מאפשרת חלוקת עומס מפורטת יותר.

  • זיקה לסשן: עוזרת להבטיח שבקשות מאותו לקוח ינותבו באופן עקבי לאותו Pod של קצה עורפי. זה חשוב במיוחד לעומסי עבודה עם שמירת מצב, כמו עגלות קניות במסחר אלקטרוני או סשנים של משחקים. שער GKE משתמש ב-GCPTrafficDistributionPolicy כדי לתמוך בכל סוגי הזיקה לסשן שזמינים ב Google Cloud מופעים של מאזן עומסים של אפליקציות, כולל STRONG_COOKIE_AFFINITY,‏ HEADER_FIELD,‏ HTTP_COOKIE,‏ GENERATED_COOKIE ו-CLIENT_IP.

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

דוגמה

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

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

    apiVersion: networking.gke.io/v1
    kind: GCPTrafficDistributionPolicy
    metadata:
      name: echoserver-v2
      namespace: team1
    spec:
      targetRefs:
      # Attach to the echoserver-v2 Service in the cluster.
      - kind: Service
        group: ""
        name: echoserver-v2
      default:
        # Use custom metrics to distribute traffic across endpoints.
        localityLbAlgorithm: WEIGHTED_ROUND_ROBIN
        # Configure metrics from an ORCA load report to use for traffic
        # distribution.
        customMetrics:
        - name: orca.named_metrics.bescm11
          dryRun: false
        - name: orca.named_metrics.bescm12
          dryRun: true
    
  2. מחילים את המניפסט על האשכול:

    kubectl apply -f GCPTrafficDistributionPolicy.yaml
    

מאזן העומסים מפזר את התנועה לנקודות קצה על סמך האלגוריתם WEIGHTED_ROUND_ROBIN והמדדים המותאמים אישית שצוינו.

הגדרת הגודל של טבעת הגיבוב

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

apiVersion: networking.gke.io/v1
kind: GCPTrafficDistributionPolicy
metadata:
  name: ring-hash-policy
  namespace: default
spec:
  default:
    localityLbAlgorithm: RING_HASH
    # Defaults to 1024. Larger ring sizes result in more granular
    # load distributions. Supported range is 1 to 2048.
    minimumHashRingSize: 1024
  targetRefs:
  -   group: ""
    kind: Service
    name: my-cache-heavy-service

הגדרת זיקה לסשן

כדי לוודא שבקשות מאותו לקוח מנותבות באופן עקבי לאותו Pod של קצה עורפי, צריך להגדיר זיקה לסשן (session affinity).

הגדרת זיקה לסשן באמצעות GCPTrafficDistributionPolicy (ברירת מחדל)

סוגי הזיקה לסשן שמתוארים בקטע הזה דורשים את הגרסאות המינימליות הבאות של GKE:

  • CLIENT_IP,‏ HEADER_FIELD,‏ GENERATED_COOKIE ו-HTTP_COOKIE: גרסה 1.35.2-gke.1269001 ואילך.
  • STRONG_COOKIE_AFFINITY: גרסה ‎1.36.3-gke.1767000 ואילך.

שער GKE תומך בכל סוגי הזיקה לסשן (session affinity) באמצעות המשאב GCPTrafficDistributionPolicy. במקור המידע הזה מוסבר איך להגדיר שליטה מפורטת יותר, כמו ניתוב שמבוסס על כותרות HTTP או קובצי Cookie מותאמים אישית. השיטה המומלצת להגדרת זיקה לסשן (session affinity) היא באמצעות GCPTrafficDistributionPolicy, והיא מוגדרת כברירת מחדל.

בטבלה הבאה מתוארים סוגי הקרבה שנתמכים כשמשתמשים ב-GCPTrafficDistributionPolicy:

סוג התחום המשותף תיאור
STRONG_COOKIE_AFFINITY שמירת נתונים של סשן מבוסס-קובצי Cookie. עוזר להבטיח שמירה על סשנים פעילים לאורך זמן כשמגדילים את מספר האירועים או משנים את גודל מאגר ה-Pods. חובה להגדיר את השדה cookie.name, ואפשר להגדיר גם את השדות cookie.path ו-cookie.ttl. אפשר להשתמש בכל הגדרה של localityLbAlgorithm (ערך ברירת המחדל הוא ROUND_ROBIN).
HTTP_COOKIE זיקה שמבוססת על קובץ Cookie‏ HTTP. כשמאזן העומסים מגיב לבקשה הראשונה, הוא יוצר קובץ Cookie ומספק אותו בכותרת התגובה Set-Cookie. בבקשות הבאות, הלקוח מחזיר את קובץ ה-Cookie שסופק על ידי מאזן העומסים, ומאזן העומסים משתמש בו כדי לנתב את הבקשות באופן עקבי לאותם פודים. חובה להגדיר את השדה cookie.name, ואפשר להגדיר גם את השדות cookie.path ו-cookie.ttl. השדה localityLbAlgorithm צריך להיות מוגדר לערך MAGLEV או RING_HASH.
GENERATED_COOKIE מאזן העומסים יוצר קובץ Cookie כדי לעקוב אחרי הסשן. שם קובץ ה-Cookie הוא GCLB עבור מאזני עומסים גלובליים חיצוניים של אפליקציות, ו-GCILB עבור מאזני עומסים פנימיים אזוריים של אפליקציות ומאזני עומסים חיצוניים אזוריים של אפליקציות. נתיב קובץ ה-Cookie הוא /. אפשר להגדיר את השדה cookie.ttl עד שבועיים לכל היותר. אי אפשר להגדיר את השדות cookie.name ו-cookie.path בסוג הזה. כדי לעשות זאת, צריך להגדיר את השדה localityLbAlgorithm לערך MAGLEV או RING_HASH.
HEADER_FIELD זיקה שמבוססת על כותרת HTTP ספציפית. השדה localityLbAlgorithm צריך להיות מוגדר לערך MAGLEV או RING_HASH.
CLIENT_IP תחום עניין משותף על סמך כתובת ה-IP של הלקוח. השדה localityLbAlgorithm צריך להיות מוגדר לערך MAGLEV או RING_HASH.
NONE השבתת זיקה לסשן.

בדוגמאות הבאות אפשר לראות איך מגדירים את GCPTrafficDistributionPolicy לפי קטגוריית זיקה לסשן: זיקה לסשן מבוססת-קובץ Cookie, זיקה לסשן מבוססת-כותרת וזיקה לסשן מבוססת-כתובת IP של לקוח.

כדי להחיל על האשכול את אחת מההגדרות הבאות של זיקה לסשן (session affinity), מבצעים את הפעולות הבאות:

  1. שומרים את קובץ המניפסט שנבחר בשם policy.yaml.
  2. מחילים את המניפסט על האשכול:

    kubectl apply -f policy.yaml
    

זיקה לסשן שמבוססת על קובצי Cookie כוללת את סוגי הזיקה STRONG_COOKIE_AFFINITY, HTTP_COOKIE ו-GENERATED_COOKIE.

העדפה לקובצי Cookie עם שמירת מצב (STRONG_COOKIE_AFFINITY)

התכונה 'שמירת זיקה לקובצי Cookie עם שמירת מצב' (STRONG_COOKIE_AFFINITY) מספקת שמירת מצב של סשנים, כך שהזיקה נשמרת גם במהלך אירועי שינוי גודל של ה-Backend.

apiVersion: networking.gke.io/v1
kind: GCPTrafficDistributionPolicy
metadata:
  name: strong-cookie-affinity-policy
  namespace: default
spec:
  default:
    sessionAffinity:
      type: STRONG_COOKIE_AFFINITY
      cookie:
        name: "GKE_STATEFUL_SESSION"
        path: "/"
        ttl: "24h"
  targetRefs:
  - group: ""
    kind: Service
    name: my-stateful-service

שיוך (Affinity) של קובצי Cookie מסוג HTTP ‏(HTTP_COOKIE)

הזיקה HTTP_COOKIE מבוססת על קובץ Cookie ספציפי שמוחזר בכותרת Set-Cookie. כדי להשתמש בסוגים אחרים של זיקה לסשן מלבד NONE ו-STRONG_COOKIE_AFFINITY, צריך להגדיר את השדה localityLbAlgorithm ל-MAGLEV או ל-RING_HASH.

apiVersion: networking.gke.io/v1
kind: GCPTrafficDistributionPolicy
metadata:
  name: http-cookie-affinity-policy
  namespace: default
spec:
  default:
    sessionAffinity:
      type: HTTP_COOKIE
      cookie:
        name: "my-app-session-id"
        path: "/"
        ttl: "3600s"
    # HTTP_COOKIE affinity requires localityLbAlgorithm to be MAGLEV or RING_HASH.
    localityLbAlgorithm: MAGLEV
  targetRefs:
  - group: ""
    kind: Service
    name: my-stateful-service

זיקה לקובץ Cookie שנוצר (GENERATED_COOKIE)

סוג הזיקה GENERATED_COOKIE מאפשר למאזן העומסים ליצור ולתת שם לקובץ Cookie זמני באופן אוטומטי. אפשר גם להגדיר את הערך של השדה cookie.ttl עד שבועיים (336h).

apiVersion: networking.gke.io/v1
kind: GCPTrafficDistributionPolicy
metadata:
  name: generated-cookie-affinity-policy
  namespace: default
spec:
  default:
    sessionAffinity:
      type: GENERATED_COOKIE
      cookie:
        ttl: "2h30m"
    # GENERATED_COOKIE affinity requires localityLbAlgorithm to be MAGLEV or RING_HASH.
    localityLbAlgorithm: MAGLEV
  targetRefs:
  - group: ""
    kind: Service
    name: my-stateful-service

ההתנהגות של TTL אפס עבור זיקה לסשן שמבוססת על קובצי Cookie כוללת את הפעולות הבאות:

  • לכל ההעדפות של סשנים שמבוססות על קובצי Cookie ‏ (STRONG_COOKIE_AFFINITY,‏ HTTP_COOKIE ו-GENERATED_COOKIE) יש מאפיין ttl.

  • ערך TTL של אפס שניות אומר שמאזן העומסים לא מקצה מאפיין Expires לקובץ ה-Cookie. במקרה הזה, הלקוח מתייחס לקובץ ה-Cookie כקובץ Cookie של סשן. ההגדרה של סשן משתנה בהתאם ללקוח:

    • חלק מהלקוחות, כמו דפדפני אינטרנט, שומרים את קובץ ה-Cookie למשך כל סשן הגלישה. הגישה הזו מאפשרת לקובץ ה-Cookie להופיע בעקביות בכמה בקשות עד שהאפליקציה נסגרת.
    • לקוחות אחרים מתייחסים לסשן כאל בקשת HTTP אחת, ומוחקים את קובץ ה-Cookie מיד אחרי שהסשן מסתיים.

זיקה לסשן מבוססת-כותרת

סוג האפליקציה HEADER_FIELD מפנה תנועה על סמך כותרת HTTP ספציפית לתרחישים כמו בדיקות A/B או ניתוב לקוח מיוחד שבהם קובץ Cookie לא מתאים. כדי להשתמש בסוגים אחרים של זיקה לסשן מלבד NONE ו-STRONG_COOKIE_AFFINITY, צריך להגדיר את השדה localityLbAlgorithm ל-MAGLEV או ל-RING_HASH. בניגוד ל-ROUND_ROBIN שמוגדר כברירת מחדל, האלגוריתמים האלה תומכים בגיבוב עקבי שמבוסס על שדות בהתאמה אישית, כמו כותרות HTTP.

apiVersion: networking.gke.io/v1
kind: GCPTrafficDistributionPolicy
metadata:
  name: header-affinity-policy
  namespace: default
spec:
  default:
    sessionAffinity:
      type: HEADER_FIELD
      httpHeaderName: "X-User-Group-ID"
    localityLbAlgorithm: MAGLEV
  targetRefs:
  - group: ""
    kind: Service
    name: SERVICE_NAME

זיקה לסשן שמבוססת על כתובת ה-IP של הלקוח

סוג האפיניות CLIENT_IP מנתב תנועה מכתובת IP ספציפית של לקוח לאותו Pod של קצה עורפי ככל האפשר. כדי להשתמש בסוגים אחרים של זיקה לסשן חוץ מ-NONE ו-STRONG_COOKIE_AFFINITY, צריך להגדיר את השדה localityLbAlgorithm ל-MAGLEV או ל-RING_HASH.

apiVersion: networking.gke.io/v1
kind: GCPTrafficDistributionPolicy
metadata:
  name: client-ip-affinity-policy
  namespace: default
spec:
  default:
    sessionAffinity:
      type: CLIENT_IP
    localityLbAlgorithm: MAGLEV
  targetRefs:
  - group: ""
    kind: Service
    name: SERVICE_NAME

אימות המדיניות

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

  1. כדי לבדוק את סטטוס המדיניות, מריצים את הפקודה הבאה:

    kubectl describe gcptrafficdistributionpolicy POLICY_NAME
    

    מחליפים את POLICY_NAME בשם המדיניות.

  2. בודקים את הקטע Conditions בתוצאה. הסטטוס True עם הסיבה Attached מציין שההגדרה תקפה ופעילה.

הגדרת זיקה לסשן באמצעות GCPBackendPolicy

בקטע הזה מוסבר איך להגדיר זיקה לסשן (session affinity) באמצעות GCPBackendPolicy.

אפשר להגדיר את הזיקה לסשן (session affinity) של GCPBackendPolicy על סמך הקריטריונים הבאים:

  • כתובת ה-IP של הלקוח (CLIENT_IP)
  • קובץ Cookie שנוצר (GENERATED_COOKIE)

כשמגדירים את הזיקה לסשן (session affinity) לשירות באמצעות GCPBackendPolicy, שער הכניסה מגדיר את ההגדרה localityLbPolicy בשירות לקצה העורפי ל-MAGLEV. כשמסירים את ההגדרה של זיקה לסשן (session affinity) מ-GCPBackendPolicy, שער ה-API מחזיר את ההגדרה localityLbPolicy לערך ברירת המחדל, ROUND_ROBIN.

במניפסט GCPBackendPolicy הבא מוגדרת זיקה לסשן על סמך כתובת ה-IP של הלקוח:

שירות

apiVersion: networking.gke.io/v1
kind: GCPBackendPolicy
metadata:
  name: my-backend-policy
  namespace: lb-service-namespace
spec:
  default:
    # On a best-effort basis, send requests from a specific client IP address
    # to the same backend. This field also sets the load balancer locality
    # policy to MAGLEV. For more information, see
    # https://cloud.google.com/load-balancing/docs/backend-service#lb-locality-policy
    sessionAffinity:
      type: CLIENT_IP
  targetRef:
    group: ""
    kind: Service
    name: lb-service

שירות אשכול מרובה

apiVersion: networking.gke.io/v1
kind: GCPBackendPolicy
metadata:
  name: my-backend-policy
  namespace: lb-service-namespace
spec:
  default:
    # On a best-effort basis, send requests from a specific client IP address
    # to the same backend. This field also sets the load balancer locality
    # policy to MAGLEV. For more information, see
    # https://cloud.google.com/load-balancing/docs/backend-service#lb-locality-policy
    sessionAffinity:
      type: CLIENT_IP
  targetRef:
    group: net.gke.io
    kind: ServiceImport
    name: lb-service

במניפסט הבא של GCPBackendPolicy מוגדרת זיקה לסשן על סמך קובץ Cookie שנוצר, ומוגדר TTL של קובץ ה-Cookie ל-50 שניות:

שירות

apiVersion: networking.gke.io/v1
kind: GCPBackendPolicy
metadata:
  name: my-backend-policy
  namespace: lb-service-namespace
spec:
  default:
    # Include an HTTP cookie in the Set-Cookie header of the response.
    # This field also sets the load balancer locality policy to MAGLEV. For more
    # information, see
    # https://cloud.google.com/load-balancing/docs/l7-internal#generated_cookie_affinity.
    sessionAffinity:
      type: GENERATED_COOKIE
      cookieTtlSec: 50  # The cookie expires in 50 seconds.
  targetRef:
    group: ""
    kind: Service
    name: lb-service

שירות אשכול מרובה

apiVersion: networking.gke.io/v1
kind: GCPBackendPolicy
metadata:
  name: my-backend-policy
  namespace: lb-service-namespace
spec:
  default:
    # Include an HTTP cookie in the Set-Cookie header of the response.
    # This field also sets the load balancer locality policy to MAGLEV. For more
    # information, see
    # https://cloud.google.com/load-balancing/docs/l7-internal#generated_cookie_affinity.
    sessionAffinity:
      type: GENERATED_COOKIE
      cookieTtlSec: 50  # The cookie expires in 50 seconds.
  targetRef:
    group: net.gke.io
    kind: ServiceImport
    name: lb-service

הגדרת זמן קצוב להשלמת תהליך (connection draining)

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

אפשר להגדיר זמן קצוב לתפוגה של ניתוק חיבורים באמצעות GCPBackendPolicy. הזמן להשלמת תהליך (connection draining) הוא הזמן בשניות להמתנה עד להשלמת התהליך. משך הזמן הקצוב לתפוגה יכול להיות בין 0 ל-3,600 שניות. ערך ברירת המחדל הוא 0, שגם משבית את זמן להשלמת תהליך (connection draining).

במניפסט GCPBackendPolicy הבא מוגדר פסק זמן של 60 שניות להפסקת החיבורים:

שירות

apiVersion: networking.gke.io/v1
kind: GCPBackendPolicy
metadata:
  name: my-backend-policy
  namespace: lb-service-namespace
spec:
  default:
    connectionDraining:
      drainingTimeoutSec: 60
  targetRef:
    group: ""
    kind: Service
    name: lb-service

שירות אשכול מרובה

apiVersion: networking.gke.io/v1
kind: GCPBackendPolicy
metadata:
  name: my-backend-policy
  namespace: lb-service-namespace
spec:
  default:
    connectionDraining:
      drainingTimeoutSec: 60
  targetRef:
    group: net.gke.io
    kind: ServiceImport
    name: lb-service

InferencePool

apiVersion: networking.gke.io/v1
kind: GCPBackendPolicy
metadata:
  name: my-backend-policy
  namespace: lb-service-namespace
spec:
  default:
    connectionDraining:
      drainingTimeoutSec: 60
  # Attach to an InferencePool in the cluster.
  targetRef:
    group: inference.networking.k8s.io
    kind: InferencePool
    name: my-inference-pool

Multi-cluster InferencePool

yaml apiVersion: networking.gke.io/v1 kind: GCPBackendPolicy metadata: name: my-backend-policy namespace: lb-service-namespace spec: default: connectionDraining: drainingTimeoutSec: 60 # Attach to a multi-cluster InferencePool. targetRef: group: networking.gke.io kind: GCPInferencePoolImport name: my-inference-pool-import

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

רישום גישה ב-HTTP

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

כברירת מחדל:

  • בקר ה-Gateway מתעד את כל בקשות ה-HTTP מלקוחות ב-Cloud Logging.
  • שיעור הדגימה הוא 1,000,000, כלומר כל הבקשות מתועדות.
  • לא נרשמים שדות אופציונליים.

יש שלוש דרכים להשבית את רישום הגישה ביומן ב-Gateway באמצעות GCPBackendPolicy:

  • אפשר להשאיר את GCPBackendPolicy בלי קטע logging
  • אפשר להגדיר את logging.enabled לערך false
  • אפשר להגדיר את logging.enabled ל-true ואת logging.sampleRate ל-0

אפשר גם להגדיר את שיעור הדגימה של רישום הגישה ואת רשימת השדות האופציונליים, למשל tls.cipher או orcaLoadReport.

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

  • מגדירים את logging.OptionalMode להיות CUSTOM.
  • מזינים את רשימת השדות האופציונליים שרוצים לרשום ביומן logging.optionalFields. כאן מופיעה רשימה של השדות הנתמכים.

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

  • אפשר להסיר את כל הרשומות מ-logging.optionalFields.
  • אפשר להגדיר את logging.OptionalMode ל-EXCLUDE_ALL_OPTIONAL.

מניפסט ה-GCPBackendPolicy הבא משנה את קצב הדגימה שמוגדר כברירת מחדל לרישום גישה, ומגדיר אותו ל-50% מבקשות ה-HTTP. המניפסט מאפשר גם רישום ביומן של שני שדות אופציונליים עבור משאב שירות נתון:

שירות

apiVersion: networking.gke.io/v1
kind: GCPBackendPolicy
metadata:
  name: my-backend-policy
  namespace: lb-service-namespace
spec:
  default:
    # Access logging configuration for the load balancer.
    logging:
      enabled: true
      # Log 50% of the requests. The value must be an integer between 0 and
      # 1000000. To get the proportion of requests to log, GKE
      # divides this value by 1000000.
      sampleRate: 500000
      # Log specific optional fields.
      optionalMode: CUSTOM
      optionalFields:
      - tls.cipher
      - orcaLoadReport.cpu_utilization
  targetRef:
    group: ""
    kind: Service
    name: lb-service

שירות אשכול מרובה

apiVersion: networking.gke.io/v1
kind: GCPBackendPolicy
metadata:
  name: my-backend-policy
  namespace: lb-service-namespace
spec:
  default:
    # Access logging configuration for the load balancer.
    logging:
      enabled: true
      # Log 50% of the requests. The value must be an integer between 0 and
      # 1000000. To get the proportion of requests to log, GKE
      # divides this value by 1000000.
      sampleRate: 500000
      # Log specific optional fields.
      optionalMode: CUSTOM
      optionalFields:
      - tls.cipher
      - orcaLoadReport.cpu_utilization
  targetRef:
    group: net.gke.io
    kind: ServiceImport
    name: lb-service

InferencePool

apiVersion: networking.gke.io/v1
kind: GCPBackendPolicy
metadata:
  name: my-backend-policy
  namespace: lb-service-namespace
spec:
  default:
    # Access logging configuration for the load balancer.
    logging:
      enabled: true
      # Log 50% of the requests. The value must be an integer between 0 and
      # 1000000. To get the proportion of requests to log, GKE
      # divides this value by 1000000.
      sampleRate: 500000
      # Log specific optional fields.
      optionalMode: CUSTOM
      optionalFields:
      - tls.cipher
      - orcaLoadReport.cpu_utilization
  # Attach to an InferencePool in the cluster.
  targetRef:
    group: inference.networking.k8s.io
    kind: InferencePool
    name: my-inference-pool

Multi-cluster InferencePool

apiVersion: networking.gke.io/v1
kind: GCPBackendPolicy
metadata:
  name: my-backend-policy
  namespace: lb-service-namespace
spec:
  default:
    # Access logging configuration for the load balancer.
    logging:
      enabled: true
      # Log 50% of the requests. The value must be an integer between 0 and
      # 1000000. To get the proportion of requests to log, GKE
      # divides this value by 1000000.
      sampleRate: 500000
      # Log specific optional fields.
      optionalMode: CUSTOM
      optionalFields:
      - tls.cipher
      - orcaLoadReport.cpu_utilization
  # Attach to a multi-cluster InferencePool.
  targetRef:
    group: networking.gke.io
    kind: GCPInferencePoolImport
    name: my-inference-pool-import

קובץ המניפסט הזה כולל את השדות הבאים:

  • enable: true: הפעלה מפורשת של רישום גישה ביומן. היומנים זמינים בקטע Logging (רישום ביומן).
  • sampleRate: 500000: מציין ש-50% מהחבילות מתועדות ביומן. אפשר להשתמש בערך בין 0 ל-1,000,000. ‫GKE ממיר את הערך הזה לערך נקודה צפה בטווח [0, 1] על ידי חלוקה ב-1,000,000. השדה הזה רלוונטי רק אם בשדה enable מגדירים את הערך true. sampleRate הוא שדה אופציונלי, אבל אם הוא מוגדר, חובה להגדיר גם את enable: true. אם המדיניות enable מוגדרת לערך true והמדיניות sampleRate לא מוגדרת, GKE מגדיר את enable לערך false.
  • optionalMode: CUSTOM: מציין שקבוצה של optionalFields צריכה להיכלל ברשומות ביומן.
  • optionalFields: tls.cipher, orcaLoadReport.cpu_utilization: מציין שרשומות היומן צריכות לכלול גם את שם ההצפנה שמשמש ללחיצת היד של TLS וגם את ניצול המעבד של השירות, בכל פעם שהם זמינים.

הגדרת התאמה אוטומטית לעומס (autoscaling) על סמך תנועה בשער חד-אשכולי

מוודאים שאשכול GKE פועל בגרסה 1.31.1-gke.2008000 ואילך.

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

כדי להגדיר את קיבולת השירות, יוצרים שירות ומדיניות GCPBackendPolicy משויכת. מניפסט GCPBackendPolicy משתמש בשדה maxRatePerEndpoint שמגדיר ערך מקסימלי של בקשות לשנייה (RPS) לכל Pod בשירות. במניפסט הבא של GCPBackendPolicy מוגדר RPS מקסימלי של 10:

apiVersion: networking.gke.io/v1
kind: GCPBackendPolicy
metadata:
  name: store
spec:
  default:
    maxRatePerEndpoint: 10
  targetRef:
    group: ""
    kind: Service
    name: store

מידע נוסף על שינוי גודל אוטומטי על סמך תנועה זמין במאמר שינוי גודל אוטומטי על סמך תנועה במאזן עומסים.

פתרון בעיות

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

המדיניות GCPTrafficDistributionPolicy לא נכנסת לתוקף

תיאור הבעיה: תעבורת הנתונים לא מופצת בהתאם להגדרות של זיקה לסשן (session affinity) או של אזוריות שמוגדרות במדיניות.

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

פתרון עקיף:

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

    kubectl describe gcptrafficdistributionpolicy POLICY_NAME
    

    מחליפים את POLICY_NAME בשם המדיניות.

    בפלט, מחפשים את הקטע Conditions. סטטוס True עם הסיבה Attached מציין שההגדרה תקינה והיא הוחלה. אם הסטטוס הוא False, צריך לבדוק את השדות Reason ו-Message אם יש שגיאות אימות (לדוגמה, אלגוריתם לא נתמך לסוג הזיקה שנבחר).

  2. אימות הסנכרון של הגדרות השער: מוודאים שהשער שמנהל את התנועה סינכרן בהצלחה את ההגדרות האלה עם תשתית הענן.

    בקטע Status, מוודאים שהתנאי Programmed הוא Status עם ערך של True. אם קוד השגיאה הוא False, המשמעות היא שבקר השער נתקל בשגיאה, שיכול להיות שהיא קשורה ל-GCPTrafficDistributionPolicy.

    כדי לראות את הפרטים המלאים, בודקים את השדות Reason ו-Message שליד התנאי Programmed. כדי לראות הודעות שגיאה מפורטות יותר או היסטוריה של כשלים בסנכרון, בודקים את Events בתחתית הפלט.

כמה GCPBackendPolicy שמצורפים לאותו שירות

תסמין:

תנאי הסטטוס הבא עשוי להתרחש כשמצרפים GCPBackendPolicy לשירות או ל-ServiceImport:

status:
  conditions:
    - lastTransitionTime: "2023-09-26T20:18:03Z"
      message: conflicted with GCPBackendPolicy "[POLICY_NAME]" of higher precedence, hence not applied
      reason: Conflicted
      status: "False"
      type: Attached

הסיבה:

תנאי הסטטוס הזה מציין שאתם מנסים להחיל GCPBackendPolicy שני על Service או ServiceImport שכבר מצורף אליו GCPBackendPolicy.

‫GKE Gateway לא תומך בכמה GCPBackendPolicy שמצורפים לאותו Service או ServiceImport. פרטים נוספים מופיעים במאמר הגבלות.

פתרון עקיף:

מגדירים מדיניות GCPBackendPolicy אחת שכוללת את כל ההגדרות המותאמות אישית ומצרפים אותה למשאב היעד (Service,‏ ServiceImport,‏ InferencePool או GCPInferencePoolImport).

הזיקה לסשן לא נלקחת בחשבון במהלך פיצול התנועה

תסמין:

הבקשות לא מנותבות באופן עקבי לאותו Pod של קצה עורפי, למרות שהוגדרה זיקה לסשן (session affinity).

הסיבה:

חלוקת תנועה משוקללת מקבלת עדיפות על פני זיקה לסשן (session affinity). אם רכיב HTTPRoute מגדיר משקלים למספר קצוות עורפיים, מאזן העומסים בוחר קצה עורפי על סמך המשקלים לפני שהוא מפעיל את לוגיקת ההעדפה.

פתרון עקיף:

מומלץ להימנע משימוש בפיצול תנועה משוקלל באותו כלל HTTPRoute שבו נדרשת שמירת נתוני סשן.

לא נמצאה מדיניות אבטחה של Cloud Armor

תסמין:

יכול להיות שתופיע הודעת השגיאה הבאה כשמפעילים את Cloud Armor בשער אזורי:

Invalid value for field 'resource': '{
"securityPolicy":"projects/123456789/regions/us-central1/securityPolicies/<policy_name>"}'.
The given security policy does not exist.

הסיבה:

הודעת השגיאה מציינת שמדיניות האבטחה האזורית של Cloud Armor שצוינה לא קיימת בפרויקט Google Cloud שלך.

פתרון עקיף:

יוצרים מדיניות אבטחה אזורית של Cloud Armor בפרויקט ומפנים למדיניות הזו ב-GCPBackendPolicy.

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