יצירת מאזן עומסים פנימי ברשתות VPC

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

לפני שאתם קוראים את הדף הזה, חשוב שתכירו את המושגים הבאים:

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

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

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

יצירת מאזן עומסים פנימי עם Private Service Connect

כבעלים של שירות מנוהל, אתם יכולים להשתמש בצירופי שירותים כדי להפוך את השירותים שלכם לזמינים לצרכני שירות ברשתות VPC אחרות באמצעות Private Service Connect. אפשר ליצור, לנהל ולמחוק חיבורי שירות באמצעות ServiceAttachment משאב בהתאמה אישית. בקר Private Service Connect של GKE עוקב אחרי המשאב ServiceAttachment ויוצר, מעדכן או מוחק באופן אוטומטי משאב ServiceAttachment תואם ב-Compute Engine.

דרישות ומגבלות

  • חלות המגבלות של Private Service Connect.
  • אפשר ליצור צירוף שירות בגרסאות GKE‏ 1.21.4-gke.300 ואילך.
  • באשכול צריך להפעיל את התוסף HttpLoadBalancing. באשכולות GKE חדשים, התוסף HttpLoadBalancing מופעל כברירת מחדל.
  • אי אפשר להשתמש באותה רשת משנה בכמה הגדרות של צירופי שירות.
  • אתם צריכים ליצור שירות GKE שמשתמש במאזן עומסי רשת פנימי להעברת סיגנל ללא שינוי.
  • שירות GKE חייב להשתמש בפרוטוקול אחד בלבד. אין תמיכה בשירותי GKE עם פרוטוקולים מעורבים.
  • בגרסאות GKE שקודמות ל-1.22.4-gke.100, אי אפשר לציין רשת משנה בפרויקט אחר (VPC משותף). ב-VPC משותף, ודאו שכל הדרישות ל-VPC משותף מתקיימות.
  • אחרי שיוצרים צירוף שירות, אי אפשר לעדכן את מאזן העומסים הפנימי. כדי לשנות את ההגדרות של מאזן העומסים, צריך למחוק את צירוף השירות וליצור אותו מחדש.

תאימות של גרסת ה-IP לרשתות משנה של שירותים ו-NAT

כשיוצרים משאב ServiceAttachment, בקר GKE Private Service Connect יוצר קובץ מצורף אחד של שירות Compute Engine שמשויך לכלל העברה של בעלים. כלל ההעברה של היצרן משתמש בכתובת IPv4 או בכתובת IPv6. בטבלה הבאה מוצג איך הבקר בוחר את כלל ההעברה על סמך הגדרת משפחת ה-IP (השדה spec.ipFamilies) של שירות Kubernetes שאליו מפנים, וסוגי המחסניות של כל רשתות המשנה שצוינו בשדה spec.natSubnets:

שירות Kubernetes (כללי העברה) סוגי המחסניות של רשתות המשנה בשדה natSubnets כלל העברה של צירוף שירות ב-Compute Engine הערות
מחסנית יחידה של IPv4 ‫IPV4_ONLY, IPV4_IPV6 או שניהם כתובת IPv4 יש תמיכה.
מכיל רשת משנה כלשהי של IPV6_ONLY אין (שגיאה) שגיאת הגדרה. כל רשתות המשנה של NAT חייבות לתמוך בכתובות IPv4.
מחסנית כפולה (כתובות IPv4 ו-IPv6) ‫IPV4_ONLY, IPV4_IPV6 או שניהם (בלי רשת משנה של IPV6_ONLY) כתובת IPv4 יש תמיכה. משתמש בכלל ההעברה של IPv4. חיבור לשירות IPv4 יכול לקבל חיבורים מנקודות קצה (endpoints) של צרכנים מסוג IPv4 ו-IPv6.
‫IPV6_ONLY, או שילוב של IPV6_ONLY ו-IPV4_IPV6 (ללא רשת משנה של IPV4_ONLY) כתובת IPv6 יש תמיכה. משתמש בכלל ההעברה של IPv6 כי יש רשת משנה של IPV6_ONLY. צירוף שירות IPv6 מקבל חיבורים רק מנקודות קצה (endpoints) של צרכני IPv6.
מכיל גם רשתות משנה של IPV4_ONLY וגם של IPV6_ONLY אין (שגיאה) שגיאת הגדרה. כל רשתות המשנה של NAT חייבות להיות באותה גרסת IP.
מחסנית יחידה של IPv6 ‫IPV6_ONLY, IPV4_IPV6 או שניהם כתובת IPv6 יש תמיכה.
מכיל רשת משנה כלשהי של IPV4_ONLY אין (שגיאה) שגיאת הגדרה. כל רשתות המשנה של NAT חייבות לתמוך בכתובות IPv6.

