יצירת מאזן עומסים עם פרוטוקולים מעורבים

במאמר הזה נסביר איך לחשוף אפליקציה שפועלת באשכול Google Kubernetes Engine ‏ (GKE) באמצעות שירות LoadBalancer חיצוני או פנימי עם פרוטוקול מעורב לתעבורת TCP ו-UDP.

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

סקירה כללית

אתם יכולים לחשוף אפליקציות שמשתמשות בפרוטוקולים TCP ו-UDP באמצעות שני שירותי LoadBalancer נפרדים של GKE עם כתובת IP משותפת שמתואמת באופן ידני. עם זאת, הגישה הזו לא יעילה כי היא מחייבת ניהול של כמה שירותים עבור אפליקציה אחת, והיא עלולה להוביל לבעיות כמו שגיאות בהגדרות או חריגה ממכסת כתובות ה-IP.

שירותי LoadBalancer עם פרוטוקולים מעורבים מאפשרים להשתמש בשירות יחיד כדי לנהל תנועה גם ב-TCP וגם ב-UDP. שימוש בשירות יחיד מפשט את ההגדרה, כי אפשר להשתמש בכתובת IP אחת ובקבוצה מאוחדת של כללי העברה לשני הפרוטוקולים. התכונה הזו נתמכת גם במאזני עומסים אזוריים חיצוניים של רשתות להעברת סיגנל ללא שינוי וגם במאזני עומסים פנימיים של רשתות להעברת סיגנל ללא שינוי.

‫GKE תומך בשירותים עם פרוטוקולים מעורבים עם הגדרות של IPv4,‏ IPv6 וסטאק כפול. שירותים עם פרוטוקולים מעורבים משתמשים בכללי העברה בשכבה 3 (L3). כברירת מחדל, הכללים האלה מעבירים את כל התעבורה שמגיעה לכתובת ה-IP הווירטואלית (VIP) של מאזן העומסים ישירות לצמתי האשכול.

כדי לשמור על האבטחה, GKE יוצר ומנהל באופן אוטומטי כללי חומת אש בעדיפות 999, שמאפשרים רק את תנועת ה-TCP וה-UDP הספציפית שמוגדרת במניפסט של השירות. כל תעבורה לא מורשית אחרת שמנותבת לכתובת ה-VIP של מאזן העומסים נחסמת על ידי כללי חומת האש המנוהלים של GKE באמצעות עדיפות 1000. אם יוצרים כללי חומת אש עם עדיפות גבוהה יותר, צריך לוודא שהכללים לא מאפשרים בטעות לתנועת נתונים לא מורשית להגיע לצמתים. מידע נוסף זמין במאמר כללי חומת האש של שירות GKE.

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

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

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

דרישות

כדי ליצור שירות LoadBalancer שמשתמש בפרוטוקולים מעורבים, האשכול צריך לעמוד בדרישות הבאות:

  • איזון עומסים של פרוטוקולים מעורבים זמין לרוב מגרסה GKE 1.36.2-gke.1498000 ואילך. הגרסה הזמינה לכולם תומכת במאזני עומסים חיצוניים ופנימיים עם הגדרות של IPv4,‏ IPv6 וסטאק כפול.
  • בגרסאות 1.34.1-gke.2190000 עד 1.36.2-gke.1498000, איזון עומסים של פרוטוקולים מעורבים נתמך רק במאזני עומסים חיצוניים שמשתמשים בכתובות IPv4.
  • צריך להפעיל את התוסף HttpLoadBalancing באשכול.
  • במאזני עומסים פנימיים, צריך להפעיל באשכול GKE subsetting.
  • בשירותים חדשים של LoadBalancer פנימי, בקובץ המניפסט של השירות, מגדירים את הערך של השדה spec.loadBalancerClass ל-networking.gke.io/l4-regional-internal. בשירותים פנימיים קיימים, ההערה networking.gke.io/load-balancer-type: "Internal" כבר מופיעה במניפסט, ואפשר להשאיר אותה כמו שהיא.
  • לגבי שירותים חדשים של LoadBalancer חיצוניים, מוודאים שמאזן העומסים הוא מאזן עומסי רשת אזורי חיצוני להעברת סיגנל ללא שינוי שמבוסס על שירות קצה עורפי. ב-GKE מגרסה 1.37 ואילך, ההגדרה הזו היא ברירת המחדל. בגרסאות קודמות, מגדירים את השדה spec.loadBalancerClass לערך networking.gke.io/l4-regional-external במניפסט של השירות. בשירותים חיצוניים קיימים, ההערה cloud.google.com/l4-rbs: "enabled" כבר מופיעה בקובץ המניפסט, ואפשר להשאיר את ההערה כמו שהיא.

