פריסת שערים

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

כדי לפרוס שערים לאיזון עומסים של תעבורת נתונים נכנסת (ingress) בכמה אשכולות (או צי), אפשר לעיין במאמר בנושא פריסת שערים מרובי אשכולות.

למידע על הגדרות ספציפיות יותר של שערים, כמו ניתוב בין מרחבי שמות ופיצול תנועת HTTP, אפשר לעיין במדריכים למשתמשים ב-Gateway API.

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

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

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

דרישות של GKE Gateway controller

  • ‫Gateway API נתמך רק באשכולות VPC-native.
  • אם אתם משתמשים ב-GatewayClasses אזוריים או חוצי-אזורים, אתם צריכים להפעיל רשת משנה ל-proxy בלבד.
  • צריך להפעיל את התוסף HttpLoadBalancing באשכול.
  • אם אתם משתמשים ב-Istio, אתם צריכים לשדרג את Istio לאחת מהגרסאות הבאות:
    • גרסה 1.15.2 ואילך
    • ‫1.14.5 ואילך
    • גרסה 1.13.9 ואילך.
  • אם משתמשים ב-VPC משותף, צריך להקצות את התפקיד Compute Network User לחשבון השירות של GKE בפרויקט המארח של פרויקט השירות.

הגבלות ומגבלות

כשמשתמשים ב-GKE Gateway, חשוב להבין את המגבלות וההגבלות הבאות:

  • מחלקות GKE Gateway תומכות ביכולות שונות בהתאם למאזן העומסים שבו הן משתמשות. מידע נוסף על התכונות השונות שנתמכות בכל GatewayClass זמין במאמר יכולות של GatewayClass.

    שיטה מומלצת:

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

  • אי אפשר להשתמש ב-FrontendConfig או ב-BackendConfig כדי להגדיר שער. חובה להשתמש במדיניות.

  • ההתנהגות של GKE Gateway שונה מזו של Ingress, כי Gateway לא מסיק פרמטרים של בדיקת תקינות. אם השירות לא מחזיר 200 לבקשות אל GET /, או אם יש לכם בדיקות מוכנות של פודים מותאמים אחרים, אתם צריכים להגדיר HealthCheckPolicy לשירות.

  • אי אפשר לציין מספר יציאה ישירות בשם המארח (לדוגמה, web.example.com:80) לניתוב תנועה.

  • אפשר לראות את משאבי מאזן העומסים ש-GKE יוצר עבור Gateways במסוף Google Cloud , אבל המשאבים האלה לא מפנים אל ה-Gateway או אל אשכול GKE שאליהם הם מצורפים.

  • אי אפשר ליצור באופן אוטומטי אישור SSL בניהול Google באמצעות Gateways, אבל אפשר ליצור אישור SSL בניהול Google באופן ידני ולהפנות אליו. מידע נוסף זמין במאמר בנושא אבטחת שער.

  • ‫HTTPRoute הוא סוג המסלול היחיד שנתמך. אין תמיכה ב-TCPRoutes, ב-UDPRoutes וב-TLSRoutes. רשימת השדות שנתמכים על ידי בקר GKE Gateway מופיעה במאמר בנושא יכולות של GatewayClass.

  • האפשרות להשתמש בכותרות מותאמות אישית של בקשות ותגובות עם הפניות אוטומטיות של שער או נתיב, ושינוי כתובות URL עם שער, זמינה רק ב-GKE בגרסה 1.27 ואילך.

  • ה-GatewayClass‏ gke-l7-gxlb לא נתמך בכותרות מותאמות אישית של בקשות ותגובות עם הפניות אוטומטיות של שערים ונתיבים, ועם שכתוב של כתובות URL עם שערים.

  • כשמגדירים כותרות מותאמות אישית של בקשות ותגובות ב-HTTPRoute, אין תמיכה בGoogle Cloud משתנים הבאים:

    • cdn_cache_id (אין תמיכה ב-Cloud CDN עם GKE Gateway)
    • cdn_cache_status (אין תמיכה ב-Cloud CDN עם GKE Gateway)
    • origin_request_header (מדיניות CORS לא נתמכת ב-GKE Gateway)
  • GKE Gateway לא תומך בתכונה של איזון עומסים ב-Cloud CDN.

  • אין תמיכה בכותרות מותאמות אישית של Mutual TLS (mTLS עם GKE Gateway לא נתמך)

  • Google Cloud המגבלות של מאזן עומסים קלאסי של אפליקציות (ALB) חלות על GKE Gateway. בנוסף, אי אפשר להגדיר כותרת תגובה של מארח בהתאמה אישית בשירות הקצה העורפי.

  • הפניות אוטומטיות של נתיבים ושינוי של כתובות URL הן פעולות שאי אפשר לבצע בו-זמנית, ולכן אי אפשר להשתמש בשני המסננים האלה באותם כללים.

  • אי אפשר להפנות תנועה ליציאה אחרת באמצעות Cloud Load Balancing. רשימת השדות שנתמכים על ידי בקר GKE Gateway מופיעה במאמר בנושא יכולות GatewayClass.

  • ‫GKE Gateway לא תומך בתווים כלליים לחיפוש, בביטויים רגולריים ובכתובות URL דינמיות.

  • אם מציינים שער עם סיווג שער חיצוני אזורי, הבקר מקצה כתובת IP פנימית במקום כתובת חיצונית. כדי ללמוד איך להשתמש בכתובת עם שם במאזן עומסים חיצוני אזורי של אפליקציות (ALB), אפשר לעיין במאמר פריסת שער חיצוני אזורי.

  • שער משתמש בקבוצות נקודות קצה ברשת עצמאיות כדי להקצות קבוצות של נקודות קצה ברשת. כדי לוודא שבקר Gateway מבצע התאמה נכונה של ההגדרה של מאזן העומסים, אסור לשנות את ההערה cloud.google.com/neg של שירות שמהווה חלק מ-Gateway.

  • ‫GKE Gateway לא תומך בהפניה לשירות שמופנה גם על ידי GKE Ingress.

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

  • אין תמיכה בהערה networking.gke.io/app-protocols. במקום זאת, צריך להשתמש בשדה appProtocol כדי להשיג את אותה התוצאה.

  • אם אתם משתמשים ב-GKE Gateway עם external-dns ומצב התקינות של ה-Gateway הוא unhealthy, כברירת מחדל, כל רשומות ה-DNS שמשויכות ל-Gateway נמחקות מאזורי ה-DNS שלכם.

    שיטה מומלצת:

    כשמריצים את external-dns, מגדירים את הדגל policy=upsert-only. ההגדרה הזו עוזרת למנוע מחיקה של רשומות DNS קיימות.

  • אם יציאה מוסרת מ-Service ש-GKE Gateway מפנה אליו דרך מסלול, צריך לעדכן גם את הערת ה-Standalone NEG בשירות כדי להסיר את היציאה הזו מהבקר של ה-Standalone NEG בשירות. אם לא תעשו זאת, בקר ה-NEG יפסיק בסופו של דבר לסנכרן את נקודות הקצה של ה-Pod בשירות הזה. פרטים נוספים זמינים במאמר NEG Controller מפסיק לנהל נקודות קצה כשמסירים יציאה מ-Service.

  • פריסות שמשתמשות בשערים מרובי אשכולות (MCG) שמשתמשים באשכולות אזוריים חשופות להפרעות בשירות במהלך שדרוגים של אשכולות. הבעיה הזו מתרחשת כי מנגנון גילוי של קבוצת נקודות קצה ברשת (NEG) מדור קודם עשוי לדווח באופן שגוי על אפס בק-אנדים כשמישור הבקרה של האשכול האזורי לא זמין באופן זמני. אנחנו עובדים על פתרון לטווח ארוך. כדי להימנע מנקודת כשל יחידה, מומלץ להשתמש באשכולות GKE אזוריים עם MCG.

הפעלת Gateway API באשכול

כדי להשתמש במשאבי Gateway ב-GKE, צריך להפעיל את Gateway API באשכול.

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

כדי להפעיל את Gateway API באשכול GKE קיים (במצב Autopilot או Standard), משתמשים בפקודה הבאה. יכול להיות שיחלפו עד 45 דקות עד שהאשכול יתעדכן ויתקין את ה-CRD.

gcloud container clusters update CLUSTER_NAME \
    --location=CLUSTER_LOCATION\
    --gateway-api=standard

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

הדגל --gateway-api=standard מורה ל-GKE להתקין את ה-CRD‏ v1beta1 עם האשכול.

אימות האשכול

אחרי שיוצרים או משדרגים את האשכול, הבקר של GKE Gateway מתקין באופן אוטומטי את GatewayClasses. יכול להיות שיעברו כמה דקות עד שהבקר יזהה את ה-CRD ויתקין את GatewayClasses.

  1. מוודאים ש-Gateway API מופעל במישור הבקרה של GKE:

    gcloud container clusters describe CLUSTER_NAME \
      --location=CLUSTER_LOCATION \
      --format json
    

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

    "networkConfig": {
      ...
      "gatewayApiConfig": {
        "channel": "CHANNEL_STANDARD"
      },
      ...
    },
    
  2. מוודאים ש-GatewayClasses מותקנים באשכול:

    kubectl get gatewayclass
    

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

    NAME                             CONTROLLER                  ACCEPTED   AGE
    gke-l7-global-external-managed   networking.gke.io/gateway   True       16h
    gke-l7-regional-external-managed networking.gke.io/gateway   True       16h
    gke-l7-gxlb                      networking.gke.io/gateway   True       16h
    gke-l7-rilb                      networking.gke.io/gateway   True       16h
    

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

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

פריסת שער פנימי

שער פנימי חושף אפליקציות שאפשר להגיע אליהן רק מתוך ה-VPC או רשתות שמחוברות ל-VPC.

פריסת שער פנימי אזורי

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

הגדרת רשת משנה לשרת proxy בלבד

לפני שיוצרים שער שמשתמש במאזן עומסים פנימי של אפליקציות (ALB), צריך להגדיר רשת משנה של פרוקסי בלבד. לכל אזור ב-VPC שבו אתם משתמשים במאזני עומסים פנימיים של אפליקציות (ALB) צריך להיות תת-רשת לשרת proxy בלבד. רשת המשנה הזו מספקת כתובות IP פנימיות לשרתי ה-proxy של מאזן העומסים.

  1. יוצרים תת-רשת לשרתי proxy בלבד:

    gcloud compute networks subnets create SUBNET_NAME \
        --purpose=REGIONAL_MANAGED_PROXY \
        --role=ACTIVE \
        --region=COMPUTE_REGION \
        --network=VPC_NETWORK_NAME \
        --range=CIDR_RANGE
    

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

    • SUBNET_NAME: השם של תת-הרשת של ה-proxy בלבד.
    • COMPUTE_REGION: האזור של תת-הרשת של ה-proxy בלבד.
    • VPC_NETWORK_NAME: השם של רשת ה-VPC שבה יוצרים את רשת המשנה הזו מסוג proxy בלבד. חשוב לוודא שזו אותה רשת VPC שבה נמצא אשכול GKE ושבה פורס השער. הפעולה הזו חשובה כדי לאפשר תקשורת חלקה בין מאזן העומסים לבין שירותי הקצה העורפי.
    • CIDR_RANGE: טווח כתובות ה-IP הראשי של רשת המשנה. צריך להשתמש במסכה של רשת משנה באורך של /26 לכל היותר, כדי שיהיו לפחות 64 כתובות IP זמינות לשרתי proxy באזור. מסכה של רשת משנה מומלצת היא /23.
  2. מאמתים את רשת המשנה של ה-proxy בלבד:

    gcloud compute networks subnets describe SUBNET_NAME \
        --region=COMPUTE_REGION
    

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

    ...
    gatewayAddress: 10.1.1.1
    ipCidrRange: 10.1.1.0/24
    kind: compute#subnetwork
    name: proxy-subnet
    network: https://www.googleapis.com/compute/v1/projects/PROJECT_NAME/global/networks/default
    privateIpGoogleAccess: false
    privateIpv6GoogleAccess: DISABLE_GOOGLE_ACCESS
    purpose: REGIONAL_MANAGED_PROXY
    region: https://www.googleapis.com/compute/v1/projects/PROJECT_NAME/regions/REGION
    role: ACTIVE
    selfLink: https://www.googleapis.com/compute/v1/projects/PROJECT_NAME/regions/REGION/subnetworks/proxy-subnet
    state: READY
    