מידע נוסף על האופן שבו נקודות קצה (endpoints) של צרכנים מתחברות לחיבורי שירות של IPv4 ו-IPv6 זמין במאמר תרגום של גרסת IP.

יצירת ServiceAttachment

  1. יוצרים רשת משנה.

    צריך ליצור רשת משנה חדשה לכל ServiceAttachment.

    gcloud compute networks subnets create SUBNET_NAME \
        --project PROJECT_ID \
        --network NETWORK_NAME \
        --region REGION \
        --range SUBNET_RANGE \
        --purpose PRIVATE_SERVICE_CONNECT
    

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

    • ‫SUBNET_NAME: השם של תת-הרשת החדשה. בגרסאות GKE‏ 1.22.4-gke.100 ואילך, אפשר לציין רשת משנה בפרויקט אחר באמצעות כתובת ה-URL המלאה של המשאב בשדה הזה. אפשר לקבל את כתובת ה-URL המלאה של המשאב באמצעות הפקודה gcloud compute networks subnets describe.
    • ‫PROJECT_ID: מזהה הפרויקט ב- Google Cloud.
    • ‫NETWORK_NAME: השם של רשת ה-VPC של רשת המשנה.
    • ‫REGION: האזור של רשת המשנה החדשה. אתם צריכים להשתמש באותו אזור שבו נמצא השירות שאתם יוצרים.
    • ‫SUBNET_RANGE: טווח כתובות ה-IPv4 לשימוש ברשת המשנה.

    כדי ליצור רשת משנה של Private Service Connect עם סטאק כפול או IPv6 בלבד, צריך לכלול את הדגלים --stack-type=IPV4_IPV6 ו---ipv6-access-type=INTERNAL או את הדגלים --stack-type=IPV6_ONLY ו---ipv6-access-type=INTERNAL (צריך להשמיט את הדגל --range כשמשתמשים בסוג הסטאק IPV6_ONLY). חשוב לוודא שסוג המחסנית של תת-הרשת תואם למשפחת כתובות ה-IP של השירות, כפי שמתואר בקטע תאימות של גרסת ה-IP לשירותים ולתת-רשתות של NAT.

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

    המניפסט הבא מתאר פריסה שמריצה קובץ אימג' של קונטיינר של אפליקציית אינטרנט לדוגמה. שומרים את המניפסט בשם my-deployment.yaml:

    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: psc-ilb
    spec:
      replicas: 3
      selector:
        matchLabels:
          app: psc-ilb
      template:
        metadata:
          labels:
            app: psc-ilb
        spec:
          containers:
          - name: whereami
            image: us-docker.pkg.dev/google-samples/containers/gke/whereami:v1
            ports:
              - name: http
                containerPort: 8080
            readinessProbe:
              httpGet:
                path: /healthz
                port: 8080
                scheme: HTTP
              initialDelaySeconds: 5
              timeoutSeconds: 1
    
  3. מחילים את המניפסט על האשכול:

    kubectl apply -f my-deployment.yaml
    
  4. יוצרים שירות. המניפסט הבא מתאר שירות שיוצר מאזן עומסי רשת פנימי להעברת סיגנל ללא שינוי ביציאת TCP‏ 8080. שומרים את המניפסט בשם my-service.yaml:

     apiVersion: v1
     kind: Service
     metadata:
       name: SERVICE_NAME
       annotations:
         networking.gke.io/load-balancer-type: "Internal"
     spec:
       type: LoadBalancer
       selector:
         app: psc-ilb
       ports:
       - port: 80
         targetPort: 8080
         protocol: TCP
    

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

    • ‫SERVICE_NAME: שם השירות החדש.
  5. מחילים את המניפסט על האשכול:

    kubectl apply -f my-service.yaml
    
  6. יוצרים ServiceAttachment.

    המניפסט הבא מתאר ServiceAttachment שחושף את השירות שיצרתם לצרכני השירות. שומרים את המניפסט בשם my-psc.yaml:

    apiVersion: networking.gke.io/v1
    kind: ServiceAttachment
    metadata:
     name: SERVICE_ATTACHMENT_NAME
     namespace: default
    spec:
     connectionPreference: ACCEPT_AUTOMATIC
     natSubnets:
     - SUBNET_NAME
     proxyProtocol: false
     reconcileConnections: false  # set to true to enable connection reconciliation
     resourceRef:
       kind: Service
       name: SERVICE_NAME
    

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

    • ‫SERVICE_ATTACHMENT_NAME: השם של צירוף השירות החדש.
    • ‫SUBNET_NAME: השם של תת-הרשת החדשה. בגרסאות GKE‏ 1.22.4-gke.100 ואילך, אפשר לציין רשת משנה בפרויקט אחר באמצעות כתובת ה-URL המלאה של המשאב בשדה הזה. אפשר לקבל את כתובת ה-URL המלאה של המשאב באמצעות הפקודה gcloud compute networks subnets describe. כדי להגדיר VPC משותף, משתמשים בפורמט הבא: projects/HOST_PROJECT_ID/regions/COMPUTE_REGION/subnetworks/SUBNET_NAME.

    מידע נוסף על שדות המניפסט זמין בקטע שדות של קובץ Manifest של שירות.

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

    kubectl apply -f my-psc.yaml
    
  8. מוודאים שהבקר של Private Service Connect יצר את קובץ השירות המצורף:

    gcloud compute service-attachments list
    

    בפלט מוצג צירוף שירות עם שם שנוצר באופן אוטומטי:

    NAME        REGION       PRODUCER_FORWARDING_RULE          CONNECTION_PREFERENCE
    k8s1-sa-... REGION_NAME  a3fea439c870148bdba5e59c9ea9451a  ACCEPT_AUTOMATIC
    