מגבלות

  • בגרסאות 1.34.1-gke.2190000 עד 1.36.2-gke.1498000, מאזני עומסים עם פרוטוקולים מעורבים תומכים רק בכתובות IPv4.
  • אי אפשר להשתמש בשירותים קיימים עם סיומות gke.networking.io/l4-ilb-v1 או gke.networking.io/l4-netlb-v1 לאיזון עומסים של פרוטוקולים מעורבים. אם רוצים להשתמש בפרוטוקולים מעורבים בשירותים האלה, צריך למחוק את השירות וליצור אותו מחדש בהתאם לדרישות שלמעלה.
  • עדכון הפורטים בשירות עלול לגרום לשיבוש קצר בתעבורה של כל הנתונים שמנותבים דרך מאזן העומסים.
  • אי אפשר לצרף Private Service Connect לשירותים עם פרוטוקולים מעורבים.

תמחור

Google Cloud החיוב מתבצע לפי כלל העברה, עבור כל כתובות ה-IP החיצוניות ועבור הנתונים שנשלחים. בטבלה הבאה מפורט מספר כללי ההעברה וכתובות ה-IP החיצוניות שמשמשים להגדרות שצוינו. מידע נוסף מופיע במאמר בנושא תמחור של רשתות VPC.

סוג שכבת התעבורה שכבת האינטרנט מספר כללי ההעברה מספר כתובות ה-IP החיצוניות
פנימי יחיד או מעורב (TCP,‏ UDP או שניהם) IPv4 1 0
IPv6 1 0
‫IPv4 ו-IPv6 (DualStack) 2 0
חיצוני יחיד או מעורב (TCP,‏ UDP או שניהם) IPv4 1 1
IPv6 1 1
‫IPv4 ו-IPv6 (DualStack) 2 2

פריסת עומס עבודה

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

  1. המאניפסט הבא הוא של אפליקציה לדוגמה שמקשיבה ביציאה 8080 לתנועת TCP ו-UDP. שומרים את קובץ המניפסט הבא בשם mixed-app-deployment.yaml:

    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: mixed-app-deployment
    spec:
      replicas: 3
      selector:
        matchLabels:
          app: mixed-app
      template:
        metadata:
          labels:
            app: mixed-app
        spec:
          containers:
          - image: gcr.io/kubernetes-e2e-test-images/agnhost:2.6
            name: agnhost
            args: ["serve-hostname", "--port=8080", "--tcp=true", "--udp=true", "--http=false"]
            ports:
              - name: tcp8080
                protocol: TCP
                containerPort: 8080
              - name: udp8080
                protocol: UDP
                containerPort: 8080
    
  2. מחילים את המניפסט על האשכול:

    kubectl apply -f mixed-app-deployment.yaml
    

יצירת מאזן עומסים עם פרוטוקולים מעורבים

יוצרים שירות מסוג LoadBalancer שחושף את הפריסה לתנועת TCP ו-UDP. אפשר ליצור מאזן עומסים חיצוני או פנימי.

  1. כדי ליצור מאזן עומסים חיצוני, שומרים את המניפסט הבא כ-mixed-protocol-lb.yaml:

    apiVersion: v1
    kind: Service
    metadata:
      name: mixed-protocol-external-lb
    spec:
      loadBalancerClass: "networking.gke.io/l4-regional-external"
      type: LoadBalancer
      selector:
        app: mixed-app
      ports:
      - name: tcp-port
        protocol: TCP
        port: 8080
      - name: udp-port
        protocol: UDP
        port: 8080
    

    כדי ליצור מאזן עומסים פנימי, מגדירים את הערך של השדה spec.loadBalancerClass ל-networking.gke.io/l4-regional-internal.

    לשירות הקודם יש שתי יציאות, אחת ל-TCP ואחת ל-UDP, שתיהן ביציאה 8080.

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

    kubectl apply --server-side -f mixed-protocol-lb.yaml
    

אימות מאזן העומסים של פרוטוקולים מעורבים

אחרי שיוצרים את השירות, מוודאים ש-GKE יצר את מאזן העומסים בהצלחה.

  1. בודקים את השירות:

    kubectl describe service SERVICE_NAME
    

    מחליפים את SERVICE_NAME בשם השירות (לדוגמה, mixed-protocol-lb).

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

    • השדה status.loadBalancer.ingress.ip מאוכלס.
    • באשכולות בגרסאות 1.34.1-gke.2190000 עד 1.36.2-gke.1498000, צריך לוודא שההערות הבאות לגבי מאזן העומסים החיצוני קיימות:
      • service.kubernetes.io/tcp-forwarding-rule
      • service.kubernetes.io/udp-forwarding-rule
    • עבור אשכולות שנוצרו בגרסאות אחרי 1.36.2-gke.1498000, צריך לוודא שההערות הבאות לגבי מאזן העומסים קיימות, בהתאם להגדרה:
      • ל-IPv4: service.kubernetes.io/l3-forwarding-rule
      • ל-IPv6: service.kubernetes.io/l3-forwarding-rule-ipv6
      • ל-dual-stack: שתי ההערות.
    • בקטע Events לא מופיעות הודעות שגיאה.

