פריסת שער חיצוני מרובה אשכולות

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

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

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

בדוגמה הזו מוסבר איך להגדיר ניתוב מבוסס-נתיב כדי להפנות תנועה לאשכולות שונים.

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

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

  1. פריסה של אשכולות GKE.

  2. רושמים את האשכולות ב-Fleet (אם הם עדיין לא רשומים).

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

לבסוף, מומלץ לעיין במגבלות ובבעיות הידועות של GKE Gateway Controller לפני שמשתמשים בבקר בסביבה שלכם.

שער חיצוני של אשכול מרובה ואזור מרובה

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

האפליקציה store.example.com נפרסת בשני אשכולות GKE ונחשפת לאינטרנט באמצעות שער מרובה אשכולות

בשלבים הבאים:

  1. פורסים את אפליקציית הדוגמה store באשכולות gke-west-1 ו-gke-east-1.
  2. מגדירים את השירותים בכל אשכול לייצוא לצי (שירותים מרובי אשכולות).
  3. פריסת שער חיצוני מרובה אשכולות ו-HTTPRoute באשכול ההגדרות (gke-west-1).

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

  • בקשות אל /west מנותבות אל store Pods באשכול gke-west-1.
  • בקשות אל /east מנותבות אל תרמילי store באשכול gke-east-1.
  • בקשות לנתיב אחר מנותבות לאחד מהאשכולות, בהתאם למצב, לקיבולת ולקרבה ללקוח ששולח את הבקשה.

פריסת אפליקציית ההדגמה

  1. יוצרים את store Deployment ואת Namespace בכל שלושת האשכולות שנפרסו בהכנת הסביבה לשימוש בשערי Multi-cluster:

    kubectl apply --context gke-west-1 -f https://raw.githubusercontent.com/GoogleCloudPlatform/gke-networking-recipes/main/gateway/gke-gateway-controller/multi-cluster-gateway/store.yaml
    kubectl apply --context gke-west-2 -f https://raw.githubusercontent.com/GoogleCloudPlatform/gke-networking-recipes/main/gateway/gke-gateway-controller/multi-cluster-gateway/store.yaml
    kubectl apply --context gke-east-1 -f https://raw.githubusercontent.com/GoogleCloudPlatform/gke-networking-recipes/main/gateway/gke-gateway-controller/multi-cluster-gateway/store.yaml
    

    הוא פורס את המשאבים הבאים בכל אשכול:

    namespace/store created
    deployment.apps/store created
    

    כל הדוגמאות בדף הזה מתייחסות לאפליקציה שנפרסה בשלב הזה. לפני שמנסים לבצע את השלבים הבאים, חשוב לוודא שהאפליקציה נפרסה בכל שלושת האשכולות. בדוגמה הזו נעשה שימוש רק באשכולות gke-west-1 ו-gke-east-1, וב-gke-west-2 נעשה שימוש בדוגמה אחרת.

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

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

Multi-cluster Services (MCS) הוא תקן API לשירותים שפועלים באשכולות, והבקר של GKE מספק גילוי שירותים באשכולות GKE. הבקר של שער מרובה אשכולות משתמש במשאבי MCS API כדי לקבץ Pods לשירות שאפשר לפנות אליו באשכולות מרובים או בטווח של אשכולות מרובים.

ב-multi-cluster Services API מוגדרים המשאבים המותאמים אישית הבאים:

  • ServiceExports ממופים לשירות Kubernetes, ומייצאים את נקודות הקצה של השירות הזה לכל האשכולות שרשומים בצי. כששירות מסוים כולל ServiceExport תואם, המשמעות היא שאפשר לפנות לשירות באמצעות שער מרובה אשכולות.
  • ServiceImports נוצרים באופן אוטומטי על ידי בקר השירות מרובה האשכולות. ‫ServiceExport ו-ServiceImport מגיעים כזוג. אם קיים ServiceExport בצי, נוצר ServiceImport תואם כדי לאפשר גישה לשירות שממופה ל-ServiceExport מכל האשכולות.

ייצוא שירותים פועל באופן הבא. שירות של חנות קיים ב-gke-west-1, והוא בוחר קבוצת Pod באותו אשכול. אובייקט ServiceExport נוצר באשכול, ומאפשר גישה לקבוצות ה-Pod ב-gke-west-1 מאשכולות אחרים בצי. המשאב ServiceExport ממפה ומציג שירותים שיש להם את אותו שם ואת אותו מרחב שמות כמו למשאב ServiceExport.