צפייה בServiceAttachment

כדי לראות את הפרטים של ServiceAttachment, משתמשים בפקודה הבאה:

kubectl describe serviceattachment SERVICE_ATTACHMENT_NAME

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

Name:        <sa-name>
Namespace:    default
Labels:       <none>
Annotations:  <none>
API Version:  networking.gke.io/v1beta1
Kind:         ServiceAttachment
Metadata:
  ...
Status:
  Forwarding Rule URL:      https://www.googleapis.com/compute/beta/projects/<project>/regions/<region>/forwardingRules/<fr-name>
  Last Modified Timestamp:  2021-07-08T01:32:39Z
  Service Attachment URL:   https://www.googleapis.com/compute/beta/projects/<projects>/regions/<region>/serviceAttachments/<gce-service-attachment-name>
Events:                     <none>

צריכת ServiceAttachment

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

  1. משיגים את כתובת ה-URL של ServiceAttachment:

    kubectl get serviceattachment SERVICE_ATTACHMENT_NAME -o=jsonpath="{.status.serviceAttachmentURL}"
    

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

      serviceAttachmentURL: https://www.googleapis.com/compute/alpha/projects/<project>/region/<region>/serviceAttachments/k8s1-...my-sa
    
  2. יוצרים נקודת קצה (endpoint) של Private Service Connect באמצעות כתובת ה-URL של ServiceAttachment.

  3. כדי לוודא שאתם יכולים להתחבר לשירות שפרסתם בפרויקט של הספק, השתמשו בפקודה curl ממכונה וירטואלית בפרויקט של הצרכן:

    curl PSC_IP_ADDRESS
    

    מחליפים את PSC_IP_ADDRESS בכתובת ה-IP של כלל ההעברה בפרויקט של הצרכן.

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

    {
      "cluster_name":"cluster",
      "host_header":"10.128.15.200",
      "node_name":"gke-psc-default-pool-be9b6e0e-dvxg.c.gke_project.internal",
      "pod_name":"foo-7bf648dcfd-l5jf8",
      "pod_name_emoji":"👚",
      "project_id":"gke_project",
      "timestamp":"2021-06-29T21:32:03",
      "zone":"ZONE_NAME"
    }
    

