פריסת Ingress באשכולות

בדף הזה מוסבר איך לפרוס Ingress שמשרת אפליקציה בכמה אשכולות GKE. מידע נוסף על Multi Cluster Ingress זמין במאמר בנושא Multi Cluster Ingress.

לשם השוואה מפורטת בין Multi Cluster Ingress ‏ (MCI),‏ Multi-cluster Gateway ‏(MCG) ומאזן עומסים עם Standalone Network Endpoint Groups ‏ (LB ו-Standalone NEGs), אפשר לעיין במאמר בחירת API לאיזון עומסים בין כמה אשכולות ב-GKE.

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

במאמר הזה אנחנו מניחים שיצרתם אשכולות בצי והגדרתם את האשכול gke-us כאשכול ההגדרות של Multi Cluster Ingress, כמו שמתואר במאמר הגדרת Multi Cluster Ingress. כדי לאמת את הגדרת האשכול, פועלים לפי השלבים הבאים:

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

    gcloud container clusters list \
        --format="table(name, location, fleet.project:label=FLEET, status)" \
        --project=FLEET_HOST_PROJECT
    

    מחליפים את FLEET_HOST_PROJECT במזהה הפרויקט המארח של ה-fleet.

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

    NAME      LOCATION          FLEET                                   STATUS
    gke-eu    europe-west1      FLEET_NAME   RUNNING
    gke-us    us-central1       FLEET_NAME   RUNNING
    

    בפלט הזה, FLEET_NAME הוא שם הצי.

  2. מתחברים לאשכול התצורה gke-us:

    gcloud container clusters get-credentials gke-us \
        --location=us-central1 \
        --project=CLUSTER_PROJECT
    

    מחליפים את CLUSTER_PROJECT במזהה הפרויקט שמכיל את אשכול gke-us.

  3. מוודאים שההגדרות של Kubernetes CustomResourceDefinitions ל-Multi Cluster Ingress מותקנות באשכול gke-us:

    kubectl get crds | grep multicluster
    

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

    multiclusteringresses.networking.gke.io       2026-05-12T16:39:52Z
    multiclusterservices.networking.gke.io        2026-05-12T16:39:53Z
    

    אם הפלט ריק, משביתים ומפעילים את Multi Cluster Ingress בשביל הצי:

    1. השבתת Multi Cluster Ingress:

      gcloud container fleet ingress disable \
          --project=FLEET_HOST_PROJECT
      
    2. מפעילים את Multi Cluster Ingress עבור הצי ומציינים את אשכול gke-us כאשכול ההגדרות:

      gcloud container fleet ingress enable \
          --config-membership=gke-us \
          --location=us-central1 \
          --project=CLUSTER_PROJECT
      

      אחרי שמפעילים את Multi Cluster Ingress, מריצים את הפקודה kubectl get crds כדי לוודא שה-CustomResourceDefinitions מותקנים באשכול gke-us.

מדריך לפריסה

במשימות הבאות תפרסו אפליקציה פיקטיבית בשם whereami ו-MultiClusterIngress בשני אשכולות. ה-Ingress מספק כתובת IP וירטואלית (VIP) משותפת לפריסות של האפליקציה.

יצירת מרחב השמות

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

בדוגמה הזו, יוצרים whereami מרחב שמות לכל אפליקציה בכל אשכול.

  1. יוצרים קובץ בשם namespace.yaml עם התוכן הבא:

    apiVersion: v1
    kind: Namespace
    metadata:
      name: whereami
    
  2. עוברים להקשר gke-us:

    kubectl config use-context gke-us
    
  3. יוצרים את מרחב השמות:

    kubectl apply -f namespace.yaml
    
  4. עוברים להקשר gke-eu:

    kubectl config use-context gke-eu
    
  5. יוצרים את מרחב השמות:

    kubectl apply -f namespace.yaml
    

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

    namespace/whereami created
    

פריסת האפליקציה

  1. יוצרים קובץ בשם deploy.yaml עם התוכן הבא:

    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: whereami-deployment
      namespace: whereami
      labels:
        app: whereami
    spec:
      selector:
        matchLabels:
          app: whereami
      template:
        metadata:
          labels:
            app: whereami
        spec:
          containers:
          - name: frontend
            image: us-docker.pkg.dev/google-samples/containers/gke/whereami:v1
            ports:
            - containerPort: 8080
    
  2. עוברים להקשר gke-us:

    kubectl config use-context gke-us
    
  3. פריסת האפליקציה whereami:

    kubectl apply -f deploy.yaml
    
  4. עוברים להקשר gke-eu:

    kubectl config use-context gke-eu
    
  5. פורסים את האפליקציה whereami:

    kubectl apply -f deploy.yaml
    
  6. מוודאים שהאפליקציה whereami נפרסה בהצלחה בכל אשכול:

    kubectl get deployment --namespace whereami
    

    הפלט בשני האשכולות צריך להיות דומה לזה:

    NAME           READY   UP-TO-DATE   AVAILABLE   AGE
    whereami-deployment   1/1     1            1           12m
    

פריסה דרך אשכול ההגדרות

עכשיו, אחרי שהאפליקציה נפרסה ב-gke-us וב-gke-eu, תפרסו מאזן עומסים על ידי פריסת משאבי MultiClusterIngress ו-MultiClusterService באשכול ההגדרות. אלה המשאבים המקבילים ל-Ingress ול-Service באשכולות מרובים.

