איזון עומסים מתקדם באשכולות GKE

בדף הזה מוסבר איך להגדיר איזון עומסים מתקדם באשכולות GKE למשתמשים מנוהלים של Cloud Service Mesh (TD) באמצעות Kubernetes API. כדי להגדיר איזון עומסים מתקדם באמצעותGoogle Cloud API, אפשר לעיין במדריך למשתמש הגדרת איזון עומסים מתקדם.

אתם יכולים להשתמש באיזון עומסים מתקדם כדי:

  • התנועה לשירות תישאר באזור עד שהקיבולת המקומית תנוצל במלואה.
  • התנועה מנותבת לשירות במיקום 'ראשי' עם יתירות כשל במיקום 'משני' כשמספיק נקודות קצה במיקום הראשי לא תקינות.
  • שליטה במועד המעבר לגיבוי (בהתבסס על אחוז המארחים התקינים).

מגבלות

  • ההגבלות הכלליות על שימוש באיזון עומסים מתקדם ב- Google Cloud חלות.
  • התכונה הזו זמינה רק למשתמשים מנוהלים של Cloud Service Mesh שמשתמשים ב-Traffic Director כמישור הבקרה, ונדרשת רמת נתונים בגרסה 1.19.10-asm.22 ומעלה.
  • לא כל השדות ב-GCPTrafficDistributionPolicy וב-GCPBackendPolicy נתמכים ב-Cloud Service Mesh (TD) מנוהל. השדות הנתמכים הם:
    • GCPTrafficDistributionPolicy
      • ServiceLbAlgorithm
      • AutoCapacityDrain
      • FailoverConfig
    • GCPBackendPolicy
      • MaxRatePerEndpoint
      • BackendPreference
  • אפשר להחיל איזון עומסים מתקדם רק על שירותי Kubernetes שמגובים על ידי עומסי עבודה שפועלים ב- Google Cloud. אין תמיכה בשירותים או בעומסי עבודה חיצוניים (כמו ServiceEntry).
  • אפשר להחיל את מדיניות איזון העומסים רק על שירותי Kubernetes ספציפיים. אין תמיכה במדיניות איזון עומסים ברמת מרחב השמות או ברמת הרשת.
  • יש תמיכה רק בקיבולת QPS.
  • יש תמיכה רק בגרסאות GKE >= 1.31.1.
  • מדיניות מתקדמת של איזון עומסים ברשת Service mesh צריכה לחול רק על שירותים שמשרתים רק תעבורה ברשת. אסור להחיל את המדיניות על שירותים שמשמשים כ-GKE Gateway בקצה העורפי. התנהגויות התנועה לא מוגדרות כשמדובר ביעד תנועה מתקדם לאיזון עומסים, שהוא שירות Kubernetes שמשרת תנועה ברשת ותנועה משער GKE.

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

אפשר להשתמש במשאבים המותאמים אישית הבאים כדי להגדיר איזון עומסים מתקדם ב-GKE. אפשר למצוא את הגדרת המשאב המפורטת במאגר gke-gateway-api.

GCPTrafficDistributionPolicy

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

אם כמה מדיניות GCPTrafficDistributionPolicies מטרגטת את אותו שירות, המדיניות הכי ישנה תיאכף.

GCPBackendPolicy

‫GCPBackendPolicy מגדיר מאפיינים של עורפי שירות שמשפיעים על התנהגות איזון העומסים, כולל:

אם כמה פריטי GCPBackendPolicy מטרגטים את אותו שירות באותו אשכול, המדיניות הכי ישנה תיאכף.

סטטוס מדיניות

ל-GCPTrafficDistributionPolicy ול-GCPBackendPolicy יש שדה סטטוס שמציין את סטטוס הצירוף של המדיניות.

לדוגמה, הרצת הפקודה kubectl describe gcpbackendpolicies example-policy -n example תניב פלט דומה לזה:

...
Status:
  Ancestors:
    Ancestor Ref:
      Group:
      Kind:       Service
      Name:       example-svc
      Namespace:  example
    Conditions:
      Last Transition Time:  2024-10-13T01:15:03Z
      Message:
      Observed Generation:   1
      Reason:                Attached
      Status:                True
      Type:                  Attached
    Controller Name:         gsmconfig.gke.io/controller

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