עדכון של ServiceAttachment

כדי לעדכן ServiceAttachment, פועלים לפי השלבים הבאים:

  1. עורכים את המניפסט של ServiceAttachment ב-my-psc.yaml:

    apiVersion: networking.gke.io/v1
    kind: ServiceAttachment
    metadata:
      name: my-sa
      namespace: default
    spec:
      connectionPreference: ACCEPT_AUTOMATIC
      natSubnets:
      - my-nat-subnet
      proxyProtocol: false
      resourceRef:
        kind: Service
        name: ilb-service
    
  2. מחילים את המניפסט על האשכול:

    kubectl apply -f my-psc.yaml
    

מחיקת ServiceAttachment

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

  1. מוחקים את קובץ השירות המצורף:

    kubectl delete serviceattachment SERVICE_ATTACHMENT_NAME --wait=false
    

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

  2. מחיקת השירות:

    kubectl delete svc SERVICE_NAME
    
  3. מוחקים את רשת המשנה:

    gcloud compute networks subnets delete SUBNET_NAME
    

ServiceAttachment שדות

השדות של ServiceAttachment:

  • ‫connectionPreference: העדפת החיבור שקובעת איך הלקוחות מתחברים לשירות. אתם יכולים להשתמש באישור פרויקט אוטומטי באמצעות ACCEPT_AUTOMATIC או באישור פרויקט מפורש באמצעות ACCEPT_MANUAL. מידע נוסף מופיע במאמר פרסום שירותים באמצעות Private Service Connect.
  • ‫natSubnets: רשימה של שמות משאבים של רשתות משנה לשימוש בחיבור לשירות.
  • ‫proxyProtocol: כשהערך הוא true, כתובת ה-IP של מקור הצרכן ומזהה החיבור של Private Service Connect זמינים בבקשות. השדה הזה הוא אופציונלי, ואם לא מציינים אותו, ערך ברירת המחדל הוא false.
  • reconcileConnections (גרסת טרום-השקה (Preview)): כשמגדירים את הערך כ-true, שינויים ברשימות האישור או הדחייה של צרכן השירות מסיימים באופן אוטומטי חיבורים קיימים לא מורשים. כשהערך הוא false, השינויים משפיעים רק על חיבורים חדשים. השדה הזה הוא אופציונלי, וערך ברירת המחדל שלו הוא false. השדה הזה נתמך מגרסה 1.36.0-gke.2459000 של GKE ואילך.
  • ‫consumerAllowList: רשימת הפרויקטים של הצרכנים שמורשים להתחבר אל ServiceAttachment. אפשר להשתמש בשדה הזה רק כש-connectionPreference הוא ACCEPT_MANUAL. מידע נוסף על השדה הזה מופיע במאמר פרסום שירותים באמצעות Private Service Connect.
    • ‫project: מזהה הפרויקט או מספר הפרויקט של הצרכן.
    • ‫connectionLimit: מגבלת החיבורים לפרויקט הצרכן. השדה הזה הוא אופציונלי.
    • ‫forceSendFields: שמות השדות שצריך לשלוח כדי לכלול בבקשות ל-API. השדה הזה הוא אופציונלי.
    • ‫nullFields: שמות השדות שצריך לכלול בבקשות API עם ערך null. השדה הזה הוא אופציונלי.
  • ‫consumerRejectList: רשימת מזהי הפרויקטים או המספרים של פרויקטים צרכניים שלא יכולים להתחבר אל ServiceAttachment. אפשר להשתמש בשדה הזה רק אם הערך של connectionPreference הוא ACCEPT_MANUAL. מידע נוסף על השדה הזה זמין במאמר פרסום שירותים באמצעות Private Service Connect.
  • ‫resourceRef: הפניה למשאב ב-Kubernetes.

    • ‫kind: סוג המשאב ב-Kubernetes. צריך להשתמש ב-Service.
    • ‫name: השם של המשאב ב-Kubernetes שחייב להיות באותו מרחב שמות כמו מאזן עומסי הרשת הפנימי להעברת סיגנל ללא שינוי.