במדריך ההגדרה, הגדרתם את אשכול gke-us כאשכול ההגדרות. אשכול התצורה משמש לפריסה ולהגדרה של Ingress בכל האשכולות.

  1. מגדירים את ההקשר לאשכול התצורה.

    kubectl config use-context gke-us
    

MultiClusterService

  1. יוצרים קובץ בשם mcs.yaml עם התוכן הבא:

    apiVersion: networking.gke.io/v1
    kind: MultiClusterService
    metadata:
      name: whereami-mcs
      namespace: whereami
    spec:
      template:
        spec:
          selector:
            app: whereami
          ports:
          - name: web
            protocol: TCP
            port: 8080
            targetPort: 8080
    
  2. פורסים את המשאב MultiClusterService שתואם לאפליקציה whereami:

    kubectl apply -f mcs.yaml
    
  3. מוודאים שהמשאב whereami-mcs נפרס בהצלחה באשכול ההגדרות:

    kubectl get mcs -n whereami
    

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

    NAME       AGE
    whereami-mcs   9m26s
    

    הפקודה MultiClusterService יוצרת שירות נגזר ללא כתובת IP בכל אשכול שתואם ל-Pods עם app: whereami. אפשר לראות שיש כזה באוסף gke-us kubectl get service -n whereami.

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

    NAME                                TYPE        CLUSTER-IP    EXTERNAL-IP   PORT(S)          AGE
    mci-whereami-mcs-svc-lgq966x5mxwwvvum   ClusterIP   None          <none>        8080/TCP         4m59s
    

שירות דומה ללא ראש יהיה קיים גם ב-gke-eu. השירותים המקומיים האלה משמשים לבחירה דינמית של נקודות קצה (endpoints) של Pod כדי לתכנת את מאזן העומסים הגלובלי של Ingress עם קצה עורפי (backend).

MultiClusterIngress

  1. יוצרים קובץ בשם mci.yaml עם התוכן הבא:

    apiVersion: networking.gke.io/v1
    kind: MultiClusterIngress
    metadata:
      name: whereami-ingress
      namespace: whereami
    spec:
      template:
        spec:
          backend:
            serviceName: whereami-mcs
            servicePort: 8080
    

    שימו לב שההגדרה הזו מנתבת את כל התנועה אל MultiClusterService whereami-mcs שקיים במרחב השמות whereami.

  2. פורסים את משאב MultiClusterIngress שמפנה אל whereami-mcs כאל קצה עורפי:

    kubectl apply -f mci.yaml
    

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

    multiclusteringress.networking.gke.io/whereami-ingress created
    

    שימו לב של-MultiClusterIngress יש את אותה סכימה כמו ל-Kubernetes Ingress. הסמנטיקה של משאב ה-Ingress זהה גם היא, למעט השדה backend.serviceName.

השדה backend.serviceName ב-MultiClusterIngress מפנה אל MultiClusterService ב-Fleet API ולא אל Service באשכול Kubernetes. המשמעות היא שאפשר להגדיר את כל ההגדרות של Ingress, כמו סיום TLS, באותו אופן.