לפני שמשלימים את המדריך הזה, צריך להקצות את Cloud Service Mesh באשכול GKE.

  1. בודקים אם ה-CRD מותקן:

    kubectl get crd
    

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

    ...
    gcptrafficdistributionpolicies.networking.gke.io   2024-07-18T21:50:12Z
    gcpbackendpolicies.networking.gke.io               2024-07-18T21:50:12Z
    ...
    
  2. אם ה-CRD‏ GCPBackendPolicy עדיין לא מותקן, מתקינים אותו:

    kubectl apply -f https://raw.githubusercontent.com/GoogleCloudPlatform/gke-gateway-api/refs/heads/main/config/crd/networking.gke.io_gcpbackendpolicies.yaml
    
  3. אם ה-CRD‏ GCPTrafficDistributionPolicy עדיין לא מותקן, מתקינים אותו:

    kubectl apply -f https://raw.githubusercontent.com/GoogleCloudPlatform/gke-gateway-api/refs/heads/main/config/crd/networking.gke.io_gcptrafficdistributionpolicies.yaml
    

כללי המדיניות לדוגמה במדריך הזה מטרגטים את השירות foo במרחב השמות foo למטרות הדגמה. אתם יכולים להריץ את הפקודה הבאה כדי ליצור את שירות הבדיקה ואת מרחב השמות, או להשתמש בשירות ובמרחב השמות שלכם:

kubectl apply -f - <<EOF
kind: Namespace
apiVersion: v1
metadata:
  name: foo
  labels:
    istio-injection: enabled
---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: foo
  namespace: foo
spec:
  replicas: 2
  selector:
    matchLabels:
      app: test-backend
  template:
    metadata:
      labels:
        app: test-backend
    spec:
      containers:
      - name: whereami
        image: gcr.io/google-samples/whereami:v1.2.23
        ports:
        - containerPort: 8080
---
apiVersion: v1
kind: Service
metadata:
  name: foo
  namespace: foo
spec:
  selector:
    app: test-backend
  ports:
  - port: 8080
    targetPort: 8080
EOF

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

כברירת מחדל, התעבורה לשירות מתחלקת באופן שווה בין כל הקצוות העורפיים של השירות שפועלים בצורה תקינה ב-Cloud Service Mesh. אפשר ליצור את המדיניות הבאה של GCPTrafficDistributionPolicy כדי שתנועת הגולשים תפוזר לאזור הקרוב ביותר עד לקיבולת של ה-Backend:

kubectl apply -f - <<EOF
apiVersion: networking.gke.io/v1
kind: GCPTrafficDistributionPolicy
metadata:
  name: lb-policy
  namespace: foo
spec:
  targetRefs:
  - kind: Service
    group: ""
    name: foo-service
  default:
    serviceLbAlgorithm: WATERFALL_BY_ZONE
EOF

כברירת מחדל, ה-backends של השירותים נחשבים כאילו יש להם קיבולת אינסופית. אם יש מספיק מארחים תקינים באזור המקומי או הקרוב ביותר, התנועה אף פעם לא תפוזר מחוץ לאזור המקומי או הקרוב ביותר עבור מיקום מסוים של לקוח. אפשר להגדיר את הקיבולת של הקצה העורפי של השירות באמצעות GCPBackendPolicy כדי שאזור יחיד לא יהיה עמוס מדי.

kubectl apply -f - <<EOF
apiVersion: networking.gke.io/v1
kind: GCPBackendPolicy
metadata:
  name: backend-policy
  namespace: foo
spec:
  targetRef:
    kind: Service
    group: ""
    name: foo-backend
  default:
    maxRatePerEndpoint: 5
EOF

שינוי התנהגות המעבר לגיבוי

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

kubectl apply -f - <<EOF
apiVersion: networking.gke.io/v1
kind: GCPTrafficDistributionPolicy
metadata:
  name: lb-policy
  namespace: foo
spec:
  targetRefs:
  - kind: Service
    group: ""
    name: foo-service
  default:
   failoverConfig:
     failoverHealthThreshold: 90
EOF

הגדרת איזון עומסים מתקדם ברשת Service mesh מרובת אשכולות