apiVersion: v1
kind: Service
metadata:
  name: store
  namespace: store
spec:
  selector:
    app: store
  ports:
  - port: 8080
    targetPort: 8080
---
kind: ServiceExport
apiVersion: net.gke.io/v1
metadata:
  name: store
  namespace: store

בתרשים הבא מוצג מה קורה אחרי פריסה של ServiceExport. אם קיימים זוג של ServiceExport ו-Service, בקר השירות של כמה אשכולות פורס ServiceImport תואם לכל אשכול GKE בצי. ‫ServiceImport הוא הייצוג המקומי של store Service בכל אשכול. ההגדרה הזו מאפשרת ל-client Pod ב-gke-east-1 להשתמש בשירותים מסוג ClusterIP או בשירותים ללא כתובת IP כדי להגיע ל-Pods של store ב-gke-west-1. כשמשתמשים בשירותים מרובי-אשכולות באופן הזה, הם מספקים איזון עומסים ממזרח למערב בין האשכולות בלי שנדרש שירות LoadBalancer פנימי. כדי להשתמש בשירותים מרובי-אשכולות לאיזון עומסים בין אשכולות, אפשר לעיין במאמר הגדרת שירותים מרובי-אשכולות.

שירותים מרובי אשכולות מייצאים שירותים בין אשכולות, מה שמאפשר תקשורת בין אשכולות

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

kind: HTTPRoute
apiVersion: gateway.networking.k8s.io/v1
metadata:
  name: store-route
  namespace: store
  labels:
    gateway: multi-cluster-gateway
spec:
  parentRefs:
  - kind: Gateway
    namespace: store
    name: external-http
  hostnames:
  - "store.example.com"
  rules:
  - backendRefs:
    - group: net.gke.io
      kind: ServiceImport
      name: store
      port: 8080

הדיאגרמה הבאה מציגה איך HTTPRoute מנתב store.example.com תנועה ל-Pods store ב-gke-west-1 וב-gke-east-1. מאזן העומסים מתייחס אליהם כאל מאגר אחד של שרתי בק-אנד. אם מצב ה-Pods באחד מהאשכולות לא תקין, אם אי אפשר להגיע אליהם או אם אין להם קיבולת תעבורה, עומס התעבורה מתאזן בין ה-Pods שנותרו באשכול השני. אפשר להוסיף או להסיר אשכולות חדשים באמצעות store Service ו-ServiceExport. הפעולה הזו מוסיפה או מסירה באופן שקוף Pods של קצה עורפי בלי שנדרשים שינויים בהגדרות הניתוב.

משאב MCS