פתרון בעיות

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

kubectl get events -n NAMESPACE

מחליפים את NAMESPACE במרחב השמות של מאזן עומסי רשת פנימי של Passthrough.

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

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

Error syncing load balancer: failed to ensure load balancer: googleapi:
Error 400: The forwarding_rule resource '<fwd-rule-URL>' is already being used
by '<svc-attachment-URL>', resourceInUseByAnotherResource.

שגיאה בהפעלת הגישה הגלובלית

יכול להיות שתופיע שגיאה כשמפעילים גישה גלובלית למאזן עומסי רשת פנימי מסוג פס-תרו (Passthrough) שמשתמש בקובץ מצורף לשירות Private Service Connect.

התסמין:

כשמפעילים גישה גלובלית על ידי עדכון המניפסט של שירות GKE והגדרת ההערה networking.gke.io/internal-load-balancer-allow-global-access: "true", העדכון נכשל כשמחילים את המניפסט. הודעת השגיאה הבאה מופיעה כשמריצים את הפקודה kubectl get events:

Error syncing load balancer: failed to ensure load balancer: googleapi: Error 400: The forwarding_rule resource '...' is already being used by '...', resourceInUseByAnotherResource

הסיבה:

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

פתרון עקיף:

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

  1. עדכון המניפסט של שירות GKE: מעדכנים את המניפסט של שירות GKE כך שיכלול את ההערה networking.gke.io/internal-load-balancer-allow-global-access: "true".

  2. הפעלה ידנית של גישה גלובלית בכלל ההעברה: פועלים לפי השלבים שמפורטים בקטע הפעלת גישה גלובלית כדי לעדכן את כלל ההעברה של מאזן העומסים באמצעות מסוףGoogle Cloud , Google Cloud CLI או Compute Engine API.

השדה ReconcileConnections לא מסונכרן

אם הפעלתם ידנית את השדה ReconcileConnections במשאב ServiceAttachment של Compute Engine, אבל השמטתם את השדה מהמניפסט של Kubernetes, ערך ברירת המחדל של השדה הוא false. במקרה כזה, הבקר של GKE לא מחליף את הערך של השדה.

התסמין:

למשאב ServiceAttachment ב-Kubernetes יש את ההערה networking.gke.io/unsynced-field: ReconcileConnections. כשמריצים את הפקודה kubectl get events, מופיע אירוע אזהרה שדומה לזה:

Field "ReconcileConnections" is not specified in the ServiceAttachment CR but has a value in GCE. The controller will not overwrite this field until it is explicitly set in the CR.

פתרון עקיף:

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

  • עדכון המשאב ServiceAttachment של GKE: מעדכנים את המניפסט של ServiceAttachment ב-GKE כך שיכלול את reconcileConnections: true (או את false אם רוצים להשבית אותו).
  • עדכון המשאב ServiceAttachment של Compute Engine: מגדירים ידנית את השדה reconcileConnections לערך false.

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