עדכון מאזן עומסים עם פרוטוקולים מעורבים

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

kubectl edit service SERVICE_NAME

מחליפים את SERVICE_NAME בשם השירות.

עדכון היציאות

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

בדוגמה הבאה מוסיפים יציאת UDP להזרמה ויציאת TCP למטא-נתונים של שרת המשחק:

apiVersion: v1
kind: Service
metadata:
  name: mixed-protocol-lb
spec:
  loadBalancerClass: "networking.gke.io/l4-regional-external"  # for internal LB, use: "networking.gke.io/l4-regional-internal"
  type: LoadBalancer
  selector:
    app: mixed-app
  ports:
  - name: tcp-port
    protocol: TCP
    port: 8080
  - name: streaming
    protocol: UDP
    port: 10100
  - name: gameserver-metadata
    protocol: TCP
    port: 10400
  - name: https
    protocol: TCP
    port: 443

עדכון מאזן עומסים עם פרוטוקול יחיד לפרוטוקול מעורב

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

בדוגמה הבאה מוסיפים יציאת UDP ל-DNS למאזן עומסים קיים מסוג TCP בלבד:

apiVersion: v1
kind: Service
metadata:
  name: already-existing-single-protocol-lb
spec:
  loadBalancerClass: "networking.gke.io/l4-regional-external" # for internal LB, use: "networking.gke.io/l4-regional-internal"
  type: LoadBalancer
  selector:
    app: mixed-app
  ports:
  - name: http
    protocol: TCP
    port: 80
  - name: https
    protocol: TCP
    port: 443
  - name: dns
    protocol: UDP
    port: 53

עדכון מאזן עומסים עם פרוטוקולים מעורבים למאזן עומסים עם פרוטוקול יחיד

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

בדוגמה הבאה מסירים את יציאת ה-UDP של DNS, וכך מאזן העומסים הופך ל-TCP בלבד:

apiVersion: v1
kind: Service
metadata:
  name: already-existing-mixed-protocol-lb
spec:
  loadBalancerClass: "networking.gke.io/l4-regional-external" # for internal LB, use: "networking.gke.io/l4-regional-internal"
  type: LoadBalancer
  selector:
    app: mixed-app
  ports:
  - name: http
    protocol: TCP
    port: 80
  - name: https
    protocol: TCP
    port: 443

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

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

kubectl delete service SERVICE_NAME

מחליפים את SERVICE_NAME בשם השירות (לדוגמה, mixed-protocol-external-lb).

‫GKE מסיר אוטומטית את כל משאבי איזון העומסים שנוצרו עבור השירות.

פתרון בעיות

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

בדיקה של אירועי שגיאה

השלב הראשון בפתרון בעיות הוא לבדוק את האירועים שמשויכים לשירות.

  1. פרטי השירות:

    kubectl describe service SERVICE_NAME
    

    מחליפים את SERVICE_NAME בשם השירות.

  2. בודקים את הקטע Events בסוף הפלט כדי לראות אם יש הודעות שגיאה.

שגיאה: פרוטוקול מעורב לא אפשרי עבור LoadBalancer

אם יצרתם את השירות באמצעות ההערה cloud.google.com/l4-rbs: "enabled", יכול להיות שתראו אירוע אזהרה מבקר השירות המקורי אחרי שתיצרו את מאזן העומסים עם הפרוטוקולים המעורבים: mixed-protocol is not supported for LoadBalancer.

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

הגדרת היציאה חסרה אחרי עדכון

הסימפטום:

כשמעדכנים שירות שמשתמש באותה יציאה גם ל-TCP וגם ל-UDP (לדוגמה, יציאה 8080), אחת מהגדרות היציאה חסרה בשירות המעודכן.

הסיבה:

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

פתרון:

הפתרון לבעיה הזו תלוי בלקוח שלכם.

  • ב-kubectl: משתמשים בדגל --server-side עם kubectl apply:

    kubectl apply --server-side -f YOUR_SERVICE_MANIFEST.yaml
    

    מחליפים את YOUR_SERVICE_MANIFEST בשם של מניפסט השירות.

  • ב-go-client: אל תשתמשו בתיקוני מיזוג. במקום זאת, צריך להשתמש בקריאה לעדכון כדי להחליף את השירות. לשם כך נדרשת בקשת HTTP‏ PUT עם המפרט המלא של אובייקט השירות.

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