ייצוא שירותים

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

  1. מחילים את המניפסט הבא על אשכול gke-west-1 כדי ליצור את השירותים store ו-ServiceExports‏ store-west-1:

    cat << EOF | kubectl apply --context gke-west-1 -f -
    apiVersion: v1
    kind: Service
    metadata:
      name: store
      namespace: store
    spec:
      selector:
        app: store
      ports:
      - port: 8080
        targetPort: 8080
    ---
    kind: ServiceExport
    apiVersion: net.gke.io/v1
    metadata:
      name: store
      namespace: store
    ---
    apiVersion: v1
    kind: Service
    metadata:
      name: store-west-1
      namespace: store
    spec:
      selector:
        app: store
      ports:
      - port: 8080
        targetPort: 8080
    ---
    kind: ServiceExport
    apiVersion: net.gke.io/v1
    metadata:
      name: store-west-1
      namespace: store
    EOF
    
  2. מחילים את המניפסט הבא על אשכול gke-east-1 כדי ליצור את השירותים store ו-ServiceExports‏ store-east-1:

    cat << EOF | kubectl apply --context gke-east-1 -f -
    apiVersion: v1
    kind: Service
    metadata:
      name: store
      namespace: store
    spec:
      selector:
        app: store
      ports:
      - port: 8080
        targetPort: 8080
    ---
    kind: ServiceExport
    apiVersion: net.gke.io/v1
    metadata:
      name: store
      namespace: store
    ---
    apiVersion: v1
    kind: Service
    metadata:
      name: store-east-1
      namespace: store
    spec:
      selector:
        app: store
      ports:
      - port: 8080
        targetPort: 8080
    ---
    kind: ServiceExport
    apiVersion: net.gke.io/v1
    metadata:
      name: store-east-1
      namespace: store
    EOF
    
  3. מוודאים שנוצרו האובייקטים הנכונים של ServiceExport באשכולות.

    kubectl get serviceexports --context CLUSTER_NAME --namespace store
    

    מחליפים את CLUSTER_NAME ב-gke-west-1 וב-gke-east-1. הפלט אמור להיראות כך:

    # gke-west-1
    NAME           AGE
    store          2m40s
    store-west-1   2m40s
    
    # gke-east-1
    NAME           AGE
    store          2m25s
    store-east-1   2m25s
    

    הפלט מראה ששירות store מכיל store Pods בשני האשכולות, וששירותים store-west-1 ו-store-east-1 מכילים רק store Pods באשכולות שלהם. השירותים החופפים האלה משמשים לטירגוט של ה-Pods בכמה אשכולות או בקבוצת משנה של Pods באשכול יחיד.

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

    kubectl get serviceimports --context CLUSTER_NAME --namespace store
    

    מחליפים את CLUSTER_NAME ב-gke-west-1 וב-gke-east-1. הפלט אמור להיראות כך:

    # gke-west-1
    NAME           TYPE           IP                  AGE
    store          ClusterSetIP   ["10.112.31.15"]    6m54s
    store-east-1   ClusterSetIP   ["10.112.26.235"]   5m49s
    store-west-1   ClusterSetIP   ["10.112.16.112"]   6m54s
    
    # gke-east-1
    NAME           TYPE           IP                  AGE
    store          ClusterSetIP   ["10.72.28.226"]    5d10h
    store-east-1   ClusterSetIP   ["10.72.19.177"]    5d10h
    store-west-1   ClusterSetIP   ["10.72.28.68"]     4h32m
    

    הדוגמה הזו מראה שניתן לגשת לכל שלושת השירותים משני האשכולות בצי. עם זאת, מכיוון שיש רק אשכול תצורה פעיל אחד לכל צי, אפשר לפרוס רק שערים ו-HTTPRoute שמפנים אל ServiceImports האלה ב-gke-west-1. כש-HTTPRoute באשכול ההגדרות מפנה אל ServiceImports האלה כאל קצה עורפי, ה-Gateway יכול להעביר תנועה לשירותים האלה בלי קשר לאשכול שממנו הם יוצאו.

פריסת ה-Gateway וה-HTTPRoute