הכללים GCPTrafficDistributionPolicy ו-GCPBackendPolicy חלים על היקף שונה ב-Service Mesh מרובה אשכולות.

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

כשמדיניות GCPBackendPolicy מטרגטת שירות מרובה אשכולות, היא מגדירה הגדרות ברמת ה-backend (לדוגמה, קיבולת לכל פוד) עבור פודי ה-backend שנבחרו על ידי שירות הטירגוט שלה באשכול המקומי. באותו שירות מרובה אשכולות, אפשר להגדיר הגדרות שונות ברמת ה-backend באשכולות שונים.

בדוגמה הבאה, נוצרת מדיניות GCPTrafficDistributionPolicy באשכול א' כדי להגדיר את אלגוריתם איזון העומסים שישמש בכל הצי, ומדיניות GCPBackendPolicies נמצאת בכל אשכול. שתי ההגדרות של GCPBackendPolicy מגדירות קיבולת של 10qps לכל פוד עבור הפודים של הקצה העורפי באשכול המקומי שלהם, בעוד שההגדרה של GCPBackendPolicy באשכול A מגדירה את הפודים של הקצה העורפי באשכול A כקצה עורפי מועדף.

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

  • תנועה מכל מקום מעדיפה בק-אנדים באשכול א' עד ש-Pods של בק-אנד באשכול א' צריכים לטפל ב-10 qps לכל Pod.
    • ההתנהגות הזו מוגדרת בעיקר על ידי GCPBackendPolicy שהגדירה את backendPreference ל-PREFERRED באשכול A.
  • תנועת גולשים שחורגת מהקיבולת המוגדרת של השרתים העורפיים באשכול א' מנותבת באמצעות אלגוריתם WATERFALL_BY_ZONE לאשכול ב'. הסבר מפורט יותר על קצה עורפי מועדף זמין במאמר סקירה כללית על איזון עומסים מתקדם.
    • ההתנהגות הזו מוגדרת בעיקר על ידי GCPTrafficDistributionPolicy, שמגדירה את האלגוריתם, באשכול A, ועל ידי GCPBackendPolicy, שמגדירה את קיבולת ה-backend, באשכולות A ו-B.

איזון עומסים מתקדם ברשת Service mesh מרובת אשכולות

ב-Istio, שירותי Kubernetes רגילים הופכים באופן מרומז ל'מרובי אשכולות' כשיש כמה אשכולות ב-Service Mesh והשירות נוצר מעבר לגבולות האשכול. למרות שהיעד של GCPTrafficDistributionPolicy הבא הוא שירות Kubernetes רגיל בשם foo, הוא חל על שירות מרובה-אשכולות בשם foo שמורכב מעומסי עבודה תואמים בשני אשכולות.

  1. יוצרים את ה-GCPTrafficDistributionPolicy לאשכול א':

    kubectl apply --context cluster-a-context -f - <<EOF
    kind: GCPTrafficDistributionPolicy
    apiVersion: networking.gke.io/v1
    metadata:
    name: foo-traffic-distribution-policy
    namespace: foo
    spec:
      targetRefs:
      - kind: Service
        group: ""
        name: foo-service
      default:
        serviceLbAlgorithm: WATERFALL_BY_ZONE
    
    EOF
    
  2. יוצרים את GCPBackendPolicy לאשכול א':

    kubectl apply --context cluster-a-context -f - <<EOF
    kind: GCPBackendPolicy
    apiVersion: networking.gke.io/v1
    metadata:
    name: foo-backend-policy
    namespace: foo
    spec:
      default:
        maxRatePerEndpoint: 100
        backendPreference: PREFERRED
      targetRef:
        group: ""
        kind: Service
        name: foo-service
    EOF
    
  3. יוצרים את GCPBackendPolicy עבור אשכול B:

    kubectl apply --context cluster-b-context -f - <<EOF
    kind: GCPBackendPolicy
    apiVersion: networking.gke.io/v1
    metadata:
    name: foo-backend-policy
    namespace: foo
    spec:
      default:
        maxRatePerEndpoint: 10
      targetRef:
        group: ""
        kind: Service
        name: foo-service
    EOF
    

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