יצירת שער

משאב Gateway מייצג מישור נתונים שמנתב תעבורה ב-Kubernetes. שער יכול לייצג סוגים שונים של איזון עומסים וניתוב, בהתאם ל-GatewayClass שממנו הוא נגזר. מידע נוסף על משאב Gateway מופיע בתיאור משאב Gateway או במפרט ה-API.

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

  1. שומרים את מניפסט השער הבא בקובץ בשם gateway.yaml:

    kind: Gateway
    apiVersion: gateway.networking.k8s.io/v1
    metadata:
       name: internal-http
    spec:
      # Specify an existing GatewayClass.
      gatewayClassName: gke-l7-rilb
      listeners:
      # Listen for HTTP traffic on port 80.
      - name: http
        protocol: HTTP
        port: 80
    

    המניפסט הזה כולל את השדות הבאים:

    • gatewayClassName: gke-l7-rilb: מציין את GatewayClass שממנו נגזר שער ה-Gateway הזה. ‫gke-l7-rilb מתאים למאזן עומסים פנימי של אפליקציות.
    • port: 80: מציין שה-Gateway חושף רק את יציאה 80 להאזנה לתנועת HTTP.

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

  2. פורסים את שער הכניסה באשכול:

    kubectl apply -f gateway.yaml
    
  3. מוודאים שהשער נפרס בצורה נכונה. יכול להיות שיעברו כמה דקות עד שכל המשאבים יופעלו.

    kubectl describe gateways.gateway.networking.k8s.io internal-http
    

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

    Name:         internal-http
    Namespace:    default
    Spec:
      Gateway Class Name:  gke-l7-rilb
      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:  192.168.1.14
       Conditions:
         Last Transition Time:  2025-03-19T19:53:46Z
         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:  2025-03-19T19:53:46Z
         Message:
         Observed Generation:   1
         Reason:                Accepted
         Status:                True
         Type:                  Accepted
         Last Transition Time:  2025-03-19T19:53:46Z
         Message:
         Observed Generation:   1
         Reason:                Programmed
         Status:                True # Indicates that the Gateway is ready.
         Type:                  Programmed
         Last Transition Time:  2025-03-19T19:53:46Z
         Message:               The OSS Gateway API has altered the "Ready" condition semantics and reserved it 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
         Last Transition Time:  2025-03-19T19:53:46Z
         Message:
         Observed Generation:   1
         Reason:                Healthy
         Status:                True
         Type:                  networking.gke.io/GatewayHealthy
    Events:
      Type    Reason  Age                From                       Message
      ----    ------  ----               ----                       -------
      Normal  ADD     92s                networking.gke.io/gateway  test/internal-http
      Normal  UPDATE  45s (x3 over 91s)  networking.gke.io/gateway  test/internal-http
      Normal  SYNC    45s                networking.gke.io/gateway  SYNC on test/internal-http was a success
    

    בפלט הזה, הסטטוס של True עבור התנאי Programmed מציין שהשער מוכן.

    בשלב הזה, יש שער (Gateway) שמוצב באשכול שלכם, שסופק לו איזון עומסים וכתובת IP. לשער אין מסלולים, ולכן הוא לא יודע איך לשלוח תנועה לשרתי קצה עורפיים. בלי מסלולים, כל התנועה מועברת לבק-אנד שמוגדר כברירת מחדל, שמחזיר HTTP 404. בשלב הבא פורסים אפליקציה ומסלולים, שמציינים ל-Gateway איך להגיע לשרתי הקצה העורפיים של האפליקציה.

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

צוותי אפליקציות יכולים לפרוס את האפליקציות והנתיבים שלהם בנפרד מהפריסה של שערים. במקרים מסוימים, צוות האפליקציה עשוי לרצות להיות הבעלים של שער הגישה ולפרוס אותו בעצמו כמשאב שמוקדש לאפליקציות שלו. במאמר שיוך מסלולים מוסבר על מודלים שונים של בעלות על שערים ומסלולים. בדוגמה הזו, צוות החנות פורס את האפליקציה שלו ואת ה-HTTPRoute הנלווה כדי לחשוף את האפליקציה שלו דרך שער internal-http שנוצר בקטע הקודם.

למשאב HTTPRoute יש הרבה שדות שאפשר להגדיר להתאמת תנועה. הסבר על השדות של HTTPRoute מופיע במפרט ה-API.

  1. פורסים את אפליקציית החנות (פריסות store-v1,‏ store-v2 ו-store-german) באשכול:

    kubectl apply -f https://raw.githubusercontent.com/GoogleCloudPlatform/gke-networking-recipes/main/gateway/gke-gateway-controller/app/store.yaml
    

    כך נוצרות שלוש פריסות ושלושה שירותים בשמות store-v1,‏ store-v2 ו-store-german.

  2. מוודאים שהפריסה של האפליקציה בוצעה בהצלחה:

    kubectl get pod
    

    הפלט אמור להיראות כך אחרי שהאפליקציה פועלת:

    NAME                        READY   STATUS    RESTARTS   AGE
    store-german-66dcb75977-5gr2n   1/1     Running   0          38s
    store-v1-65b47557df-jkjbm       1/1     Running   0          14m
    store-v2-6856f59f7f-sq889       1/1     Running   0          14m
    
  3. בודקים שהשירותים נפרסו:

    kubectl get service
    

    הפלט מציג שירות לכל פריסת חנות:

    NAME           TYPE        CLUSTER-IP    EXTERNAL-IP   PORT(S)    AGE
    store-german   ClusterIP   10.48.3.183   <none>        8080/TCP   4s
    store-v1       ClusterIP   10.48.2.224   <none>        8080/TCP   5s
    store-v2       ClusterIP   10.48.4.48    <none>        8080/TCP   5s
    

פריסת HTTPRoute