אחרי שפורסים את האפליקציות, אפשר להגדיר שער באמצעות gke-l7-global-external-managed-mc GatewayClass. השער הזה יוצר מאזן עומסים חיצוני של אפליקציות (ALB) שמוגדר להפצת תנועה בין אשכולות היעד.

  1. מחילים את Gatewayהמניפסטgke-west-1 הבא על אשכול ההגדרות, gke-west-1בדוגמה הזו:

    cat << EOF | kubectl apply --context gke-west-1 -f -
    kind: Gateway
    apiVersion: gateway.networking.k8s.io/v1
    metadata:
      name: external-http
      namespace: store
    spec:
      gatewayClassName: gke-l7-global-external-managed-mc
      listeners:
      - name: http
        protocol: HTTP
        port: 80
        allowedRoutes:
          kinds:
          - kind: HTTPRoute
    EOF
    

    הגדרת שער כזו פורסת משאבים של מאזן עומסים חיצוני של אפליקציות (ALB) עם מוסכמת השמות הבאה: gkemcg1-NAMESPACE-GATEWAY_NAME-HASH.

    משאבי ברירת המחדל שנוצרים עם ההגדרה הזו הם:

    • מאזן עומסים אחד: gkemcg1-store-external-http-HASH
    • כתובת IP ציבורית אחת: gkemcg1-store-external-http-HASH
    • כלל העברה אחד: gkemcg1-store-external-http-HASH
    • ‫2 שירותים לקצה העורפי:
      • שירות ברירת המחדל לקצה העורפי של דף 404: gkemcg1-store-gw-serve404-HASH
      • ברירת מחדל של 500 שירותים לקצה העורפי: gkemcg1-store-gw-serve500-HASH
    • בדיקת תקינות אחת:
      • בדיקת תקינות של דף 404 שמוגדר כברירת מחדל: gkemcg1-store-gw-serve404-HASH
    • ‫0 כללי ניתוב (מיפוי כתובות ה-URL ריק)

    בשלב הזה, כל בקשה ל-GATEWAY_IP:80 תוביל להצגת דף ברירת מחדל עם ההודעה הבאה: fault filter abort.

  2. מחילים את HTTPRouteהמניפסטgke-west-1 הבא על אשכול ההגדרות, gke-west-1בדוגמה הזו:

    cat << EOF | kubectl apply --context gke-west-1 -f -
    kind: HTTPRoute
    apiVersion: gateway.networking.k8s.io/v1
    metadata:
      name: public-store-route
      namespace: store
      labels:
        gateway: external-http
    spec:
      hostnames:
      - "store.example.com"
      parentRefs:
      - name: external-http
      rules:
      - matches:
        - path:
            type: PathPrefix
            value: /west
        backendRefs:
        - group: net.gke.io
          kind: ServiceImport
          name: store-west-1
          port: 8080
      - matches:
        - path:
            type: PathPrefix
            value: /east
        backendRefs:
          - group: net.gke.io
            kind: ServiceImport
            name: store-east-1
            port: 8080
      - backendRefs:
        - group: net.gke.io
          kind: ServiceImport
          name: store
          port: 8080
    EOF
    

    בשלב הזה, כל בקשה ל-GATEWAY_IP:80 תוביל להצגת דף ברירת מחדל עם ההודעה הבאה: fault filter abort.

    אחרי הפריסה, ההגדרה של HTTPRoute קובעת את התנהגות הניתוב הבאה:

    • הבקשות אל /west מנותבות אל קבוצות ה-Pod‏ store באשכול gke-west-1, כי קבוצות ה-Pod שנבחרו על ידי ServiceExport‏ store-west-1 קיימות רק באשכול gke-west-1.
    • הבקשות אל /east מנותבות אל קבוצות ה-Pod‏ store באשכול gke-east-1, כי קבוצות ה-Pod שנבחרו על ידי ServiceExport‏ store-east-1 קיימות רק באשכול gke-east-1.
    • בקשות לכל נתיב אחר מנותבות ל-Pods של store באחד מהאשכולות, בהתאם למצב התקינות, לקיבולת ולקרבה ללקוח ששולח את הבקשה.
    • בקשות אל GATEWAY_IP:80 מובילות להצגת דף ברירת מחדל עם ההודעה הבאה: fault filter abort.

    ה-HTTPRoute מאפשר ניתוב לקבוצות משנה שונות של אשכולות באמצעות חפיפה של שירותים

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

    נוצרים משאבים חדשים עם ההגדרה הזו:

    • ‫3 שירותים לקצה העורפי:
      • השירות לקצה העורפי: storegkemcg1-store-store-8080-HASH
      • השירות לקצה העורפי: store-east-1gkemcg1-store-store-east-1-8080-HASH
      • השירות לקצה העורפי: store-west-1gkemcg1-store-store-west-1-8080-HASH
    • 3 בדיקות תקינות:
      • בדיקת התקינות store: gkemcg1-store-store-8080-HASH
      • בדיקת התקינות store-east-1: gkemcg1-store-store-east-1-8080-HASH
      • בדיקת התקינות store-west-1: gkemcg1-store-store-west-1-8080-HASH
    • כלל ניתוב אחד במיפוי כתובות ה-URL:
      • store.example.com כלל הניתוב:
      • מארח אחד: store.example.com
      • ‫Multiple matchRules כדי לנתב לשירותי הקצה העורפי החדשים

הדיאגרמה הבאה מציגה את המשאבים שפרסתם בשני האשכולות. ‫gke-west-1 הוא אשכול ההגדרות של שער הכניסה, ולכן זה האשכול שבו בקר שער הכניסה עוקב אחרי שער הכניסה, HTTPRoutes ו-ServiceImports. לכל אשכול יש ServiceImport אחד ועוד ServiceImport שספציפי לאותו אשכול.store שניהם מצביעים על אותם תרמילים. כך אפשר לציין ב-HTTPRoute בדיוק לאן תעבורת הנתונים צריכה להגיע – ל-Pods של store באשכול ספציפי או ל-Pods של store בכל האשכולות.

זהו מודל המשאבים של Gateway ושל שירותים מרובי אשכולות בשני האשכולות

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

אימות הפריסה