איך מוודאים שהפריסה בוצעה בהצלחה

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

  1. מוודאים שהפריסה בוצעה:

    kubectl describe mci whereami-ingress -n whereami
    

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

    Name:         whereami-ingress
    Namespace:    whereami
    Labels:       <none>
    Annotations:  kubectl.kubernetes.io/last-applied-configuration:
                    {"apiVersion":"networking.gke.io/v1","kind":"MultiClusterIngress","metadata":{"annotations":{},"name":"whereami-ingress","namespace":"whe...
    API Version:  networking.gke.io/v1
    Kind:         MultiClusterIngress
    Metadata:
      Creation Timestamp:  2020-04-10T23:35:10Z
      Finalizers:
        mci.finalizer.networking.gke.io
      Generation:        2
      Resource Version:  26458887
      Self Link:         /apis/networking.gke.io/v1/namespaces/whereami/multiclusteringresses/whereami-ingress
      UID:               62bec0a4-8a08-4cd8-86b2-d60bc2bda63d
    Spec:
      Template:
        Spec:
          Backend:
            Service Name:  whereami-mcs
            Service Port:  8080
    Status:
      Cloud Resources:
        Backend Services:
          mci-8se3df-8080-whereami-whereami-mcs
        Firewalls:
          mci-8se3df-default-l7
        Forwarding Rules:
          mci-8se3df-fw-whereami-whereami-ingress
        Health Checks:
          mci-8se3df-8080-whereami-whereami-mcs
        Network Endpoint Groups:
          zones/europe-west1-b/networkEndpointGroups/k8s1-e4adffe6-whereami-mci-whereami-mcs-svc-lgq966x5m-808-88670678
          zones/us-central1-b/networkEndpointGroups/k8s1-a6b112b6-whereami-mci-whereami-mcs-svc-lgq966x5m-808-609ab6c6
        Target Proxies:
          mci-8se3df-whereami-whereami-ingress
        URL Map:  mci-8se3df-whereami-whereami-ingress
      VIP:        34.98.102.37
    Events:
      Type    Reason  Age                    From                              Message
      ----    ------  ----                   ----                              -------
      Normal  ADD     3m35s                  multi-cluster-ingress-controller  whereami/whereami-ingress
      Normal  UPDATE  3m10s (x2 over 3m34s)  multi-cluster-ingress-controller  whereami/whereami-ingress
    

    יש כמה שדות שמציינים את הסטטוס של פריסת ה-Ingress הזו:

    • Events הוא המקום הראשון שצריך לבדוק. אם אירעה שגיאה, היא תופיע כאן.

    • Cloud Resourceמציג את משאבי Compute Engine כמו כללי העברה, שירותים לקצה העורפי וכללי חומת אש שנוצרו על ידי בקר Multi Cluster Ingress. אם הם לא מופיעים ברשימה, סימן שהם עדיין לא נוצרו. אפשר לבדוק משאבים ספציפיים ב-Compute Engine באמצעות המסוף או הפקודה gcloud כדי לראות את הסטטוס שלהם.

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

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

  2. מוודאים שהאפליקציה פועלת ב-VIP עם נקודת הקצה /ping:

    curl INGRESS_VIP/ping
    

    מחליפים את INGRESS_VIP בכתובת ה-IP הווירטואלית (VIP).

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

    {
    "cluster_name": "gke-us",
    "host_header": "34.120.175.141",
    "pod_name": "whereami-deployment-954cbf78-mtlpf",
    "pod_name_emoji": "😎",
    "project_id": "my-project",
    "timestamp": "2021-11-29T17:01:59",
    "zone": "us-central1-b"
    }
    

    הפלט צריך לציין את האזור ואת העורף של האפליקציה.

  3. אפשר גם לעבור אל http://INGRESS_VIP כתובת ה-URL בדפדפן כדי לראות גרסה גרפית של האפליקציה שבה מוצג האזור שממנו היא מוגשת.

    האשכול שאליו מועברת התנועה תלוי במיקום שלכם. ה-GCLB נועד להעביר את תנועת הלקוחות לקצה העורפי הזמין הקרוב ביותר עם קיבולת.

מפרטי המשאבים

מפרט MultiClusterService

ההגדרה של MultiClusterService מורכבת משני חלקים:

  1. קטע template שמגדיר את השירות שייווצר באשכולות Kubernetes. שימו לב: למרות שהקטע template מכיל שדות שנתמכים בשירות רגיל, יש רק שני שדות שנתמכים ב-MultiClusterService: selector ו-ports. המערכת מתעלמת משאר השדות.

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

המניפסט הבא מתאר MultiClusterService רגיל:

apiVersion: networking.gke.io/v1
kind: MultiClusterService
metadata:
  name: NAME
  namespace: NAMESPACE
spec:
  template:
    spec:
      selector:
        app: POD_LABEL
      ports:
      - name: web
        protocol: TCP
        port: PORT
        targetPort: TARGET_PORT

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

  • ‫NAME: השם של MultiClusterService. השם הזה מופיע בשדה serviceName במשאבי MultiClusterIngress.
  • ‫NAMESPACE: מרחב השמות של Kubernetes שבו נפרס MultiClusterService. הוא חייב להיות באותו מרחב שמות כמו MultiClusterIngress וה-Pods בכל האשכולות ב-fleet.
  • ‫POD_LABEL: התווית שקובעת אילו פודים נבחרים כשרתי קצה עורפיים עבור MultiClusterService בכל האשכולות ב-Fleet.
  • ‫PORT: צריך להיות זהה ליציאה שאליה מתייחס MultiClusterIngress שמתייחס ל-MultiClusterService הזה.
  • ‫TARGET_PORT: היציאה שמשמשת לשליחת תנועה אל ה-Pod מ-GCLB. קבוצת נקודות קצה ברשת (NEG) נוצרת בכל אשכול, והיציאה הזו משמשת כיציאת השירות שלה.

מפרט MultiClusterIngress

הקוד הבא ב-mci.yaml מתאר את ממשק המשתמש של מאזן העומסים:

apiVersion: networking.gke.io/v1
kind: MultiClusterIngress
metadata:
  name: NAME
  namespace: NAMESPACE
spec:
  template:
    spec:
      backend:
       serviceName: DEFAULT_SERVICE
       servicePort: PORT
      rules:
        - host: HOST_HEADER
          http:
            paths:
            - path: PATH
              backend:
                serviceName: SERVICE
                servicePort: PORT

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

  • ‫NAME: השם של משאב MultiClusterIngress.
  • ‫NAMESPACE: מרחב השמות של Kubernetes שבו נפרס MultiClusterIngress. הוא צריך להיות באותו מרחב שמות כמו MultiClusterService וה-Pods בכל האשכולות בצי.
  • ‫DEFAULT_SERVICE: משמש כקצה העורפי שמוגדר כברירת מחדל לכל התנועה שלא תואמת לכללים של מארח או נתיב. זהו שדה חובה, וצריך לציין קצה עורפי שמוגדר כברירת מחדל ב-MultiClusterIngress, גם אם מוגדרות התאמות אחרות של מארח או נתיב.
  • ‫PORT: כל מספר יציאה תקין. הערך הזה צריך להיות זהה לערך בשדה port במשאבי MultiClusterService.
  • ‫HOST_HEADER: התאמה לתנועה לפי שדה הכותרת של מארח ה-HTTP. השדה host הוא אופציונלי.
  • ‫PATH: התאמה של תעבורת נתונים לפי הנתיב של כתובת URL מסוג HTTP. השדה path הוא אופציונלי.
  • ‫SERVICE: השם של MultiClusterService שנפרס באותו מרחב שמות ובאותו אשכול הגדרות כמו MultiClusterIngress.

תכונות של Multi Cluster Ingress

בקטע הזה מוסבר איך להגדיר תכונות נוספות של Multi Cluster Ingress.

בחירת אשכול

כברירת מחדל, שירותים שנוצרו מ-Multi Cluster Ingress מתוזמנים בכל אשכול חבר. עם זאת, יכול להיות שתרצו להחיל כללי כניסה על אשכולות ספציפיים. הנה כמה תרחישי שימוש:

  • החלת Multi Cluster Ingress על כל האשכולות מלבד אשכול ההגדרות, כדי לבודד את אשכול ההגדרות.
  • העברת עומסי עבודה בין אשכולות בשיטת blue-green.
  • ניתוב לשרתי בק-אנד של אפליקציות שקיימים רק בקבוצת משנה של אשכולות.
  • שימוש ב-VIP יחיד ברמה 7 לניתוב מארחים או נתיבים לקצה עורפי שפועל באשכולות שונים.

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

  1. פתיחת mcs.yaml

    apiVersion: networking.gke.io/v1
    kind: MultiClusterService
    metadata:
      name: whereami-mcs
      namespace: whereami
    spec:
      template:
        spec:
          selector:
            app: whereami
          ports:
          - name: web
            protocol: TCP
            port: 8080
            targetPort: 8080
    

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

  2. מוסיפים את השורות הבאות לקטע clusters:

    apiVersion: networking.gke.io/v1
    kind: MultiClusterService
    metadata:
      name: whereami-mcs
      namespace: whereami
    spec:
      template:
        spec:
          selector:
            app: whereami
          ports:
          - name: web
            protocol: TCP
            port: 8080
            targetPort: 8080
      clusters:
      - link: "us-central1-b/gke-us"
      - link: "europe-west1-b/gke-eu"
    

    בדוגמה הזו, משאבי שירות נגזרים נוצרים רק באשכולות gke-us ו-gke-eu. כדי להחיל כללי תעבורת נתונים נכנסת באופן סלקטיבי, צריך לבחור אשכולות. אם לא צוין הקטע "clusters" ב-MultiClusterService או אם לא מופיעים אשכולות, המערכת מפרשת זאת כברירת המחדל "all" (כל האשכולות).

תמיכה ב-HTTPS

‫Kubernetes Secret תומך ב-HTTPS. לפני שמפעילים תמיכה ב-HTTPS, צריך ליצור כתובת IP סטטית. כתובת ה-IP הסטטית הזו מאפשרת ל-HTTP ול-HTTPS לשתף את אותה כתובת IP. מידע נוסף זמין במאמר יצירת כתובת IP סטטית.

אחרי שיוצרים כתובת IP סטטית, אפשר ליצור סוד.

  1. יוצרים סוד:

    kubectl -n whereami create secret tls SECRET_NAME --key PATH_TO_KEYFILE --cert PATH_TO_CERTFILE
    

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

    • SECRET_NAME בשם של הסוד.
    • ‫PATH_TO_KEYFILE מחליפים בנתיב לקובץ מפתח ה-TLS.
    • PATH_TO_CERTFILE בנתיב לקובץ אישור ה-TLS.
  2. מעדכנים את הקובץ mci.yaml עם שם הסוד:

    apiVersion: networking.gke.io/v1
    kind: MultiClusterIngress
    metadata:
      name: whereami-ingress
      namespace: whereami
      annotations:
        networking.gke.io/static-ip: STATIC_IP_ADDRESS
    spec:
      template:
        spec:
          backend:
            serviceName: whereami-mcs
            servicePort: 8080
          tls:
          - secretName: SECRET_NAME
    

    מחליפים את SECRET_NAME בשם הסוד. ‫STATIC_IP_ADDRESS היא כתובת ה-IP או כתובת ה-URL המלאה שהקציתם בקטע יצירת כתובת IP סטטית.

  3. פורסים מחדש את המשאב MultiClusterIngress:

    kubectl apply -f mci.yaml
    

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

    multiclusteringress.networking.gke.io/whereami-ingress configured
    

תמיכה ב-BackendConfig

ה-CRD הבא של BackendConfig מאפשר להתאים אישית את ההגדרות במשאב BackendService של Compute Engine:

apiVersion: cloud.google.com/v1
kind: BackendConfig
metadata:
  name: whereami-health-check-cfg
  namespace: whereami
spec:
  healthCheck:
    checkIntervalSec: [int]
    timeoutSec: [int]
    healthyThreshold: [int]
    unhealthyThreshold: [int]
    type: [HTTP | HTTPS | HTTP2 | TCP]
    port: [int]
    requestPath: [string]
  timeoutSec: [int]
  connectionDraining:
    drainingTimeoutSec: [int]
  sessionAffinity:
    affinityType: [CLIENT_IP | CLIENT_IP_PORT_PROTO | CLIENT_IP_PROTO | GENERATED_COOKIE | HEADER_FIELD | HTTP_COOKIE | NONE]
    affinityCookieTtlSec: [int]
  cdn:
    enabled: [bool]
    cachePolicy:
      includeHost: [bool]
      includeQueryString: [bool]
      includeProtocol: [bool]
      queryStringBlacklist: [string list]
      queryStringWhitelist: [string list]
  securityPolicy:
    name: ca-how-to-security-policy
  logging:
    enable: [bool]
    sampleRate: [float]
  iap:
    enabled: [bool]
    oauthclientCredentials:
      secretName: [string]

כדי להשתמש ב-BackendConfig, צריך לצרף אותו למשאב MultiClusterService באמצעות הערה:

apiVersion: networking.gke.io/v1
kind: MultiClusterService
metadata:
  name: whereami-mcs
  namespace: whereami
  annotations:
    cloud.google.com/backend-config: '{"ports": {"8080":"whereami-health-check-cfg"}}'
spec:
 template:
   spec:
     selector:
       app: whereami
     ports:
     - name: web
       protocol: TCP
       port: 8080
       targetPort: 8080

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

תמיכה ב-gRPC

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

  1. מוודאים שהתנועה ממאזן העומסים לאפליקציה היא HTTP/2. כדי להגדיר את זה, משתמשים בפרוטוקולי אפליקציה.
  2. חשוב לוודא שהאפליקציה מוגדרת כראוי ל-SSL, כי זו דרישה של HTTP/2. שימו לב: אפשר להשתמש באישורים בחתימה עצמית.
  3. צריך להשבית את mTLS באפליקציה, כי mTLS לא נתמך במאזני עומסים חיצוניים בשכבה 7.

מחזור החיים של משאב

שינויים בהגדרות

המשאבים MultiClusterIngress ו-MultiClusterService מתנהגים כאובייקטים רגילים של Kubernetes, ולכן שינויים באובייקטים משתקפים במערכת באופן אסינכרוני. כל שינוי שגורם להגדרה לא תקינה, גורם לכך שהאובייקטים המשויכים שלGoogle Cloud לא משתנים, ומופיעה שגיאה בזרם האירועים של האובייקט. שגיאות שקשורות להגדרה ידווחו כאירועים.

ניהול משאבים ב-Kubernetes

מחיקת האובייקט Ingress מסירה את מאזן העומסים מסוג HTTP(S), כך שהתנועה לא מועברת יותר לאף MultiClusterService שהוגדר.

מחיקה של MultiClusterService מסירה את השירותים הנגזרים המשויכים בכל אחד מהאשכולות.

ניהול אשכולות

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

לדוגמה, כדי להסיר את אשכול gke-eu כקצה עורפי של Ingress, מריצים את הפקודה:

gcloud container fleet memberships unregister CLUSTER_NAME \
  --gke-uri=URI

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

  • ‫CLUSTER_NAME: השם של האשכול.
  • ‫URI: ה-URI של אשכול GKE.

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

gcloud container fleet memberships register europe-cluster \
  --context=europe-cluster --enable-workload-identity

מידע נוסף על אפשרויות רישום האשכול זמין במאמר רישום אשכול GKE.

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

השבתת Multi Cluster Ingress

לפני שמשביתים את Multi Cluster Ingress, צריך למחוק את המשאבים MultiClusterIngress ו-MultiClusterService ולוודא שכל משאבי הרשת שמשויכים אליהם נמחקו.

כדי להשבית את Multi Cluster Ingress, משתמשים בפקודה הבאה:

gcloud container fleet ingress disable

אם לא תמחקו את המשאבים MultiClusterIngress ו-MultiClusterService לפני השבתת Multi Cluster Ingress, יכול להיות שתיתקלו בשגיאה דומה לזו שמופיעה בהמשך:

Feature has associated resources that should be cleaned up before deletion.

כדי להשבית את Multi Cluster Ingress באופן מאולץ, משתמשים בפקודה הבאה:

gcloud container fleet ingress disable --force

הערות

ההערות הבאות נתמכות במשאבי MultiClusterIngress ו-MultiClusterService.

הערות של MultiClusterIngress

הערה תיאור
networking.gke.io/frontend-config מפנה אל משאב FrontendConfig באותו מרחב שמות כמו משאב MultiClusterIngress.
networking.gke.io/static-ip מתייחס לכתובת ה-IP המילולית של כתובת IP סטטית גלובלית.
networking.gke.io/pre-shared-certs הפניה למשאב SSLCertificate גלובלי.

הערות MultiClusterService

הערה תיאור
networking.gke.io/app-protocols משתמשים בהערה הזו כדי להגדיר את הפרוטוקול לתקשורת בין מאזן העומסים לבין האפליקציה. הפרוטוקולים האפשריים הם HTTP,‏ HTTPS ו-HTTP/2. אפשר לקרוא מידע נוסף במאמרים HTTPS בין מאזן העומסים לבין האפליקציה ו-HTTP/2 לאיזון עומסים עם Ingress.
cloud.google.com/backend-config משתמשים באנוטציה הזו כדי להגדיר את שירות לקצה העורפי שמשויך ל-servicePort. מידע נוסף זמין במאמר בנושא הגדרת Ingress.

מדיניות SSL והפניות אוטומטיות של HTTPS

אתם יכולים להשתמש במשאב FrontendConfig כדי להגדיר מדיניות SSL והפניות אוטומטיות ל-HTTPS. כללי מדיניות SSL מאפשרים לכם לציין אילו סטים של אלגוריתמים להצפנה (cipher suite) וגרסאות TLS מאזן העומסים מקבל. הפניות אוטומטיות ל-HTTPS מאפשרות לאכוף את ההפניה האוטומטית מ-HTTP או מיציאה 80 ל-HTTPS או ליציאה 443. בשלבים הבאים מוסבר איך להגדיר מדיניות SSL והפניה אוטומטית ל-HTTPS ביחד. שימו לב שאפשר גם להגדיר אותם בנפרד.

  1. יוצרים מדיניות SSL שתדחה בקשות שמשתמשות בגרסה נמוכה מ-TLS v1.2.

    gcloud compute ssl-policies create tls-12-policy \
     --profile MODERN \
     --min-tls-version 1.2 \
     --project=PROJECT_ID
    

    מחליפים את PROJECT_ID במזהה הפרויקט שבו פועלים אשכולות GKE.

  2. כדאי לעיין במדיניות כדי לוודא שהיא נוצרה.

    gcloud compute ssl-policies list --project=PROJECT_ID
    

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

    NAME           PROFILE  MIN_TLS_VERSION
    tls-12-policy  MODERN   TLS_1_2
    
  3. יוצרים אישור ל-foo.example.com כמו בדוגמה. אחרי שמקבלים את key.pem ואת cert.pem, מאחסנים את פרטי הכניסה האלה כסוד שיהיה הפניה למשאב MultiClusterIngress.

    kubectl -n whereami create secret tls SECRET_NAME --key key.pem --cert cert.pem
    
  4. שומרים את המשאב הבא של FrontendConfig בתור frontendconfig.yaml. מידע נוסף על השדות הנתמכים ב-FrontendConfig זמין במאמר הגדרת משאבי FrontendConfig.

    apiVersion: networking.gke.io/v1beta1
    kind: FrontendConfig
    metadata:
      name: frontend-redirect-tls-policy
      namespace: whereami
    spec:
      sslPolicy: tls-12-policy
      redirectToHttps:
        enabled: true
    

    ההגדרה הזו של FrontendConfig תפעיל הפניות אוטומטיות של HTTPS ומדיניות SSL שתאכוף גרסת TLS מינימלית של 1.2.

  5. פורסים את frontendconfig.yaml באשכול ההגדרות האישיות.

    kubectl apply -f frontendconfig.yaml --context MCI_CONFIG_CLUSTER
    

    מחליפים את MCI_CONFIG_CLUSTER בשם של אשכול ההגדרות.

  6. שומרים את ה-MultiClusterIngress הבא בתור mci-frontendconfig.yaml.

    apiVersion: networking.gke.io/v1
    kind: MultiClusterIngress
    metadata:
      name: foo-ingress
      namespace: whereami
      annotations:
        networking.gke.io/frontend-config: frontend-redirect-tls-policy
        networking.gke.io/static-ip: STATIC_IP_ADDRESS
    spec:
      template:
        spec:
          backend:
            serviceName: default-backend
            servicePort: 8080
          rules:
          - host: foo.example.com
            http:
              paths:
                - backend:
                    serviceName: whereami-mcs
                    servicePort: 8080
          tls:
          - secretName: SECRET_NAME
    
    • מחליפים את STATIC_IP_ADDRESS בכתובת IP גלובלית סטטית שכבר הקציתם.
    • מחליפים את SECRET_NAME ב-Secret שבו מאוחסן האישור foo.example.com.

    יש שתי דרישות להפעלת הפניות אוטומטיות ל-HTTPS:

    • צריך להפעיל את TLS, דרך השדה spec.tls או דרך ההערה networking.gke.io/pre-shared-certs של האישור ששותף מראש. הפריסה של MultiClusterIngress לא תתבצע אם הפניות אוטומטיות ל-HTTPS מופעלות אבל HTTPS לא מופעל.
    • צריך להפנות לכתובת IP סטטית באמצעות ההערה networking.gke.io/static-ip. כשמפעילים HTTPS ב-MultiClusterIngress, צריך להשתמש בכתובות IP סטטיות.
  7. פורסים את MultiClusterIngress באשכול התצורה.

    kubectl apply -f mci-frontendconfig.yaml --context MCI_CONFIG_CLUSTER
    
  8. מחכים דקה או שתיים ובודקים את foo-ingress.

    kubectl describe mci foo-ingress --context MCI_CONFIG_CLUSTER
    

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

    • הסטטוס Cloud Resources מאוכלס בשמות של משאבים
    • השדה VIP מאוכלס בכתובת ה-IP של מאזן העומסים
    Name:         foobar-ingress
    Namespace:    whereami
    
    ...
    
    Status:
      Cloud Resources:
        Backend Services:
          mci-otn9zt-8080-whereami-bar
          mci-otn9zt-8080-whereami-default-backend
          mci-otn9zt-8080-whereami-foo
        Firewalls:
          mci-otn9zt-default-l7
        Forwarding Rules:
          mci-otn9zt-fw-whereami-foobar-ingress
          mci-otn9zt-fws-whereami-foobar-ingress
        Health Checks:
          mci-otn9zt-8080-whereami-bar
          mci-otn9zt-8080-whereami-default-backend
          mci-otn9zt-8080-whereami-foo
        Network Endpoint Groups:
          zones/europe-west1-b/networkEndpointGroups/k8s1-1869d397-multi-cluste-mci-default-backend-svc--80-9e362e3d
          zones/europe-west1-b/networkEndpointGroups/k8s1-1869d397-multi-cluster--mci-bar-svc-067a3lzs8-808-89846515
          zones/europe-west1-b/networkEndpointGroups/k8s1-1869d397-multi-cluster--mci-foo-svc-820zw3izx-808-8bbcb1de
          zones/us-central1-b/networkEndpointGroups/k8s1-a63e24a6-multi-cluste-mci-default-backend-svc--80-a528cc75
          zones/us-central1-b/networkEndpointGroups/k8s1-a63e24a6-multi-cluster--mci-bar-svc-067a3lzs8-808-36281739
          zones/us-central1-b/networkEndpointGroups/k8s1-a63e24a6-multi-cluster--mci-foo-svc-820zw3izx-808-ac733579
        Target Proxies:
          mci-otn9zt-whereami-foobar-ingress
          mci-otn9zt-whereami-foobar-ingress
        URL Map:  mci-otn9zt-rm-whereami-foobar-ingress
      VIP:        34.149.29.76
    Events:
      Type     Reason  Age                From                              Message
      ----     ------  ----               ----                              -------
      Normal   UPDATE  38m (x5 over 62m)  multi-cluster-ingress-controller  whereami/foobar-ingress
    
  9. כדי לוודא שההפניות האוטומטיות של HTTPS פועלות בצורה תקינה, שולחים בקשת HTTP דרך curl.

    curl VIP
    

    מחליפים את VIP בכתובת ה-IP של MultiClusterIngress.

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

  10. כדי לוודא שמדיניות TLS פועלת בצורה תקינה, שולחים בקשת HTTPS באמצעות TLS בגרסה 1.1. מכיוון ש-DNS לא מוגדר לדומיין הזה, צריך להשתמש באפשרות --resolve כדי להנחות את curl לתרגם את כתובת ה-IP ישירות.

    curl https://foo.example.com --resolve foo.example.com:443:VIP --cacert CERT_FILE -v
    

    בשלב הזה צריך להשתמש בקובץ ה-PEM של האישור שמשמש לאבטחת MultiClusterIngress. פלט מוצלח ייראה כך:

    ...
    * SSL connection using TLSv1.2 / ECDHE-RSA-CHACHA20-POLY1305
    * ALPN, server accepted to use h2
    * Server certificate:
    *  subject: O=example; CN=foo.example.com
    *  start date: Sep  1 10:32:03 2021 GMT
    *  expire date: Aug 27 10:32:03 2022 GMT
    *  common name: foo.example.com (matched)
    *  issuer: O=example; CN=foo.example.com
    *  SSL certificate verify ok.
    * Using HTTP2, server supports multi-use
    * Connection state changed (HTTP/2 confirmed)
    * Copying HTTP/2 data in stream buffer to connection buffer after upgrade: len=0
    * Using Stream ID: 1 (easy handle 0x7fa10f00e400)
    > GET / HTTP/2
    > Host: foo.example.com
    > User-Agent: curl/7.64.1
    > Accept: */*
    >
    * Connection state changed (MAX_CONCURRENT_STREAMS == 100)!
    < HTTP/2 200
    < content-type: application/json
    < content-length: 308
    < access-control-allow-origin: *
    < server: Werkzeug/1.0.1 Python/3.8.6
    < date: Wed, 01 Sep 2021 11:39:06 GMT
    < via: 1.1 google
    < alt-svc: clear
    <
    {"cluster_name":"gke-us","host_header":"foo.example.com","metadata":"foo","node_name":"gke-gke-us-default-pool-22cb07b1-r5r0.c.mark-church-project.internal","pod_name":"foo-75ccd9c96d-dkg8t","pod_name_emoji":"👞","project_id":"mark-church-project","timestamp":"2021-09-01T11:39:06","zone":"us-central1-b"}
    * Connection #0 to host foo.example.com left intact
    * Closing connection 0
    

    קוד התגובה הוא 200 ונעשה שימוש ב-TLSv1.2, מה שמצביע על כך שהכול פועל כמו שצריך.

    אחר כך אפשר לוודא שמדיניות ה-SSL אוכפת את גרסת ה-TLS הנכונה על ידי ניסיון להתחבר באמצעות TLS 1.1. כדי שהשלב הזה יעבוד, צריך להגדיר את מדיניות ה-SSL לגרסה 1.2 לפחות.

  11. שולחים את אותה בקשה מהשלב הקודם, אבל אוכפים גרסת TLS של 1.1.

    curl https://foo.example.com --resolve foo.example.com:443:VIP -v \
      --cacert CERT_FILE \
      --tls-max 1.1
    

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

    * Added foo.example.com:443:34.149.29.76 to DNS cache
    * Hostname foo.example.com was found in DNS cache
    *   Trying 34.149.29.76...
    * TCP_NODELAY set
    * Connected to foo.example.com (34.149.29.76) port 443 (#0)
    * ALPN, offering h2
    * ALPN, offering http/1.1
    * successfully set certificate verify locations:
    *   CAfile: cert.pem
      CApath: none
    * TLSv1.1 (OUT), TLS handshake, Client hello (1):
    * TLSv1.1 (IN), TLS alert, protocol version (582):
    * error:1400442E:SSL routines:CONNECT_CR_SRVR_HELLO:tlsv1 alert protocol version
    * Closing connection 0
    curl: (35) error:1400442E:SSL routines:CONNECT_CR_SRVR_HELLO:tlsv1 alert protocol version
    

    הכשל בהשלמת לחיצת יד בפרוטוקול TLS מציין שמדיניות ה-SSL חסמה את TLS 1.1 בהצלחה.

יצירת כתובת IP סטטית

  1. מקצים כתובת IP סטטית:

    gcloud compute addresses create ADDRESS_NAME --global
    

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

    הפלט מכיל את כתובת ה-URL המלאה של הכתובת שיצרתם, בדומה לכתובת הבאה:

    Created [https://www.googleapis.com/compute/v1/projects/PROJECT_ID/global/addresses/ADDRESS_NAME].
    
  2. כדי לראות את כתובת ה-IP שיצרתם:

    gcloud compute addresses list
    

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

    NAME          ADDRESS/RANGE  TYPE      STATUS
    ADDRESS_NAME  STATIC_IP_ADDRESS  EXTERNAL  RESERVED
    

    הפלט הזה כולל:

    • הערך של ADDRESS_NAME שהגדרתם.
    • הוקצו STATIC_IP_ADDRESS.
  3. מעדכנים את הקובץ mci.yaml עם כתובת ה-IP הסטטית:

    apiVersion: networking.gke.io/v1
    kind: MultiClusterIngress
    metadata:
      name: whereami-ingress
      namespace: whereami
      annotations:
        networking.gke.io/static-ip: STATIC_IP_ADDRESS
    spec:
      template:
        spec:
          backend:
            serviceName: whereami-mcs
            servicePort: 8080
    

    מחליפים את STATIC_IP_ADDRESS באחד מהערכים הבאים:

    • כתובת ה-IP שהוקצתה, בדומה ל: 34.102.201.47
    • כתובת ה-URL המלאה של הכתובת שיצרתם, בדומה לכתובת הבאה: "https://www.googleapis.com/compute/v1/projects/PROJECT_ID/global/addresses/ADDRESS_NAME"

    הערך STATIC_IP_ADDRESS הוא לא שם המשאב (ADDRESS_NAME).

  4. פורסים מחדש את המשאב MultiClusterIngress:

    kubectl apply -f mci.yaml
    

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

    multiclusteringress.networking.gke.io/whereami-ingress configured
    
  5. פועלים לפי השלבים במאמר אימות סטטוס פריסה מוצלחת כדי לוודא שהפריסה משרתת את STATIC_IP_ADDRESS.

אישורים ששותפו מראש

אישורים ששותפו מראש הם אישורים שהועלו אל Google Cloud , שבהם מאזן העומסים יכול להשתמש לסיום TLS במקום אישורים שמאוחסנים ב-Kubernetes Secrets. האישורים האלה מועלים מחוץ לפס מ-GKE אל Google Cloud ומקושרים למשאב MultiClusterIngress. יש גם תמיכה בכמה אישורים, באמצעות אישורים ששותפו מראש או סודות של Kubernetes.

כדי להשתמש באישורים ב-Multi Cluster Ingress, צריך את ההערה networking.gke.io/pre-shared-certs ואת שמות האישורים. כשמציינים כמה אישורים ל-MultiClusterIngress מסוים, סדר שנקבע מראש קובע איזה אישור יוצג ללקוח.

כדי להציג את רשימת אישורי ה-SSL הזמינים, מריצים את הפקודה:

gcloud compute ssl-certificates list

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

kind: MultiClusterIngress
metadata:
  name: shopping-service
  namespace: whereami
  annotations:
    networking.gke.io/pre-shared-certs: "domain1-cert, domain2-cert"
spec:
  template:
    spec:
      rules:
      - host: my-domain1.gcp.com
        http:
          paths:
          - backend:
              serviceName: domain1-svc
              servicePort: 443
      - host: my-domain2.gcp.com
        http:
          paths:
          - backend:
              serviceName: domain2-svc
              servicePort: 443

אישורים שמנוהלים על ידי Google

אישורים שמנוהלים על ידי Google נתמכים במשאבי MultiClusterIngress באמצעות ההערה networking.gke.io/pre-shared-certs. ‫Multi Cluster Ingress תומך בצירוף אישורים שמנוהלים על ידי Google למשאב MultiClusterIngress, אבל בניגוד ל-Ingress של אשכול יחיד, יצירה הצהרתית של משאב ManagedCertificate ב-Kubernetes לא נתמכת במשאבי MultiClusterIngress. צריך ליצור את האישור המנוהל על ידי Google ישירות דרך compute ssl-certificates create API לפני שאפשר לצרף אותו ל-MultiClusterIngress. כדי לעשות את זה:

  1. יוצרים אישור שמנוהל על ידי Google כמו שמתואר בשלב 1 כאן. אל תעברו לשלב 2, כי Multi Cluster Ingress יצרף את האישור הזה בשבילכם.

    gcloud compute ssl-certificates create my-google-managed-cert \
        --domains=my-domain.gcp.com \
        --global
    
  2. מפנים לשם של האישור ב-MultiClusterIngress באמצעות ההערה networking.gke.io/pre-shared-certs.

    kind: MultiClusterIngress
    metadata:
    name: shopping-service
    namespace: whereami
    annotations:
      networking.gke.io/pre-shared-certs: "my-google-managed-cert"
    spec:
    template:
      spec:
        rules:
        - host: my-domain.gcp.com
          http:
            paths:
            - backend:
                serviceName: my-domain-svc
                servicePort: 8080
    

המניפסט הקודם מצרף את האישור ל-MultiClusterIngress, כדי שיוכל לסיים את התנועה לאשכולות ה-GKE לקצה העורפי. האישור יחודש אוטומטית על ידיGoogle Cloud לפני שיפוג תוקפו. החידושים מתבצעים באופן שקוף ולא נדרשים עדכונים ל-Multi Cluster Ingress.

פרוטוקולים של אפליקציות

החיבור משרת ה-proxy של מאזן העומסים לאפליקציה משתמש ב-HTTP כברירת מחדל. באמצעות ההערה networking.gke.io/app-protocols, אתם יכולים להגדיר את מאזן העומסים כך שישתמש ב-HTTPS או ב-HTTP/2 כשהוא מעביר בקשות לאפליקציה. בדוגמה הבאה, בשדה annotation, http2 מתייחס לשם היציאה MultiClusterService ו-HTTP2 מתייחס לפרוטוקול שבו מאזן העומסים משתמש.

kind: MultiClusterService
metadata:
  name: shopping-service
  namespace: whereami
  annotations:
    networking.gke.io/app-protocols: '{"http2":"HTTP2"}'
spec:
  template:
    spec:
      ports:
      - port: 443
        name: http2

BackendConfig

בקטע שלמעלה מוסבר איך להגדיר את ההערה.

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