משאבי ניתוב מגדירים כללים ספציפיים לפרוטוקול למיפוי תנועה משערים (Gateway) לשרתי קצה עורפיים של Kubernetes. המשאב HTTPRoute מבצע התאמה וסינון של תנועת HTTP ו-HTTPS, והוא נתמך על ידי כל GatewayClasses של gke-l7.

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

  1. שומרים את מניפסט ה-HTTPRoute הבא בקובץ בשם store-route.yaml:

    kind: HTTPRoute
    apiVersion: gateway.networking.k8s.io/v1
    metadata:
      name: store
    spec:
      # Attach the HTTPRoute to a Gateway.
      parentRefs:
      - kind: Gateway
        name: internal-http
      # Route requests that have `store.example.com` in the Host header.
      hostnames:
      - "store.example.com"
      rules:
      # Send requests with the `env: canary` header to the `store-v2` Service.
      - matches:
        - headers:
          - name: env
            value: canary
        backendRefs:
        - name: store-v2
          port: 8080
      # Send requests with `/de` in the path to the `store-german` Service.
      - matches:
        - path:
            value: /de
        backendRefs:
        - name: store-german
          port: 8080
      # Send unmatched requests to the store-v1 Service.
      - backendRefs:
        - name: store-v1
          port: 8080
    
  2. פורסים את ה-HTTProute באשכול:

    kubectl apply -f store-route.yaml
    

    ‫HTTPRoute‏ store קשור ל-Gateway‏ internal-http באמצעות המאפיין parentRefs. כללי הניתוב האלה מוגדרים במאזן העומסים הבסיסי, כמו בתרשים הזה:

    כללי הניתוב שהוגדרו על ידי HTTPRoute של החנות

    כללי הניתוב האלה מעבדים תנועת HTTP באופן הבא:

    • תנועת הגולשים באתר store.example.com/de מגיעה לשירות store-german.
    • תנועה אל store.example.com עם כותרת HTTP‏ "env: canary" עוברת אל השירות store-v2.
    • שאר התנועה אל store.example.com מופנית אל השירות store-v1.
  3. מוודאים שרכיב ה-HTTPRoute נפרס:

    kubectl describe httproute store
    

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

    Name:         store
    Namespace:    default
    Labels:       <none>
    Annotations:  <none>
    API Version:  gateway.networking.k8s.io/v1
    Kind:         HTTPRoute
    # Multiple lines are omitted here.
    Spec:
      Hostnames:
        store.example.com
      Parent Refs:
        Group:  gateway.networking.k8s.io
        Kind:   Gateway
        Name:   internal-http
      Rules:
        Backend Refs:
          Group:
          Kind:    Service
          Name:    store-v1
          Port:    8080
          Weight:  1
        Matches:
          Path:
            Type:   PathPrefix
            Value:  /
        Backend Refs:
          Group:
          Kind:    Service
          Name:    store-v2
          Port:    8080
          Weight:  1
        Matches:
          Headers:
            Name:   env
            Type:   Exact
            Value:  canary
          Path:
            Type:   PathPrefix
            Value:  /
        Backend Refs:
          Group:
          Kind:    Service
          Name:    store-german
          Port:    8080
          Weight:  1
        Matches:
          Path:
            Type:   PathPrefix
            Value:  /de
    Status:
      Parents:
        Conditions:
          Last Transition Time:  2022-11-01T04:18:52Z
          Message:
          Reason:                Accepted
          Status:                True
          Type:                  Accepted
          Last Transition Time:  2022-11-01T04:18:52Z
          Message:
          Reason:                ReconciliationSucceeded
          Status:                True
          Type:                  Reconciled
        Controller Name:         networking.gke.io/gateway
        Parent Ref:
          Group:  gateway.networking.k8s.io
          Kind:   Gateway
          Name:   internal-http
    Events:
      Type    Reason  Age                From                   Message
      ----    ------  ----               ----                   -------
      Normal  ADD     24m                sc-gateway-controller  default/store
      Normal  SYNC    16m (x4 over 23m)  sc-gateway-controller  Bind of HTTPRoute "default/store" to ParentRef {Group:       gateway.networking.k8s.io",
      # Multiple lines are omitted here.
    
  4. מוודאים ש-HTTPRoute קשור ל-Gateway:

    kubectl describe gateway
    

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

    Name:         internal-http
    Namespace:    default
    Labels:       <none>
    <...>
    Status:
      Addresses:
        Type:   IPAddress
        Value:  10.128.15.203
      Conditions:
        Last Transition Time:  2022-11-01T03:47:01Z
        Message:
        Reason:                Scheduled
        Status:                True
        Type:                  Scheduled
        Last Transition Time:  2022-11-01T03:47:01Z
        Message:
        Reason:                Ready
        Status:                True
        Type:                  Ready
      Listeners:
        Attached Routes:  1
        Conditions:
          Last Transition Time:  2022-11-01T03:47:01Z
          Message:
          Reason:                Ready
          Status:                True
          Type:                  Ready
        Name:                    http
        Supported Kinds:
          Group:  gateway.networking.k8s.io
          Kind:   HTTPRoute
          <...>
    

שליחת תנועה לאפליקציה

עכשיו, אחרי שפרסתם את שער הכניסה, המסלול והאפליקציה באשכול, אתם יכולים להעביר תנועה לאפליקציה. השער מוגדר להעברת תנועת HTTP רק ביציאה 80. בקשות שמבוצעות באמצעות HTTPS עלולות להיכשל אלא אם TLS הוגדר בנפרד.

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

    kubectl get gateways.gateway.networking.k8s.io internal-http -o=jsonpath="{.status.addresses[0].value}"
    

    הפלט הוא כתובת IP.

  2. שולחים תעבורה לכתובת ה-IP הזו מהמעטפת במכונה וירטואלית (VM) עם קישוריות לאשכול. אפשר ליצור מכונה וירטואלית למטרה הזו. הפעולה הזו נדרשת כי לשער יש כתובת IP פנימית, ואפשר לגשת אליו רק מתוך רשת ה-VPC. מכיוון ש-internal-http הוא מאזן עומסים אזורי, מעטפת הלקוח צריכה להיות באותו אזור כמו אשכול GKE.

    שליחת בקשה אל store.example.com:

    curl http://store.example.com --resolve store.example.com:80:GATEWAY_IP_ADDRESS -v
    

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

    הפלט מאפליקציית ההדגמה מציג מידע על המיקום שבו האפליקציה פועלת:

    {
      "cluster_name": "gke1",
      "host_header": "store.example.com",
      "metadata": "store-v1",
      "node_name": "gke-gke1-pool-2-bd121936-5pfc.c.gateway-demo-243723.internal",
      "pod_name": "store-v1-84b47c7f58-pmgmk",
      "pod_name_emoji": "💇🏼‍♀️",
      "project_id": "gateway-demo-243723",
      "timestamp": "2022-10-25T13:31:17",
      "zone": "ZONE_NAME"
    }
    
  3. כדי לבדוק את ההתאמה של הנתיב, עוברים לגרסה הגרמנית של שירות החנות בכתובת store.example.com/de:

    curl http://store.example.com/de --resolve store.example.com:80:GATEWAY_IP_ADDRESS -v
    

    הפלט מאשר שהבקשה הוגשה על ידי store-german Pod:

    {
      "cluster_name": "gke1",
      "host_header": "store.example.com",
      "metadata": "Gutentag!", 
      "node_name": "gke-gke1-pool-2-bd121936-n3xn.c.gateway-demo-243723.internal",
      "pod_name": "store-german-5cb6474c55-lq5pl", 
      "pod_name_emoji": "🧞‍♀",
      "project_id": "gateway-demo-243723",
      "timestamp": "2022-10-25T13:35:37",
      "zone": "ZONE_NAME"
    }
    
  4. לבסוף, משתמשים בכותרת env: canary HTTP כדי לשלוח תנועה לגרסת הקנרי של שירות החנות:

    curl -H "env: canary" http://store.example.com --resolve store.example.com:80:GATEWAY_IP_ADDRESS -v
    

    הפלט מאשר שהבקשה הוגשה על ידי store-v2 Pod:

    {
      "cluster_name": "gke1",
      "host_header": "store.example.com",
      "metadata": "store-v2", 
      "node_name": "gke-gke1-pool-2-bd121936-5pfc.c.gateway-demo-243723.internal",
      "pod_name": "store-v2-5788476cbd-s9thb", 
      "pod_name_emoji": "🦰",
      "project_id": "gateway-demo-243723",
      "timestamp": "2022-10-25T13:38:26",
      "zone": "ZONE_NAME"
    }
    

פריסת שער חיצוני

שער חיצוני חושף אפליקציות שאפשר להגיע אליהן מהאינטרנט או מרשתות מחוץ לרשת ה-VPC. הפריסה דומה לפריסת שער פנימי, אבל צריך לאבטח את האפליקציות כי השער נגיש לאינטרנט הציבורי.

יש שתי אפשרויות ליצירת שער חיצוני: שער חיצוני גלובלי או שער חיצוני אזורי.

  • שער חיצוני גלובלי: השער הזה משתמש בכתובת IP גלובלית (או בכתובת IP מסוג Anycast) כחלק הקדמי של השער. כתובת ה-IP הזו מפורסמת בכל האזורים של Google Cloud Compute. לקוחות ששולחים תעבורת נתונים לכתובת ה-IP מסוג Anycast הזו מנותבים למיקום הקרוב ביותר של Google שבו כתובת ה-IP מפורסמת. שער חיצוני גלובלי זמין רק במסלול הפרימיום של שירותי הרשת.
  • שער חיצוני אזורי: השער הזה משתמש בכתובת IP אזורית כחלק הקדמי של השער. ההתנהגות של השער הזה תלויה במסלול שירות הרשת שתבחרו:
    • אם בוחרים במסלול הרגיל של שירותי הרשת (ברירת המחדל), כתובת ה-IP האזורית מפורסמת רק באזור Google Cloud Compute המקומי שבו נפרס שער חיצוני אזורי. תעבורת נתונים מלקוחות שנשלחת לכתובת ה-IP הזו מנותבת על ידי ספק האינטרנט המקומי שלהם דרך האינטרנט הציבורי, לפני שהיא מגיעה לאזור של Google שבו כתובת ה-IP מפורסמת.
    • אם בוחרים במסלול הפרימיום של שירות הרשת, כתובת ה-IP האזורית מפורסמת בכל הרשת הגלובלית של Google. כלומר, תעבורת הנתונים של הלקוח נכנסת לרשת הגלובלית האיכותית של Google בשדרה המרכזית בנקודת קישור בין רשתות שכנות (peering) בקצה של Google, הכי קרוב שאפשר ללקוח, גם אם היעד הוא כתובת IP אזורית. המיקום הזה מפחית באופן משמעותי את זמן האחזור ומשפר את הביצועים, כי הוא מצמצם את המרחק שהתנועה עוברת באינטרנט הציבורי.

פריסת שער חיצוני גלובלי

בדוגמה הבאה אפשר לראות איך חושפים אפליקציה בחנות עם כמה אישורים שמצורפים לשער החיצוני הגלובלי ומקובצים במפת אישורים באמצעות Certificate Manager ו-HTTPRoute.

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

‫Google ממליצה להשתמש בCertificate Manager כדי לנהל אישורים כשצריך 15 אישורים או יותר לכל שער, או כשצריך להשתמש באישור כללי.

אפשר גם לאבטח את שער הכניסה החיצוני באמצעות סודות של Kubernetes או אישורי SSL בניהול Google. מידע נוסף זמין במאמר בנושא אבטחת שערים.

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

  1. מפעילים את Certificate Manager API:

    gcloud services enable certificatemanager.googleapis.com
    
  2. יוצרים מיפוי אישורים:

    gcloud beta certificate-manager maps create store-example-com-map
    
  3. טוענים את האישור והמפתחות שמנוהלים על ידי Google לתוך אישור:

    gcloud beta certificate-manager certificates create store-example-com-cert \
        --certificate-file="CERTIFICATE_FILE" \
        --private-key-file="PRIVATE_KEY_FILE"
    

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

    • CERTIFICATE_FILE: השם של קובץ האישור. הקובץ חייב לכלול את הסיומת .pem. לדוגמה: cert.pem.
    • PRIVATE_KEY_FILE: השם של קובץ המפתח הפרטי.

    מידע נוסף זמין במאמר יצירת מפתח פרטי ותעודה.

  4. יוצרים CertificateMapEntry שבו מוקצה האישור למיפוי האישורים:

    gcloud beta certificate-manager maps entries create store-example-com-map-entry \
        --map=store-example-com-map \
        --hostname=store.example.com \
        --certificates=store-example-com-cert
    

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

יצירת שער

משאב Gateway מייצג מישור נתונים שמנתב תעבורה ב-Kubernetes. שער יכול לייצג סוגים שונים של איזון עומסים וניתוב, בהתאם ל-GatewayClass שבו הוא משתמש.

מידע נוסף על משאב שער זמין בתיאור משאב שער או במפרט ה-API.

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

  1. שומרים את המניפסט הבא בקובץ בשם gateway.yaml:

    kind: Gateway
    apiVersion: gateway.networking.k8s.io/v1
    metadata:
      name: external-http
      annotations:
        networking.gke.io/certmap: store-example-com-map
    spec:
      # This GatewayClass uses a global external Application Load Balancer.
      gatewayClassName: gke-l7-global-external-managed
      listeners:
      - name: https
        protocol: HTTPS
        port: 443
    
    

    במניפסט הזה מתואר שער עם השדות הבאים:

    • gatewayClassName: gke-l7-global-external-managed: מציין את GatewayClass עבור השער הזה. סוג השער הזה משתמש במאזן עומסים חיצוני גלובלי של אפליקציות (ALB).
    • protocol: HTTPS ו-port: 443: מציינים ששער הגישה חושף את יציאה 443 לתנועת HTTPS. השדות האלה מאפשרים TLS.
    • networking.gke.io/certmap: store-example-com-map: מציין את השם של מיפוי האישורים ב-Certificate Manager.

    אין קטע TLS כי TLS מוגדר באמצעות Certificate Manager באמצעות ההערה networking.gke.io/certmap.

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

    kubectl apply -f gateway.yaml
    

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

  3. מוודאים שהפריסה של שער הגישה בוצעה בהצלחה:

    kubectl describe gateway
    

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

    Name:         external-http
    Namespace:    default
    Labels:       <none>
    ...
    Spec:
      Gateway Class Name:  gke-l7-global-external-managed
      Listeners:
        Allowed Routes:
          Namespaces:
            From:  Same
        Name:      https
        Port:      443
        Protocol:  HTTPS
        Tls:
          Certificate Refs:
            Group:
            Kind:   Secret
            Name:   store-example-com
          Mode:     Terminate
     ...
    

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

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

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

מידע נוסף על שדות HTTPRoute זמין במפרט ה-API.

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

    kubectl apply -f https://raw.githubusercontent.com/GoogleCloudPlatform/gke-networking-recipes/main/gateway/gke-gateway-controller/app/store.yaml
    

    אפליקציית הדוגמה הזו יוצרת שלוש פריסות ושלושה שירותים בשמות store-v1, store-v2 ו-store-german.

  2. מוודאים שהפריסה של האפליקציה הצליחה:

    kubectl get pod
    

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

    NAME                            READY   STATUS    RESTARTS   AGE
    store-german-66dcb75977-5gr2n   1/1     Running   0          38s
    store-v1-65b47557df-jkjbm       1/1     Running   0          14m
    store-v2-6856f59f7f-sq889       1/1     Running   0          14m
    
  3. מוודאים שהשירותים נפרסו בהצלחה:

    kubectl get service
    

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

    NAME           TYPE        CLUSTER-IP    EXTERNAL-IP   PORT(S)    AGE
    store-german   ClusterIP   10.48.3.183   <none>        8080/TCP   4s
    store-v1       ClusterIP   10.48.2.224   <none>        8080/TCP   5s
    store-v2       ClusterIP   10.48.4.48    <none>        8080/TCP   5s
    

יצירת HTTPRoute

משאבי ניתוב מגדירים כללים ספציפיים לפרוטוקול למיפוי תנועה משערים (Gateway) לשרתי קצה עורפיים של Kubernetes. רכיב HTTPRoute מבצע התאמה וסינון של תנועת HTTP ו-HTTPS, ונתמך על ידי כל רכיבי gke-l7-* GatewayClass.

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

  1. שומרים את המניפסט הבא בקובץ בשם store-route-external.yaml:

    kind: HTTPRoute
    apiVersion: gateway.networking.k8s.io/v1
    metadata:
      name: store-external
    spec:
      parentRefs:
      # Bind the route to the 'external-http' Gateway.
      - kind: Gateway
        name: external-http
      hostnames:
      - "store.example.com"
      rules:
      # Default rule for store.example.com that sends traffic to the store-v1 service.
      - backendRefs:
        - name: store-v1
          port: 8080
      # Match requests with the "env: canary" header and send them to the store-v2 service.
      - matches:
        - headers:
          - name: env
            value: canary
        backendRefs:
        - name: store-v2
          port: 8080
      # Match requests with the path "/de" and sends them to the store-german service.
      - matches:
        - path:
            value: /de
        backendRefs:
        - name: store-german
          port: 8080
    

    במניפסט הזה מתואר HTTPRoute שמפנה אל external-httpGateway.

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

    kubectl apply -f store-route-external.yaml
    

    ‫HTTPRoute‏ store קשור ל-Gateway‏ external-http באמצעות המאפיין parentRefs. בתרשים הבא מוצגים כללי הניתוב שהוגדרו במאזן העומסים הבסיסי:

    כללי הניתוב שהוגדרו על ידי HTTPRoute של החנות

    כללי הניתוב מעבדים תנועת HTTP באופן הבא:

    • תנועה אל מסלולי store.example.com/de אל שירות store-german.
    • תנועת נתונים אל store.example.com עם כותרת HTTP‏ "env: canary" מנותבת אל שירות store-v2.
    • התנועה שנותרה אל store.example.com מנותבת לשירות store-v1.
  3. מוודאים שרכיב ה-HTTPRoute נפרס:

    kubectl describe httproute store-external
    

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

    Name:         store-external
    Namespace:    default
    Labels:       <none>
    Annotations:  <none>
    API Version:  gateway.networking.k8s.io/v1
    Kind:         HTTPRoute
    # Multiple lines are omitted here.
    Spec:
      Hostnames:
        store.example.com
      Parent Refs:
        Group:  gateway.networking.k8s.io
        Kind:   Gateway
        Name:   external-http
      Rules:
        Backend Refs:
          Group:
          Kind:    Service
          Name:    store-v1
          Port:    8080
          Weight:  1
        Matches:
          Path:
            Type:   PathPrefix
            Value:  /
        Backend Refs:
          Group:
          Kind:    Service
          Name:    store-v2
          Port:    8080
          Weight:  1
        Matches:
          Headers:
            Name:   env
            Type:   Exact
            Value:  canary
          Path:
            Type:   PathPrefix
            Value:  /
        Backend Refs:
          Group:
          Kind:    Service
          Name:    store-german
          Port:    8080
          Weight:  1
        Matches:
          Path:
            Type:   PathPrefix
            Value:  /de
    Status:
      Parents:
        # This section shows the status of this route in relation to each Gateway attached.
        Conditions:
          Last Transition Time:  2022-11-01T05:42:31Z
          Message:
          Reason:                Accepted
          Status:                True # Means that the Gateway has validated and accepted this route's configuration.
          Type:                  Accepted
          Last Transition Time:  2022-11-01T05:43:18Z
          Message:
          Reason:                ReconciliationSucceeded
          Status:                True
          Type:                  Reconciled
        Controller Name:         networking.gke.io/gateway
        Parent Ref:
          Group:  gateway.networking.k8s.io
          Kind:   Gateway
          Name:   external-http
    Events:
      Type     Reason  Age    From                   Message
      ----     ------  ----   ----                   -------
      Normal   ADD     2m48s  sc-gateway-controller  default/store-external
      Normal  SYNC  61s (x3 over 2m27s)  sc-gateway-controller  Bind of HTTPRoute "default/store-external" to ParentRef Group:       "gateway.networking.k8s.io",
      ...
    
  4. מוודאים ש-HTTPRoute קשור ל-Gateway:

    kubectl describe gateway external-http
    

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

    Name:         external-http
    Namespace:    default
    Labels:       <none>
    # Multiple lines are omitted here.
    Status:
      Addresses:
        Type:   IPAddress
        Value:  34.149.207.45
      Conditions:
        Last Transition Time:  2022-11-01T05:37:21Z
        Message:
        Reason:                Scheduled
        Status:                True
        Type:                  Scheduled
        Last Transition Time:  2022-11-01T05:43:18Z
        Message:
        Reason:                Ready
        Status:                True
        Type:                  Ready
      Listeners:
        Attached Routes:  1
        Conditions:
          Last Transition Time:  2022-11-01T05:43:18Z
          Message:
          Reason:                Ready
          Status:                True
          Type:                  Ready
        Name:                    https
        Supported Kinds:
          Group:  gateway.networking.k8s.io
          Kind:   HTTPRoute
          # Multiple lines are omitted here.
    

שליחת תנועה לאפליקציה

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

  1. קבלת כתובת ה-IP של השער:

    kubectl get gateways.gateway.networking.k8s.io external-http -o=jsonpath="{.status.addresses[0].value}"
    

    הפלט הוא כתובת IP.

  2. יוצרים מכונה וירטואלית:

    gcloud cloud-shell ssh
    
  3. שליחת תנועה לכתובת ה-IP של השער מהמכונה הווירטואלית. צריך להגדיר את כותרת המארח באופן ידני כי אתם לא הבעלים של שם המארח example.com.

    curl https://store.example.com --resolve store.example.com:443:GATEWAY_IP_ADDRESS --cacert cacert.pem -v
    

    מחליפים את GATEWAY_IP_ADDRESS בכתובת ה-IP של השער מהשלב הקודם.

    cacert.pem: קובץ האישור שיצרתם. צריך לשמור את הקובץ הזה במחשב שמשמש להתחברות לשער.

    בפלט מוצג מידע מאפליקציית ההדגמה על המיקום שבו האפליקציה פועלת:

    {
      "cluster_name": "gke1",
      "host_header": "store.example.com",
      "metadata": "store-v1",
      "node_name": "gke-gke1-pool-2-bd121936-5pfc.c.gateway-demo-243723.internal",
      "pod_name": "store-v1-84b47c7f58-pmgmk",
      "pod_name_emoji": "💇🏼‍♀️",
      "project_id": "gateway-demo-243723",
      "timestamp": "2022-09-25T13:31:17",
      "zone": "us-central1-a"
    }
    
  4. כדי לבדוק את ההתאמה לנתיב, עוברים לגרסה הגרמנית של שירות store בכתובת store.example.com/de:

    curl https://store.example.com/de --resolve store.example.com:443:GATEWAY_IP_ADDRESS --cacert cacert.pem -v
    

    הפלט מאשר שהבקשה הוגשה על ידי store-german Pod:

    {
      "cluster_name": "gke1",
      "host_header": "store.example.com",
      "metadata": "Gutentag!",
      "node_name": "gke-gke1-pool-2-bd121936-n3xn.c.gateway-demo-243723.internal",
      "pod_name": "store-german-5cb6474c55-lq5pl",
      "pod_name_emoji": "🧞‍♀",
      "project_id": "gateway-demo-243723",
      "timestamp": "2022-09-25T13:35:37",
      "zone": "us-central1-a"
    }
    
  5. שליחת תנועה לגרסת הקנרי של שירות store באמצעות כותרת ה-HTTP‏ env: canary:

    curl -H "env: canary" https://store.example.com --resolve store.example.com:443:GATEWAY_IP_ADDRESS --cacert cacert.pem -v
    

    הפלט מאשר שהבקשה הוגשה על ידי store-v2 Pod:

    {
      "cluster_name": "gke1",
      "host_header": "store.example.com",
      "metadata": "store-v2",
      "node_name": "gke-gke1-pool-2-bd121936-5pfc.c.gateway-demo-243723.internal",
      "pod_name": "store-v2-5788476cbd-s9thb",
      "pod_name_emoji": "👩🏿",
      "project_id": "gateway-demo-243723",
      "timestamp": "2022-09-25T13:38:26",
      "zone": "us-central1-a"
    }
    

פריסת שער חיצוני אזורי

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

יצירת תת-רשת של שרת proxy לשער אזורי

כדי ליצור שער שמשתמש במאזן עומסים חיצוני אזורי של אפליקציות, צריך קודם להגדיר רשת משנה לשימוש פרוקסי בלבד. לכל אזור ברשת VPC שבה משתמשים במאזן עומסים חיצוני אזורי של אפליקציות (ALB) צריך להיות external_managed_proxy רשת משנה. רשת המשנה הזו מספקת כתובות IP פנימיות לשרתי ה-proxy של מאזן העומסים.

יצירת אישור לאבטחת תנועת הלקוחות

אתם יכולים להשתמש באישור שהונפק ואומת על ידי רשות האישורים (CA) שלכם או ליצור אישור עם חתימה עצמית. מידע נוסף על יצירת אישור זמין במאמר בנושא אחסון אישור ב-Kubernetes Secret.

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

  • אישורים שמנוהלים על ידי Google או שמנוהלים באופן עצמאי ב-Certificate Manager
  • אישורי SSL אזוריים בניהול עצמי
  • סודות של Kubernetes

CertificateMap או אישורי SSL בניהול Google לא נתמכים עם שערים אזוריים.

מידע נוסף זמין במאמר בנושא אישורים ומאזני עומסים. Google Cloud

יצירת שער HTTP(S) חיצוני אזורי

  1. יוצרים כתובת IP סטטית אזורית למאזן העומסים החיצוני.

    gcloud compute addresses create IP_ADDRESS_NAME \
      --region=COMPUTE_REGION \
      --network-tier=STANDARD
    

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

    • IP_ADDRESS_NAME: השם של כתובת ה-IP הסטטית החדשה.
    • COMPUTE_REGION: האזור ב-Compute Engine שבו האשכול פועל.
  2. יוצרים שער אזורי חיצוני של מאזן עומסים של אפליקציות באמצעות אישור בניהול עצמי באופן הבא ושומרים את המניפסט כ-regional-gateway.yaml:

      kind: Gateway
      apiVersion: gateway.networking.k8s.io/v1
      metadata:
        name: external-regional-http
      spec:
        # Name of an existing GatewayClass.
        gatewayClassName: gke-l7-regional-external-managed
        # Listen for HTTPS traffic on port 443
        listeners:
        - name: https
          protocol: HTTPS
          port: 443
          tls:
            # Terminate the TLS session with the client at the Gateway.
            mode: Terminate
            # Certificates for the Gateway to use to create a new TLS session.
            certificateRefs:
            - name: store-example-com
        # The name of the static IP address of the external load balancer.
        # You can also use the `IPAddress` type to specify the actual IP address.
        addresses:
        - type: NamedAddress
          value: IP_ADDRESS_NAME
    
  3. החלת מניפסט regional-gateway:

      kubectl apply -f regional-gateway.yaml
    
  4. מאמתים את ההגדרה.

      kubectl get gateway
    

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

    NAME            CLASS                              ADDRESS         READY   AGE
    external-http   gke-l7-regional-external-managed   35.118.32.224   True    49s
    

    כדי לקבל פרטים נוספים, משתמשים בפקודה describe:

    kubectl describe gateway
    

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

    Name:         external-regional-http
    Namespace:    default
    Labels:       <none>
    ...
    Spec:
      Gateway Class Name:  gke-l7-regional-external-managed
      Listeners:
        Allowed Routes:
          Namespaces:
            From:  Same
        Name:      https
        Port:      443
        Protocol:  HTTPS
        Tls:
          Certificate Refs:
            Group:
            Kind:   Secret
            Name:   store-example-com
          Mode:     Terminate
      ...
    

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

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

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

יצירת HTTPRoute

כדי להתאים ולסנן תנועה של HTTP ו-HTTPS, צריך ליצור HTTPRoute.

שליחת תנועה לאפליקציה

אחרי שפורסים את האפליקציה ויוצרים HTTPRoutes, אפשר להעביר תנועה לאפליקציה.

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

שימוש בשערי גישה משותפים

‫Gateway API משתמש במשאבים נפרדים, משאבי Gateways ו-Route, כדי לפרוס מאזני עומסים וכללי ניתוב. ההגדרה הזו שונה מ-Ingress, שמשלבת את הכול במשאב אחד. ה-Gateway מאפשר לפצל את האחריות בין המשאבים, כך שניתן לפרוס את מאזן העומסים ואת כללי הניתוב שלו בנפרד, ומשתמשים או צוותים שונים יכולים לפרוס אותם. כך שערים יכולים להפוך לשערים משותפים שמצורפים למסלולים שונים רבים, שאפשר להיות הבעלים שלהם ולנהל אותם על ידי צוותים עצמאיים, גם במרחבי שמות שונים.

פריסת מסלולים מול שער משותף

הדוגמה הזו מבוססת על internal-http השער שנפרס בפריסת שער פנימי.

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

  1. מפעילים את האפליקציה לדוגמה:

    kubectl apply -f https://raw.githubusercontent.com/GoogleCloudPlatform/gke-networking-recipes/main/gateway/gke-gateway-controller/app/site.yaml
    
  2. שומרים את המניפסט הבא בקובץ בשם site-route-internal.yaml:

    kind: HTTPRoute
    apiVersion: gateway.networking.k8s.io/v1
    metadata:
      name: site-internal
    spec:
      # Attach the HTTPRoute to the `internal-http` Gateway.
      parentRefs:
      - kind: Gateway
        name: internal-http
      # Route requests that have `site.example.com` in the Host header.
      hostnames:
      - "site.example.com"
      # Send all requests to the `site-v1` Service.
      rules:
      - backendRefs:
        - name: site-v1
          port: 8080
    

    קובץ המניפסט הזה מתאר HTTPRoute שתואם לכל התנועה של site.example.com ומנתב אותה לשירות site-v1.

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

    kubectl apply -f site-route-internal.yaml
    
  4. מוודאים ש-HTTPRoute מצורף ל-Gateway:

    kubectl describe httproute.gateway.networking.k8s.io site-internal
    

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

    Status:
      Parents:
        Conditions:
          Last Transition Time:  2023-01-09T15:05:43Z
          Message:
          Reason:                Accepted
          Status:                True
          Type:                  Accepted
          Last Transition Time:  2023-01-09T15:05:43Z
          Message:
          Reason:                ReconciliationSucceeded
          Status:                True
          Type:                  Reconciled
        Controller Name:         networking.gke.io/gateway
        Parent Ref:
          Group:  gateway.networking.k8s.io
          Kind:   Gateway
          Name:   internal-http
          ...
    

    אם התנאי Accepted של שער הכניסה הוא True, ה-HTTPRoute נקשר בהצלחה לשער הכניסה. מידע נוסף על השדה 'סטטוס' זמין במאמר בנושא סטטוס המסלול.

  5. מוודאים שהתנועה אל שער הכניסה מנותבת בצורה נכונה:

    curl -H "host: site.example.com" GATEWAY_IP_ADDRESS
    curl -H "host: store.example.com" GATEWAY_IP_ADDRESS
    

    מחליפים את GATEWAY_IP_ADDRESS בכתובת ה-IP של השער הפנימי.

    חובה להשתמש במכונה וירטואלית (VM) באותו VPC כמו השער.

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

    {
      "cluster_name": "CLUSTER_NAME",
      "host_header": "site.example.com",
      "metadata": "site-v1",
      "pod_name": "site-v1-5d64fc4d7d-fz6f6",
      "pod_name_emoji": "👩🏼‍🍳",
      "project_id": "PROJECT_ID",
      "timestamp": "2022-11-02T19:07:01",
      "zone": "ZONE_NAME"
    }
    ...
    {
      "cluster_name": "CLUSTER_NAME",
      "host_header": "store.example.com",
      "metadata": "store-v1",
      "pod_name": "store-v1-6d8d58d78-vz8pn",
      "pod_name_emoji": "🧝🏻‍♂️",
      "project_id": "PROJECT_ID",
      "timestamp": "2022-11-02T19:07:01",
      "zone": "ZONE_NAME"
    }
    

    הפלט הזה מציין שבקשות עם כותרת המארח site.example.com מגיעות לשירות site-v1, ובקשות עם כותרת המארח store.example.com מגיעות לשירות store-v1.

הגדרת מסלול רשת

אתם יכולים לציין את מסלול הרשת של כתובת המאזין של מאזן עומסים חיצוני אזורי של אפליקציות באמצעות השדה type במערך addresses[] בהגדרת שער. אם לא מציינים מסלול רשת, כברירת מחדל מוגדרת כתובת IP ארעית במסלול הרגיל לשער.

משתמשים בערכים הבאים בשדה type:

  • networking.gke.io/premium-ephemeral-ipv4-address: מקצה כתובת IP ברמת פרימיום.
  • networking.gke.io/standard-ephemeral-ipv4-address: מקצה כתובת IP ברמה Standard.

כדי להקצות כתובות IP משני מסלולי הרשת, מציינים את שני הסוגים בשדה addresses.

בדוגמה הבאה אפשר לראות איך להקצות כתובת IP ברמת מסלול פרימיום לשער. Google Cloud כדי להקצות כתובת IP במסלול הרגיל, משתמשים ב-networking.gke.io/standard-ephemeral-ipv4-address.

  1. שומרים את קובץ המניפסט לדוגמה הבא בשם external-regional-http.yaml:

    kind: Gateway
    apiVersion: gateway.networking.k8s.io/v1
    metadata:
      name: external-regional-http
    spec:
      # Name of an existing GatewayClass.
      gatewayClassName: gke-l7-regional-external-managed
      # Listen for HTTPS traffic on port 443.
      listeners:
      - name: https
        protocol: HTTPS
        port: 443
        tls:
          # Terminate the TLS session with the client at the Gateway.
          mode: Terminate
          # Certificates for the Gateway to use to create a new TLS session.
          certificateRefs:
          - name: store-example-com
        addresses:
        # Request a Premium Tier ephemeral IPv4 address for the Gateway.
        - type: networking.gke.io/premium-ephemeral-ipv4-address
    
  2. החלת המניפסט לדוגמה:

    kubectl apply -f external-regional-http.yaml
    

הגדרת קצה עורפי שמוגדר כברירת מחדל בשער

כל ה-GatewayClasses‏ gke-l7-* מחזירים HTTP 404 לתנועה שלא תואמת. אפשר להגדיר את קצה העורף (backend) כברירת מחדל באמצעות מסלול ברירת מחדל מפורש ששולח תנועה לא תואמת לשירות שסופק על ידי המשתמש.

הגדרנו את השערים כך שיטפלו בקודי שגיאה כמו 404 (לא נמצא) ו-500 (שגיאה בחיבור לשרת), גם ללא הגדרות ספציפיות של קצה העורפי. ההתנהגות שמוגדרת כברירת מחדל עשויה להשתנות בהתאם להטמעות של Gateway. כדי לשלוט טוב יותר בטיפול בשגיאות, כדאי להגדיר קצה עורפי בהתאמה אישית.

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

kind: HTTPRoute
apiVersion: gateway.networking.k8s.io/v1
metadata:
  name: custom-default-backend
spec:
  parentRefs:
  - kind: Gateway
    name: my-internal-gateway
  # Omit the `hostnames` field to route all unmatched traffic from the
  # attached Gateway.
  rules:
  - backendRefs:
    - name: my-custom-default-backend-service
      port: 8080

ה-HTTPRoute הזה תואם לכל התנועה משער מסוים. אפשר להגדיר רק כלל אחד כזה לכל שער, אחרת הכללים יתנגשו וסדר העדיפות יחול.

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

הגדרת כתובת IP סטטית לשער

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

אחרי פריסת שער, כתובת ה-IP שלו מופיעה בשדה הסטטוס:

kind: Gateway
...
status:
  addresses:
    - value: 10.15.32.3

בהתאם ל-GatewayClass, כתובת ה-IP מוקצית מרשתות המשנה הבאות:

GatewayClasses מאגר כתובות IP שמוגדר כברירת מחדל
  • gke-l7-rilb
  • gke-l7-rilb-mc
  • כתובות IP פרטיות אזוריות מטווח כתובות ה-IPv4/IPv6 של הצומת הראשי
  • gke-l7-regional-external-managed
  • gke-l7-regional-external-managed-mc
  • כתובות IP ציבוריות אזוריות מטווחים אזוריים של כתובות IPv4/IPv6 חיצוניות של Google
  • gke-l7-global-external-managed
  • gke-l7-global-external-managed-mc
  • gke-l7-gxlb
  • gke-l7-gxlb-mc
  • כתובות IP ציבוריות גלובליות מטווחים גלובליים של IPv4/IPv6 חיצוניים של Google

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

    שימוש בכתובת IP עם שם

    אפשר להגדיר כתובת IPv4 או IPv6 על ידי ציון NamedAddress. לפני שיוצרים שער, צריך להקצות כתובת IP סטטית.

    1. יוצרים משאב של כתובת IP סטטית:

      gcloud compute addresses create IP_ADDRESS_NAME \
          --purpose=SHARED_LOADBALANCER_VIP \
          --region=COMPUTE_REGION \
          --subnet=SUBNET \
          --project=PROJECT_ID
      

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

      • IP_ADDRESS_NAME: השם של כתובת ה-IP הסטטית החדשה
      • COMPUTE_REGION: עבור שערים אזוריים, האזור ב-Compute Engine שבו האשכול פועל. אין צורך בדגל הזה בשערים גלובליים חיצוניים.
      • SUBNET: רשת המשנה של כתובת ה-IP. אין צורך בדגל הזה בשערים גלובליים חיצוניים.
      • PROJECT_ID: הפרויקט שבו פועל אשכול GKE.
    2. שומרים את המניפסט הבא בקובץ בשם named-ip-gateway.yaml:

      kind: Gateway
      apiVersion: gateway.networking.k8s.io/v1
      metadata:
        name: internal-http
      spec:
        gatewayClassName: gke-l7-rilb
        listeners:
        - name: http
          protocol: HTTP
          port: 80
        addresses:
        - type: NamedAddress
          value: IP_ADDRESS_NAME
      

      המניפסט הזה מתאר שער שמפנה לכתובת ה-IP שצוינה בשם.

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

      kubectl apply -f named-ip-gateway.yaml
      
    4. מאמתים את כתובת ה-IP של השער:

      kubectl describe gateway internal-http
      

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

      Name:         internal-http
      Namespace:    default
      Labels:       <none>
      ...
      Spec:
        Addresses:
          Type:              NamedAddress
          Value:             IP_ADDRESS_NAME
        Gateway Class Name:  gke-l7-rilb
        Listeners:
          Allowed Routes:
            Namespaces:
              From:  Same
          Name:      http
          Port:      80
          Protocol:  HTTP
      Status:
        Addresses:
          Type:   IPAddress
          Value:  10.15.32.103
      

    הגדרת הפניות אוטומטיות מ-HTTP ל-HTTPS

    שירות Cloud Load Balancing מציע פונקציונליות של הפניה אוטומטית מ-HTTP ל-HTTPS. מאזן עומסים חיצוני של אפליקציות מפנה בקשות HTTP לא מוצפנות למאזן עומסים של HTTPS שמשתמש באותה כתובת IP. כשיוצרים שער עם הפניות אוטומטיות מ-HTTP ל-HTTPS, שני מאזני העומסים האלה נוצרים אוטומטית. בקשות לכתובת ה-IP החיצונית של שער הכניסה ביציאה 80 מופנות אוטומטית לאותה כתובת IP חיצונית ביציאה 443.

    כברירת מחדל, הפניות מ-HTTP ל-HTTPS לא מוגדרות בשער.

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

    בדוגמה הבאה מוצג איך אפשר להשתמש בהפניה אוטומטית מ-HTTP ל-HTTPS כדי לוודא שהתנועה מהלקוחות לאפליקציות האינטרנט שלכם תמיד מופנית לדף מאובטח.

    אין תמיכה בהפניות אוטומטיות מ-HTTP ל-HTTPS ב-GatewayClasses‏ gke-l7-gxlb ו-gke-l7-gxlb-mc. מידע נוסף על התכונות השונות שנתמכות בכל GatewayClass זמין במאמר יכולות של GatewayClass.

    שימו לב: הקטע hostnames ב-HTTPRoute הוא אופציונלי. אפשר ליצור הפניה אוטומטית כללית לכל שמות המארחים ביציאת HTTP ספציפית על ידי השמטת הקטע hostnames. בנוסף, אפשר להשתמש בהפניה אוטומטית עם תו כללי לחיפוש, לדוגמה:

    ...
    hostnames:
    - "*.example.com" # Matches all subdomains of example.com
    ...
    

    הפניית תנועת HTTP ממרחב שמות של תשתית

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

    בדוגמה הבאה מוצגת הגבלה נוספת של השימוש במאזין HTTP כדי למנוע שימוש לא מכוון בפרוטוקול לא מאובטח מצד צוותי האפליקציה. בדוגמה הזו מוגדר שער שיאפשר ל-HTTPRoute להשתמש במאזין HTTP רק אם המסלול נמצא במרחב שמות עם התווית otherInfra: httpToHttps. עם זאת, השער מאפשר ל-HTTPRoutes בכל מרחב שמות להשתמש במאזין HTTPS. אפשר להגביל את מרחב השמות http-redirect באמצעות Kubernetes RBAC, כדי שצוותי פיתוח אפליקציות לא יוכלו ליצור בטעות HTTPRoute במרחב השמות הזה.

    1. יוצרים את מרחב השמות של שער. שומרים את קובץ המניפסט בשם gateway-namespace.yaml:

      apiVersion: v1
      kind: Namespace
      metadata:
        name: gateway-infra
      
    2. החלת המניפסט:

      kubectl apply -f gateway-namespace.yaml
      
    3. יוצרים את מרחב השמות של שער ושומרים את המניפסט כ-redirect-namespace.yaml:

      apiVersion: v1
      kind: Namespace
      metadata:
        name: http-redirect
        labels:
          otherInfra: httpToHttps
      

      מרחב השמות http-redirect כולל את התווית otherInfra: httpToHttps.

    4. החלת המניפסט:

      kubectl apply -f redirect-namespace.yaml
      
    5. כדי להגביל את השימוש במאזין http, יוצרים Gateway באמצעות המניפסט הבא. שומרים את קובץ המניפסט בשם external-gateway.yaml:

      kind: Gateway
      apiVersion: gateway.networking.k8s.io/v1
      metadata:
        name: external-http
        namespace: gateway-infra
      spec:
        # Name of an existing GatewayClass.
        gatewayClassName: gke-l7-global-external-managed
        listeners:
        - name: http
          protocol: HTTP
          port: 80
          #  Allow only HTTPRoutes from namespaces that have the
          # `otherInfra: httpToHttps` label to use this listener.
          allowedRoutes:
            kinds:
            - kind: HTTPRoute
            namespaces:
              from: Selector
              selector:
                matchLabels:
                  otherInfra: httpToHttps
        - name: https
          protocol: HTTPS
          port: 443
          # Allow HTTPRoutes from any namespace to use this listener.
          allowedRoutes:
            kinds:
            - kind: HTTPRoute
            namespaces:
              from: All
          tls:
            mode: Terminate
            options:
              networking.gke.io/pre-shared-certs: store-example-com
      
      • השדה namespace מציין שהשער נוצר במרחב השמות gateway-infra.

      • השדה namespaces בקטע allowedRoutes מגביל את מאזין ה-HTTP למרחב השמות שתואם לתווית otherInfra: httpToHttps.

    6. החלת המניפסט:

      kubectl apply -f external-gateway.yaml
      
    7. כדי לכפות את ההפניה האוטומטית ל-HTTPS, יוצרים HTTPRoute שמוגדר כברירת מחדל באמצעות המניפסט הבא. שומרים את קובץ המניפסט בשם http-redirect.yaml:

      kind: HTTPRoute
      apiVersion: gateway.networking.k8s.io/v1
      metadata:
        name: redirect
        # Create the HTTPRoute in the `http-redirect` namespace.
        namespace: http-redirect
      spec:
        # Attach the HTTPRoute to the `http` listener in the `external-http`
        # Gateway.
        parentRefs:
        - namespace: gateway-infra
          name: external-http
          sectionName: http
        rules:
        # Respond to the request with an HTTPS redirection.
        - filters:
          - type: RequestRedirect
            requestRedirect:
              scheme: https
      
      • השדה sectionName מורה ל-Gateway להתאים רק ל-http listener. המסנן RequestRedirect כופה את ההפניה למאזין https.
    8. החלת המניפסט:

      kubectl apply -f http-redirect.yaml
      
    9. יוצרים שירות לאפליקציה באמצעות המניפסט הבא. שומרים את קובץ המניפסט בשם service-deployment.yaml:

      apiVersion: v1
      kind: Service
      metadata:
        name: store-v1
      spec:
        selector:
          app: store
          version: v1
        ports:
        - port: 8080
          targetPort: 8080
      ---
      apiVersion: apps/v1
      kind: Deployment
      metadata:
        name: store-v1
      spec:
        replicas: 2
        selector:
          matchLabels:
            app: store
            version: v1
        template:
          metadata:
            labels:
              app: store
              version: v1
          spec:
            containers:
            - name: whereami
              image: us-docker.pkg.dev/google-samples/containers/gke/whereami:v1
              ports:
              - containerPort: 8080
              env:
              - name: METADATA
                value: "store-v1"
      
    10. החלת המניפסט:

      kubectl apply -f service-deployment.yaml
      
    11. יוצרים HTTPRoute לאפליקציה שמאפשרת רק HTTPS באמצעות המניפסט הבא. שומרים את קובץ המניפסט בשם http-route.yaml:

      kind: HTTPRoute
      apiVersion: gateway.networking.k8s.io/v1
      metadata:
        name: store-external
        labels:
          gateway: external-http
      spec:
        # Attach the HTTPRoute to the HTTPS listener in the `external-http`
        # Gateway.
        parentRefs:
        - name: external-http
          namespace: gateway-infra
          sectionName: https
        # Match requests that have the `store.example.com` Host header.
        hostnames:
        - "store.example.com"
        # Route requests to the `store-v1` Service.
        rules:
        - backendRefs:
          - name: store-v1
            port: 8080
      
    12. החלת המניפסט:

      kubectl apply -f http-route.yaml
      

    הגדרת הפניות אוטומטיות של נתיבים ושכתוב של כתובות URL

    הפניות אוטומטיות של נתיבים כוללות הפניה אוטומטית של בקשה נכנסת מנתיב כתובת URL אחד לנתיב אחר. הפניות נתיב מאפשרות לשנות את מבנה כתובת ה-URL כשצריך לטפל בכתובות URL מיושנות או שהוצאו משימוש.

    שינוי כתובות URL עוזר לשנות את כתובת ה-URL הנכנסת לפני העיבוד שלה בשרת. היא מאפשרת לשנות את המבנה או הפורמט של כתובת ה-URL בלי לשנות בפועל את התוכן או את מבנה הקובץ. שיכתוב כתובות URL מועיל ליצירת כתובות URL ידידותיות למשתמש ולקידום אתרים (SEO), שקל לזכור ולהבין. כברירת מחדל, הפניות אוטומטיות של נתיבים ושכתוב של כתובות URL לא מוגדרים, ולכן צריך להגדיר אותן באופן מפורש באמצעות מסנן ב-HTTPRoute.

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

    הגדרת הפניות אוטומטיות של נתיבים

    אפשר להגדיר הפניות אוטומטיות של נתיבים כך שיחליפו את הנתיב כולו או רק את הקידומת בכתובת ה-URL.

    החלפת הנתיב כולו

    1. כדי להחליף נתיב שלם, מגדירים מסנן ב-HTTPRoute שמחליף כל כתובת URL שמכילה את הקידומת /any-path בנתיב כתובת ה-URL בערך המדויק /new-path.

    2. יוצרים קובץ מניפסט HTTPRoute באופן הבא ונותנים לו את השם store.yaml:

        apiVersion: gateway.networking.k8s.io/v1
        kind: HTTPRoute
        metadata:
          name: store
        spec:
          parentRefs:
          - kind: Gateway
            name: external-http
          hostnames:
          - store.example.com
          rules:
          - matches:
            - path:
                # Match requests by a prefix, like `/any-path` and `/any-path/home`.
                type: PathPrefix
                value: /any-path
            filters:
            - type: RequestRedirect
              requestRedirect:
                path:
                  # Replace the full path with `/new-path`. For example, both
                  # `/any-path/home` and `/any-path` become `/new-path`.
                  type: ReplaceFullPath
                  replaceFullPath: /new-path
                statusCode: 302
      

      לדוגמה, המניפסט הזה מגדיר כלל ניתוב ל-HTTPRoute באופן הבא: כל מסלול לכתובת ה-URL https://store.example.com/any-path/... צריך להיות מופנה למיקום חדש, https://store.example.com/new-path/ (strict).

    3. החלת המניפסט:

      kubectl apply -f store.yaml
      

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

    החלפת קידומת בלבד

    1. כדי להחליף רק קידומת, מגדירים מסנן ב-HTTPRoute שמחליף כל כתובת URL שמכילה את הקידומת /any-prefix בנתיב כתובת ה-URL בערך המדויק /new-prefix.

    2. יוצרים קובץ מניפסט HTTPRoute באופן הבא ונותנים לו את השם store.yaml:

      apiVersion: gateway.networking.k8s.io/v1
      kind: HTTPRoute
      metadata:
        name: store
      spec:
        parentRefs:
          - kind: Gateway
            name: external-http
        hostnames:
        - store.example.com
        rules:
        - matches:
            - path:
                # Match requests by prefix, like `/any-prefix` and
                # `/any-prefix/home`.
                type: PathPrefix
                value: /any-prefix
          filters:
          - type: RequestRedirect
            requestRedirect:
              path:
                # Replace the matched prefix with `/new-prefix`. For example,
                # `/any-prefix` becomes `/new-prefix` and `/any-prefix/home`
                # becomes `/new-prefix/home`.
                type: ReplacePrefixMatch
                replacePrefixMatch: /new-prefix
              statusCode: 302
      

      לדוגמה, במניפסט הזה מוגדר כלל ניתוב ל-HTTPRoute באופן הבא: כל ניתוב לכתובת ה-URL https://store.example.com/any-path/v1/... צריך להיות מופנה למיקום חדש, https://store.example.com/new-path/v1/... (בלבד).

    3. החלת המניפסט:

        kubectl apply -f store.yaml
      

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

    הגדרת כתיבה מחדש של כתובות URL

    הגדרת כתיבה מחדש של כתובות URL כדי לשנות את האופן שבו כתובת URL מוצגת למשתמשים. אפשר להשתמש בשכתוב כתובות URL כדי להפוך אותן לידידותיות יותר למשתמשים, כדי לשפר את ה-SEO או כדי להפנות משתמשים לדף חדש.

    לשכתב את שם המארח כולו

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

    1. מגדירים מסנן ב-HTTPRoute שמורה ל-Gateway להחליף את המידע Host בכותרת הבקשה מ-www.example.com ל-store.example.com לפני העברת הבקשה לשירות לקצה העורפי.

    2. יוצרים קובץ מניפסט HTTPRoute באופן הבא ונותנים לו את השם www.yaml:

        apiVersion: gateway.networking.k8s.io/v1
        kind: HTTPRoute
        metadata:
          name: www
        spec:
          parentRefs:
            - kind: Gateway
              name: external-http
          hostnames:
          - www.example.com
          rules:
          - filters:
            - type: URLRewrite
              # Replace the hostname in the URL with `store.example.com`.
              urlRewrite:
                hostname: store.example.com
            backendRefs:
            - name: store-v1
              port: 8080
      

      לדוגמה, עם ההגדרה שלמעלה, כל בקשה אל https://www.example.com מועברת לשירות לקצה העורפי עם הכותרת Host: store.example.com, במקום Host: www.example.com.

    3. החלת המניפסט:

        kubectl apply -f www.yaml
      

    כתיבה מחדש באמצעות משני נתיבים

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

    כדי לשכתב באמצעות משני נתיבים:

    1. מגדירים מסנן ב-HTTPRoute שמורה ל-Gateway להחליף את פרטי ה-Host בכותרת הבקשה מ-www.example.comto store.example.com ולהחליף את הערך /store ב-/ לפני העברת הבקשה לשירות הקצה העורפי.

    2. יוצרים קובץ מניפסט HTTPRoute באופן הבא ונותנים לו את השם www.yaml:

        apiVersion: gateway.networking.k8s.io/v1
        kind: HTTPRoute
        metadata:
          name: www
        spec:
          parentRefs:
            - kind: Gateway
              name: external-http
          hostnames:
          - www.example.com
          rules:
          - matches:
            - path:
                type: PathPrefix
                value: /store
            filters:
            - type: URLRewrite
              # For URLs that have `/store` in the path, replace the hostname with
              # store.example.com and replace the `/store` prefix with `/de`.
              urlRewrite:
                hostname: store.example.com
                path:
                  type: ReplacePrefixMatch
                  replacePrefixMatch: /de
            backendRefs:
            - name: store-german
              port: 8080
      

      לדוגמה, בהגדרה שלמעלה, כל בקשה אל https://www.example.com/store/... מועברת לשירות לקצה העורפי עם Host: store.example.com בכותרת הבקשה (במקום Host: www.example.com), ו-/store נכתב מחדש כ-/de.

    3. החלת המניפסט:

      kubectl apply -f www.yaml
      

    אימות ההגדרות את ההגדרות

    כדי לוודא שהמסנן הוחל אחרי שיצרתם את ה-HTTPRoute עם מסנני שכתוב כתובות URL או הפניות אוטומטיות של נתיבים, מבצעים את הפעולות הבאות:

    kubectl get httproute www -o yaml
    

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

      apiVersion: gateway.networking.k8s.io/v1
      kind: HTTPRoute
      metadata:
        annotations:
          kubectl.kubernetes.io/last-applied-configuration: |
            {"apiVersion":"gateway.networking.k8s.io/v1","kind":"HTTPRoute","metadata":{"annotations":{},"name":"www","namespace":"default"},"spec":{"hostnames":["www.example.com"],"parentRefs":[{"kind":"Gateway","name":"external-http"}],"rules":[{"backendRefs":[{"name":"store-german","port":8080}],"filters":[{"type":"URLRewrite","urlRewrite":{"hostname":"store.example.com","path":{"replacePrefixMatch":"/de","type":"ReplacePrefixMatch"}}}],"matches":[{"path":{"type":"PathPrefix","value":"/store"}}]}]}}
        creationTimestamp: "2023-06-22T01:00:42Z"
        generation: 3
        name: www
        namespace: default
        resourceVersion: "51268631"
        uid: e516493e-806d-44d6-ae0d-1c9ff25682cf
      spec:
        hostnames:
        - www.example.com
        parentRefs:
        - group: gateway.networking.k8s.io
          kind: Gateway
          name: external-http
        rules:
        - backendRefs:
          - group: ""
            kind: Service
            name: store-german
            port: 8080
            weight: 1
          filters:
          - type: URLRewrite
            urlRewrite:
              hostname: store.example.com
              path:
                replacePrefixMatch: /de
                type: ReplacePrefixMatch
          matches:
          - path:
              type: PathPrefix
              value: /store
      status:
        parents:
        - conditions:
          - lastTransitionTime: "2023-06-22T01:11:26Z"
            message: ""
            observedGeneration: 2
            reason: Accepted
            status: "True"
            type: Accepted
          - lastTransitionTime: "2023-06-22T01:11:26Z"
            message: ""
            observedGeneration: 2
            reason: ReconciliationSucceeded
            status: "True"
            type: Reconciled
          controllerName: networking.gke.io/gateway
          parentRef:
            group: gateway.networking.k8s.io
            kind: Gateway
            name: external-http
    
    

    כדי לקבל פרטים נוספים, משתמשים בפקודה describe:

    kubectl describe httproute
    

    הגדרת כותרות מותאמות אישית של בקשות ותגובות

    כותרות מותאמות אישית של בקשות ותגובות מאפשרות לכם לציין כותרות נוספות לבקשות ולתגובות של HTTP(S). בהתאם למידע שזוהה על ידי מאזן העומסים, הכותרות האלה יכולות לכלול את המידע הבא:

    • זמן האחזור ללקוח
    • המיקום הגיאוגרפי של כתובת ה-IP של הלקוח
    • פרמטרים של חיבור TLS

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

    כדי להגדיר כותרות בהתאמה אישית, מוסיפים קטע של מסנן לכללים של HTTPRoute באופן הבא:

    הגדרת כותרות בקשות בהתאמה אישית

    יוצרים מניפסט HTTPRoute עם מסנן RequestHeaderModifier ושומרים אותו בשם http-route-request.yaml:

      apiVersion: gateway.networking.k8s.io/v1
      kind: HTTPRoute
      metadata:
        name: store
      spec:
        <...>
        rules:
            filters:
              - type: RequestHeaderModifier
                requestHeaderModifier:
                  <...>
    

    החלת המניפסט:

      kubectl apply -f http-route-request.yaml
    

    הגדרת כותרות תגובה מותאמות אישית

    יוצרים מניפסט HTTPRoute עם מסנן ResponseHeaderModifier ושומרים אותו בשם http-route-response.yaml:

    apiVersion: gateway.networking.k8s.io/v1
    kind: HTTPRoute
    metadata:
      name: store
    spec:
      <...>
      rules:
          filters:
            - type: ResponseHeaderModifier
              responseHeaderModifier:
                <...>
    

    החלת המניפסט:

      kubectl apply -f http-route-response.yaml
    

    אפשר להוסיף, להגדיר ולהסיר כותרות כמו שמתואר במאמר בנושא הטמעה של Gateway API. אפשר להגדיר את HTTPRoute עם כותרת בהתאמה אישית באמצעות Google Cloud משתנים נתמכים.

    דוגמה 1:

    כדי להגדיר HTTPRoute שמוסיף נתוני מיקום של לקוח לבקשת HTTP לפני שליחתה לשירות לקצה העורפי, יוצרים מניפסט HTTPRoute ונותנים לו את השם external-http-request.yaml:

      apiVersion: gateway.networking.k8s.io/v1
      kind: HTTPRoute
      metadata:
        name: store
      spec:
        parentRefs:
          - kind: Gateway
            name: external-http
        hostnames:
        - store.example.com
        rules:
          - matches:
            - path:
                type: PathPrefix
                value: /fr
            filters:
              # Add custom headers to requests that have `/fr` in the path.
              - type: RequestHeaderModifier
                requestHeaderModifier:
                  add:
                    - name: X-Client-Geo-Location
                      value: "{client_region},{client_city}"
            backendRefs:
              - name: store-french
                port: 8080
    

    לדוגמה, עבור לקוחות שנמצאים בשטרסבורג שבצרפת, שער הכניסה מוסיף כותרת כ-X-Client-Geo-Location:FR,Strasbourg.

    דוגמה 2:

    כדי להגדיר HTTPRoute שמוסיף כותרת תגובה מותאמת אישית לתמיכה ב-HTTP Strict Transport Security, יוצרים מניפסט HTTPRoute ונותנים לו את השם external-http-response.yaml:

      apiVersion: gateway.networking.k8s.io/v1
      kind: HTTPRoute
      metadata:
        name: store
      spec:
        parentRefs:
          - kind: Gateway
            name: external-http
        hostnames:
        - store.example.com
        rules:
          - matches:
            - path:
                type: PathPrefix
                value: /de
            filters:
              # Add custom headers to responses to requests that have `/de` in the
              # path.
              - type: ResponseHeaderModifier
                responseHeaderModifier:
                  add:
                    - name: Strict-Transport-Security
                      value: max-age=63072000
            backendRefs:
              - name: store-german
                port: 8080
    

    אימות ההגדרות את ההגדרות

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

        kubectl get httproute
      

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

        NAME    HOSTNAMES               AGE
        store   ["store.example.com"]   4d23h
      
    2. כדי לקבל פרטים נוספים, משתמשים בפקודה describe:

        kubectl describe httproute
      

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

        Name:         store
        Namespace:    default
        Labels:       <none>
        Annotations:  <none>
        API Version:  gateway.networking.k8s.io/v1
        Kind:         HTTPRoute
        Metadata:
          Creation Timestamp:  2023-05-27T00:51:01Z
          Generation:          5
          Resource Version:    25418887
          UID:                 2e07a1b8-420b-41b4-acd1-cecbfcd39f42
        Spec:
          Hostnames:
            store.example.com
          Parent Refs:
            Group:  gateway.networking.k8s.io
            Kind:   Gateway
            Name:   external-http
          Rules:
            Backend Refs:
              Group:
              Kind:    Service
              Name:    store-v1
              Port:    8080
              Weight:  1
            Matches:
              Path:
                Type:   PathPrefix
                Value:  /
            Backend Refs:
              Group:
              Kind:    Service
              Name:    store-v2
              Port:    8080
              Weight:  1
            Matches:
              Headers:
                Name:   env
                Type:   Exact
                Value:  canary
              Path:
                Type:   PathPrefix
                Value:  /
            Backend Refs:
              Group:
              Kind:    Service
              Name:    store-german
              Port:    8080
              Weight:  1
            Filters:
              Request Header Modifier:
                Add:
                  Name:   X-Client-Geo-Location
                  Value:  {client_region},{client_city}
              Type:       RequestHeaderModifier
            Matches:
              Path:
                Type:   PathPrefix
                Value:  /de
        Status:
          <...>
      

    סטטוס המסלול

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

    תנאים של HTTPRoute

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

    • Accepted=True מציין ש-HTTPRoute קשור בהצלחה ל-Gateway.
    • Accepted=False מציין ש-HTTPRoute נדחה מקישור ל-Gateway הזה.

    אם אין שערים שמופיעים מתחת לכותרת Gateway bindings, יכול להיות שתוויות ה-HTTPRoute ובוררי התוויות של השער לא תואמים. מצב כזה יכול לקרות אם אף שער לא בוחר את המסלול שלכם.

    אירועים של HTTPRoute

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

    • ADD אירועים מופעלים כשמוסיפים משאב.
    • אירועי UPDATE מופעלים כשמשאב מתעדכן.
    • אירועי SYNC מופעלים על ידי התאמה תקופתית.

    מיזוג נתיבים, קדימות ואימות

    קדימות של מסלולים

    ‫Gateway API מגדיר כללי קדימות מחמירים לגבי האופן שבו תנועה מותאמת לנתיבים עם כללי ניתוב חופפים. הקדימות בין שני נתיבי HTTP חופפים היא כדלקמן:

    1. מיזוג של שמות מארחים: ההתאמה הארוכה או הספציפית ביותר של שם המארח.
    2. מיזוג נתיבים: ההתאמה לנתיב הארוך או הספציפי ביותר.
    3. מיזוג כותרות: המספר הגדול ביותר של כותרות HTTP שתואמות.
    4. התנגשות: אם שלוש הכללים הקודמים לא קובעים סדר עדיפות, סדר העדיפות נקבע לפי משאב HTTPRoute עם חותמת הזמן הכי ישנה.

    מיזוג מסלולים

    ב-gke-l7 GatewayClasses, כל ה-HTTPRoutes של Gateway נתון ממוזגים לאותו משאב של מפת URL. אופן המיזוג של רכיבי HTTPRoutes תלוי בסוג החפיפה ביניהם. כדי להמחיש את מיזוג המסלולים ואת סדר העדיפויות, אפשר לפצל את HTTPRoute מהדוגמה הקודמת לשלושה HTTPRoute נפרדים:

    1. מיזוג של נתיבים: כל שלושת נתיבי ה-HTTP מצורפים לאותו internal-http Gateway, ולכן הם ממוזגים יחד.
    2. מיזוג של שמות מארחים: כל שלושת המסלולים תואמים ל-store.example.com, ולכן כללי שם המארח שלהם ממוזגים.
    3. מיזוג נתיבים: הנתיב store-german-route הוא ספציפי יותר /de, ולכן הוא לא עובר מיזוג נוסף. הנתיבים store-v1-route ו-store-v2-route תואמים שניהם לנתיב /* זהה, ולכן הם עוברים מיזוג בנתיב.
    4. מיזוג כותרות: ל-store-v2-route יש קבוצה ספציפית יותר של התאמות כותרות HTTP מאשר ל-store-v1-route, ולכן הן לא ממוזגות יותר.
    5. התנגשות: מכיוון שאפשר למזג את המסלולים לפי שם המארח, הנתיב והכותרות, אין התנגשויות וכל כללי הניתוב חלים על התנועה.

    ה-HTTPRoute היחיד שבו נעשה שימוש בדוגמה הקודמת שווה ערך לשלושת המסלולים הנפרדים האלה:

    kind: HTTPRoute
    apiVersion: gateway.networking.k8s.io/v1
    metadata:
      name: store-v1-route
    spec:
      parentRefs:
      - kind: Gateway
        name: internal-http
      hostnames:
      - "store.example.com"
      rules:
      - backendRefs:
        - kind: Service
          name: store-v1
          port: 8080
    ---
    kind: HTTPRoute
    apiVersion: gateway.networking.k8s.io/v1
    metadata:
      name: store-v2-route
    spec:
      parentRefs:
      - kind: Gateway
        name: internal-http
      hostnames:
      - "store.example.com"
      rules:
      - matches:
        - headers:
          - type: Exact
            name: env
            value: canary
        backendRefs:
        - kind: Service
          name: store-v2
          port: 8080
    ---
    kind: HTTPRoute
    apiVersion: gateway.networking.k8s.io/v1
    metadata:
      name: store-german-route
    spec:
      parentRefs:
      - kind: Gateway
        name: internal-http
      hostnames:
      - "store.example.com"
      rules:
      - matches:
        - path:
            type: PathPrefix
            value: /de
        backendRefs:
        - kind: Service
          name: store-german
          port: 8080
    

    שערי Kubernetes ושערי Istio

    שימו לב של-Kubernetes Gateway API ול-Istio API יש משאב בשם Gateway. הם מבצעים פונקציות דומות, אבל הם לא אותו מקור. אם אתם משתמשים ב-Istio וב-Gateway API באותו אשכול Kubernetes, השמות האלה חופפים כשמשתמשים ב-kubectl בשורת הפקודה. יכול להיות שהפונקציה kubectl get gateway תחזיר את משאבי Kubernetes Gateway ולא את משאבי Istio Gateway, או להיפך.

    $ kubectl api-resources
    NAME       SHORTNAMES   APIGROUP                       NAMESPACED   KIND
    gateways   gw           networking.istio.io/v1beta1    true         Gateway
    gateways   gtw          networking.k8s.io/v1beta1      true         Gateway
    

    אם אתם משתמשים ב-Istio ומשדרגים ל-GKE 1.20 ואילך, מומלץ להתחיל להשתמש בשם הקצר של משאב Gateway או לציין את קבוצת ה-API. השם הקצר של שער Kubernetes הוא gtw והשם הקצר של שער Istio הוא gw. הפקודות הבאות מחזירות את משאבי Kubernetes Gateway ו-Istio Gateway בהתאמה.

    # Kubernetes Gateway
    $ kubectl get gtw
    NAME                        CLASS
    multi-cluster-gateway       gke-l7-global-external-managed-mc
    
    $ kubectl get gateway.networking.x-k8s.io
    NAME                        CLASS
    multi-cluster-gateway       gke-l7-global-external-managed-mc
    
    # Istio Gateway
    $ kubectl get gw
    NAME               AGE
    bookinfo-gateway   64m
    
    $ kubectl get gateway.networking.istio.io
    NAME               AGE
    bookinfo-gateway   64m
    

    פתרון בעיות

    חסרה רשת משנה של שרת proxy בלבד באזור

    התסמין:

    יכול להיות שתיתקלו בבעיה הבאה כשתיצרו שער אזורי (פנימי או חיצוני):

    generic::invalid_argument: error ensuring load balancer: Insert: Invalid value for field 'resource.target': 'regions/[REGION_NAME]/targetHttpProxies/gkegw-x5vt-default-internal-http-[ID]'. A reserved managed proxy subnetwork with purpose REGIONAL_MANAGED_PROXY is required.
    

    הסיבה:

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

    פתרון עקיף:

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

    כבר קיימת רשת משנה מסוג Proxy-only באזור עם מטרה שגויה

    התסמין:

    יכולה להתרחש הבעיה הבאה כשיוצרים רשת משנה של שרת proxy בלבד עבור שער אזורי (פנימי או חיצוני):

    ERROR: (gcloud.compute.networks.subnets.create) Could not fetch resource:
     - The resource 'projects/[PROJECT_NAME]/regions/[REGION_NAME]/subnetworks/[PROXY_ONLY_SUBNET_NAME]' already exists
    

    הסיבה:

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

    פתרון עקיף:

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

    1. צריך לבדוק שרשת משנה מסוג proxy-only כבר קיימת באזור, ולוודא שהמטרה שלה נכונה:

      1. מציגים את רשימת רשתות המשנה כדי לראות איזו מהן היא רשת המשנה של שרת proxy בלבד באזור:

        gcloud compute networks subnets list --regions=COMPUTE_REGION
        

        מחליפים את COMPUTE_REGION באזור Compute Engine שבו רוצים ליצור את שער אזורי.

      2. מתארים את רשת המשנה של ה-proxy באזור כדי להבין מה המטרה שלה:

        gcloud compute networks subnets describe PROXY_ONLY_SUBNET \
            --region COMPUTE_REGION | grep -E 'name|purpose'
        

        מחליפים את PROXY_ONLY_SUBNET ברשת המשנה של ה-proxy בלבד.

      GKE Gateway תומך רק ברשתות משנה של REGIONAL_MANAGED_PROXY proxy-only עבור שערים אזוריים (פנימיים או אזוריים).

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

    אין מקור תקין

    התסמין:

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

    no healthy upstream
    

    הסיבה:

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

    פתרון עקיף:

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

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