מעכשיו אפשר לשלוח בקשות אל שער הכניסה (Gateway) הרב-אשכולי שלנו ולחלק את התנועה בין שני אשכולות GKE.

  1. כדי לוודא שהפריסה של Gateway ו-HTTPRoute בוצעה בהצלחה, בודקים את הסטטוס והאירועים של Gateway.

    kubectl describe gateways.gateway.networking.k8s.io external-http --context gke-west-1 --namespace store
    

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

    Name:         external-http
    Namespace:    store
    Labels:       <none>
    Annotations:  networking.gke.io/addresses: /projects/PROJECT_NUMBER/global/addresses/gkemcg1-store-external-http-laup24msshu4
                  networking.gke.io/backend-services:
                    /projects/PROJECT_NUMBER/global/backendServices/gkemcg1-store-gw-serve404-80-n65xmts4xvw2, /projects/PROJECT_NUMBER/global/backendServices/gke...
                  networking.gke.io/firewalls: /projects/PROJECT_NUMBER/global/firewalls/gkemcg1-l7-default-global
                  networking.gke.io/forwarding-rules: /projects/PROJECT_NUMBER/global/forwardingRules/gkemcg1-store-external-http-a5et3e3itxsv
                  networking.gke.io/health-checks:
                    /projects/PROJECT_NUMBER/global/healthChecks/gkemcg1-store-gw-serve404-80-n65xmts4xvw2, /projects/PROJECT_NUMBER/global/healthChecks/gkemcg1-s...
                  networking.gke.io/last-reconcile-time: 2023-10-12T17:54:24Z
                  networking.gke.io/ssl-certificates:
                  networking.gke.io/target-http-proxies: /projects/PROJECT_NUMBER/global/targetHttpProxies/gkemcg1-store-external-http-94oqhkftu5yz
                  networking.gke.io/target-https-proxies:
                  networking.gke.io/url-maps: /projects/PROJECT_NUMBER/global/urlMaps/gkemcg1-store-external-http-94oqhkftu5yz
    API Version:  gateway.networking.k8s.io/v1
    Kind:         Gateway
    Metadata:
      Creation Timestamp:  2023-10-12T06:59:32Z
      Finalizers:
        gateway.finalizer.networking.gke.io
      Generation:        1
      Resource Version:  467057
      UID:               1dcb188e-2917-404f-9945-5f3c2e907b4c
    Spec:
      Gateway Class Name:  gke-l7-global-external-managed-mc
      Listeners:
        Allowed Routes:
          Kinds:
            Group:  gateway.networking.k8s.io
            Kind:   HTTPRoute
          Namespaces:
            From:  Same
        Name:      http
        Port:      80
        Protocol:  HTTP
    Status:
      Addresses:
        Type:   IPAddress
        Value:  34.36.127.249
      Conditions:
        Last Transition Time:  2023-10-12T07:00:41Z
        Message:               The OSS Gateway API has deprecated this condition, do not depend on it.
        Observed Generation:   1
        Reason:                Scheduled
        Status:                True
        Type:                  Scheduled
        Last Transition Time:  2023-10-12T07:00:41Z
        Message:
        Observed Generation:   1
        Reason:                Accepted
        Status:                True
        Type:                  Accepted
        Last Transition Time:  2023-10-12T07:00:41Z
        Message:
        Observed Generation:   1
        Reason:                Programmed
        Status:                True
        Type:                  Programmed
        Last Transition Time:  2023-10-12T07:00:41Z
        Message:               The OSS Gateway API has altered the "Ready" condition semantics and reservedit for future use.  GKE Gateway will stop emitting it in a future update, use "Programmed" instead.
        Observed Generation:   1
        Reason:                Ready
        Status:                True
        Type:                  Ready
      Listeners:
        Attached Routes:  1
        Conditions:
          Last Transition Time:  2023-10-12T07:00:41Z
          Message:
          Observed Generation:   1
          Reason:                Programmed
          Status:                True
          Type:                  Programmed
          Last Transition Time:  2023-10-12T07:00:41Z
          Message:               The OSS Gateway API has altered the "Ready" condition semantics and reservedit for future use.  GKE Gateway will stop emitting it in a future update, use "Programmed" instead.
          Observed Generation:   1
          Reason:                Ready
          Status:                True
          Type:                  Ready
        Name:                    http
        Supported Kinds:
          Group:  gateway.networking.k8s.io
          Kind:   HTTPRoute
    Events:
      Type    Reason  Age                    From                   Message
      ----    ------  ----                   ----                   -------
      Normal  UPDATE  35m (x4 over 10h)      mc-gateway-controller  store/external-http
      Normal  SYNC    4m22s (x216 over 10h)  mc-gateway-controller  SYNC on store/external-http was a success
    
  2. אחרי שהשער נפרס בהצלחה, מאחזרים את כתובת ה-IP החיצונית מ-external-http Gateway.

    kubectl get gateways.gateway.networking.k8s.io external-http -o=jsonpath="{.status.addresses[0].value}" --context gke-west-1 --namespace store
    

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

  3. הפניית תנועה לנתיב הבסיסי של הדומיין. הוא מאזן את העומס של התעבורה אל store ServiceImport שחוצה את האשכול gke-west-1 ואת gke-east-1. מאזן העומסים שולח את התנועה שלכם לאזור הקרוב ביותר אליכם, ויכול להיות שלא תראו תגובות מהאזור השני.

    curl -H "host: store.example.com" http://VIP
    

    הפלט מאשר שהבקשה הוגשה על ידי Pod מהאשכול gke-east-1:

    {
      "cluster_name": "gke-east-1",
      "zone": "us-east1-b",
      "host_header": "store.example.com",
      "node_name": "gke-gke-east-1-default-pool-7aa30992-t2lp.c.agmsb-k8s.internal",
      "pod_name": "store-5f5b954888-dg22z",
      "pod_name_emoji": "⏭",
      "project_id": "agmsb-k8s",
      "timestamp": "2021-06-01T17:32:51"
    }
    
  4. לאחר מכן, שולחים תנועה לנתיב /west. התנועה מנותבת אל store-west-1 ServiceImport שיש לו רק Pods שפועלים באשכול gke-west-1. ‫ServiceImport ספציפי לאשכול, כמו store-west-1, מאפשר לבעלים של אפליקציה לשלוח תנועה באופן מפורש לאשכול ספציפי, במקום לאפשר למאזן העומסים לקבל את ההחלטה.

    curl -H "host: store.example.com" http://VIP/west
    

    הפלט מאשר שהבקשה הוגשה על ידי Pod מהאשכול gke-west-1:

    {
      "cluster_name": "gke-west-1", 
      "zone": "us-west1-a", 
      "host_header": "store.example.com",
      "node_name": "gke-gke-west-1-default-pool-65059399-2f41.c.agmsb-k8s.internal",
      "pod_name": "store-5f5b954888-d25m5",
      "pod_name_emoji": "🍾",
      "project_id": "agmsb-k8s",
      "timestamp": "2021-06-01T17:39:15",
    }
    
  5. לבסוף, שולחים תנועה לנתיב /east.

    curl -H "host: store.example.com" http://VIP/east
    

    הפלט מאשר שהבקשה הוגשה על ידי Pod מהאשכול gke-east-1:

    {
      "cluster_name": "gke-east-1",
      "zone": "us-east1-b",
      "host_header": "store.example.com",
      "node_name": "gke-gke-east-1-default-pool-7aa30992-7j7z.c.agmsb-k8s.internal",
      "pod_name": "store-5f5b954888-hz6mw",
      "pod_name_emoji": "🧜🏾",
      "project_id": "agmsb-k8s",
      "timestamp": "2021-06-01T17:40:48"
    }
    

הסרת המשאבים

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

  1. מחיקת האשכולות.

  2. ביטול הרישום של האשכולות ב-Fleet אם אין צורך לרשום אותם למטרה אחרת.

  3. השבתת התכונה multiclusterservicediscovery:

    gcloud container fleet multi-cluster-services disable
    
  4. השבתת Multi Cluster Ingress:

    gcloud container fleet ingress disable
    
  5. משביתים את ממשקי ה-API:

    gcloud services disable \
        multiclusterservicediscovery.googleapis.com \
        multiclusteringress.googleapis.com \
        trafficdirector.googleapis.com \
        --project=PROJECT_ID
    

פתרון בעיות

אין מקור תקין

התסמין:

יכולה להתרחש הבעיה הבאה כשיוצרים Gateway אבל אין גישה לשירותי ה-Backend (קוד תגובה 503):

no healthy upstream

הסיבה:

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

פתרון עקיף:

כדי לפתור את הבעיה, מתאימים אישית את בדיקת התקינות בהתאם לדרישות של האפליקציה (לדוגמה, /health) באמצעות HealthCheckPolicy.

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