פריסת משאבי Kubernetes Gateway כדי לנהל את האופן שבו תנועה חיצונית מגיעה לאפליקציות באשכול Google Kubernetes Engine (GKE) יחיד. הגדרת GKE Gateway מאפשרת שליטה גמישה ומשמעותית בתעבורת הנתונים הנכנסת (ingress), ומשפרת את יכולת ההתאמה לעומס (scalability) ואת האמינות של האפליקציות. לדוגמה, GKE Gateway מציע יכולות של ניתוב אופטימלי ושל התאמה אוטומטית לעומס. היכולות האלה חיוניות למילוי בקשות באופן מיידי עם זמן אחזור קצר, כדי להבטיח חוויית משתמש מהירה ולעזור לשלוט בעלויות.
כדי לפרוס שערים בכמה אשכולות או ב-fleet, קראו את המאמר פריסת שערים מרובי אשכולות. להגדרות ספציפיות של Gateway, כמו ניתוב בין מרחבי שמות ופיצול תנועת HTTP, אפשר לעיין במדריכים למשתמשים של Gateway API.
לפני שמתחילים
לפני שמתחילים, חשוב לוודא שביצעתם את המשימות הבאות:
- מפעילים את Google Kubernetes Engine API. הפעלת Google Kubernetes Engine API
- כדי להשתמש ב-Google Cloud CLI למשימה הזו, מתקינים ואז מאתחלים את ה-CLI של gcloud. אם כבר התקנתם את ה-CLI של gcloud, הריצו את הפקודה
gcloud components updateכדי לקבל את הגרסה העדכנית. יכול להיות שבגרסאות קודמות של ה-CLI של gcloud אי אפשר להריץ את הפקודות שבמסמך הזה.
מוודאים שיש לכם אשכול קיים במצב Autopilot או במצב Standard. כדי ליצור אשכול חדש, קראו את המאמר יצירת אשכול Autopilot.
כדי ליצור את מפות האישורים הנדרשות, ודאו שלחשבון המשתמש שלכם יש את התפקיד 'עריכת Certificate Manager' (
roles/certificatemanager.editor).
הדרישות של GKE Gateway controller
- אפשר להשתמש ב-Gateway API רק באשכולות מותאמים ל-VPC.
- אם אתם משתמשים ב-GatewayClasses אזוריים או חוצי-אזורים, אתם צריכים להפעיל רשת משנה לשרת proxy בלבד.
- התוסף
HttpLoadBalancingצריך להיות מופעל באשכול. - אם אתם משתמשים ב-Istio, אתם צריכים לשדרג את Istio לאחת מהגרסאות הבאות:
- 1.15.2 ואילך
- 1.14.5 ואילך
- 1.13.9 ואילך.
- אם משתמשים ב-VPC משותף, צריך להקצות בפרויקט המארח את התפקיד
Compute Network Userלחשבון השירות של GKE בפרויקט השירות.
הגבלות ומגבלות
כשמשתמשים ב-GKE Gateway, חשוב להבין את המגבלות וההגבלות הבאות:
היכולות של GKE GatewayClasses משתנות בהתאם למאזן העומסים שבו משתמשים. למידע נוסף על התכונות השונות שנתמכות בכל GatewayClass, קראו את המאמר יכולות של GatewayClass.
שיטה מומלצת: כדי להבטיח ביצועים אופטימליים, מומלץ להגביל את מספר השערים ל-100 לכל היותר. חריגה מהמגבלה הזו עלולה להשפיע על הביצועים או לגרום לעלייה בזמן האחזור.
GKE Gateway תומך רק בערוץ ההפצה הרגיל של Gateway API.
GKE Gateway תמיד מופעל באשכולות Autopilot. אי אפשר להתקין CRD של ערוץ ההפצה הניסיוני של Gateway API באשכולות Autopilot.
אי אפשר להשתמש ב-FrontendConfig או ב-BackendConfig כדי להגדיר שער. צריך להשתמש ב-Policy.
GKE Gateway פועל באופן שונה מ-Ingress, כי Gateway לא מסיק פרמטרים של בדיקת תקינות. אם השירות לא מחזיר את הערך 200 לבקשות ל-
GET /, או אם יש לכם בדיקות מוכנות אחרות של pod, אתם צריכים להגדיר HealthCheckPolicy לשירות.אי אפשר לציין מספר יציאה ישירות בשם המארח (לדוגמה, web.example.com:80) לניתוב תנועה.
אתם יכולים לראות את משאבי מאזן העומסים ש-GKE יוצר לשערים במסוף Google Cloud , אבל המשאבים האלה לא מפנים לשער או לאשכול GKE שאליהם הם מחוברים.
אי אפשר ליצור באופן אוטומטי אישור SSL בניהול Google באמצעות שערים, אבל אפשר ליצור באופן ידני אישור SSL בניהול Google ולהפנות אליו. מידע נוסף זמין במאמר אבטחת שער.
HTTPRoute הוא סוג הנתיב היחיד שנתמך. אין תמיכה ב-TCPRoutes, ב-UDPRoutes וב-TLSRoutes. רשימה של השדות שנתמכים ב-GKE Gateway Controller מופיעה במאמר היכולות של GatewayClass.
כותרות מותאמות אישית של בקשות ותגובות עם Gateway או הפניות אוטומטיות של נתיבים ושכתובים של כתובות URL עם Gateway זמינים רק ב-GKE מגרסה 1.27 ואילך.
בכותרות מותאמות אישית של בקשות ותגובות עם הפניות אוטומטיות של Gateway ונתיבים, ובשכתובים של כתובות URL עם Gateway, אין תמיכה ב-GatewayClass
gke-l7-gxlb.כשמגדירים כותרות של בקשות בהתאמה אישית ב-HTTPRoute, אי אפשר להשתמש Google Cloud במשתנה
origin_request_header. כדי להגדיר CORS, אפשר להשתמש בסוג המסנןCORS.המגבלות שלGoogle Cloud מאזן העומסים הקלאסי של אפליקציות (ALB) חלות על GKE Gateway. בנוסף, אי אפשר להגדיר כותרת תגובה מותאמת אישית של מארח בשירות לקצה העורפי.
הפניות אוטומטיות של נתיבים ושכתובים של כתובות URL הם בלעדיים זה לזה, אי אפשר להשתמש בשני המסננים בו-זמנית באותם כללים.
ב-Cloud Load Balancing אין תמיכה בהפניית תנועה ליציאה אחרת. כדי לראות את רשימת השדות שנתמכים ב-GKE Gateway controller, קראו את המאמר היכולות של GatewayClass.
GKE Gateway לא תומך בתווים כלליים לחיפוש ובכתובות URL דינמיות. ביטויים רגולריים לא נתמכים ב-GatewayClasses
gke-l7-gxlbו-gke-l7-gxlb-mc. מידע נוסף זמין במאמר הגדרת התאמה לביטויים רגולריים.אם מציינים שער עם מחלקת שער חיצונית אזורית, הבקר מקצה כתובת IP פנימית במקום הכתובת החיצונית. כדי ללמוד איך להשתמש בכתובת עם שם במאזן עומסים חיצוני אזורי של אפליקציות (ALB), ראו פריסת שער חיצוני אזורי.
השער משתמש בקבוצות עצמאיות של נקודות קצה ברשת כדי להקצות קבוצות של נקודות קצה ברשת. כדי לוודא שבקר ה-Gateway מתאים בצורה נכונה את הגדרת מאזן העומסים, אי אפשר לשנות את ההערה
cloud.google.com/negשל שירות שהוא חלק מה-Gateway.GKE Gateway לא תומך בהפניה לשירות שגם GKE Ingress מפנה אליו.
כששער מוגדר להקצות כתובת IP, אי אפשר לשנות את ה-
Gateway.spec.gatewayClass. כדי לוודא שבקר השער מתאים בצורה נכונה את מאזן העומסים, צריך למחוק את השער הקיים ולפרוס מחדש את המניפסט עם הערך המעודכן שלgatewayClass.אין תמיכה בהערה
networking.gke.io/app-protocols. כדי להשיג את אותה תוצאה, צריך להשתמש בשדהappProtocol.אם אתם משתמשים ב-GKE Gateway עם
external-dnsומצב התקינות של ה-Gateway לא תקין, כברירת מחדל כל רשומות ה-DNS שמשויכות ל-Gateway נמחקות מתחומי ה-DNS שלכם.שיטה מומלצת: כשמריצים את
external-dns, מגדירים את הדגלpolicy=upsert-only. ההגדרה הזו עוזרת למנוע מחיקה של רשומות DNS קיימות.אם מסירים יציאה משירות ש-GKE Gateway מפנה אליו דרך נתיב, צריך גם לעדכן את ההערה של ה-NEG העצמאי בשירות כדי להסיר את היציאה הזו. אם לא תעשו את זה, בסופו של דבר בקר ה-NEG יפסיק לסנכרן את נקודות הקצה של Pod בשביל השירות הזה. לפרטים, ראו בקר NEG מפסיק לנהל נקודות קצה כשמסירים יציאה מהשירות.
פריסות שמשתמשות בשערים מרובי אשכולות (MCG) עם אשכולות אזוריים עלולות לגרום לשיבושים בשירות במהלך שדרוגי אשכולות. הבעיה הזו מתרחשת כי מנגנון גילוי מדור קודם של קבוצת נקודות קצה ברשת (NEG) עלול לדווח באופן שגוי על אפס שירותים לקצה העורפי כשמישור הבקרה של האשכול האזורי לא זמין באופן זמני. אנחנו עובדים על פתרון לטווח ארוך. כדי למנוע את נקודת הכשל הבודדת הזו, השתמשו באשכולות GKE אזוריים עם MCG.
הפעלת Gateway API באשכול
כדי להשתמש במשאבי Gateway ב-GKE, צריך להפעיל את Gateway API באשכול.
לפני שמעדכנים אשכול GKE קיים כדי להפעיל את Gateway API, צריך לוודא שהוא עומד בדרישות המינימליות.
כדי להפעיל את Gateway API באשכול GKE קיים (Autopilot או Standard), משתמשים בפקודה הבאה. הפעולה הזו יכולה להימשך עד 45 דקות, עד שהאשכול יתאים ויתקין את CustomResourceDefinition.
gcloud container clusters update CLUSTER_NAME \
--location=CLUSTER_LOCATION\
--gateway-api=standard
מחליפים את מה שכתוב בשדות הבאים:
CLUSTER_NAME: השם של האשכול הקיים.
CLUSTER_LOCATION: האזור או התחום של Compute Engine שבהם נמצא האשכול.
הדגל --gateway-api=standard מורה ל-GKE להתקין את ה-CRD של Gateway API Standard Channel עם האשכול.
אימות האשכול
אחרי שיוצרים או משדרגים את האשכול, GKE Gateway controller מתקין באופן אוטומטי את GatewayClasses. יכול להיות שיעברו כמה דקות עד שהבקר יזהה את ה-CRD ויתקין את ה-GatewayClasses.
מוודאים ש-Gateway API מופעל במישור הבקרה של GKE:
gcloud container clusters describe CLUSTER_NAME \ --location=CLUSTER_LOCATION \ --format jsonהפלט אמור להיראות כך: אם הפלט הזה ריק, מריצים מחדש את פקודת עדכון האשכול.
"networkConfig": { ... "gatewayApiConfig": { "channel": "CHANNEL_STANDARD" }, ... },מוודאים שה-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) פנימי, צריך להגדיר רשת משנה של שרת proxy בלבד. בכל אזור של VPC שבו אתם משתמשים במאזני עומסים פנימיים של אפליקציות (ALB), חייבת להיות רשת משנה של שרתי proxy בלבד. רשת המשנה הזו מספקת כתובות IP פנימיות לשרתי ה-Proxy של מאזן העומסים.
יוצרים רשת משנה מסוג proxy-only:
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.
-
מאמתים את רשת המשנה לשרת 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 רוצה ליצור שער שצוותים שונים יוכלו להשתמש בו כדי לחשוף את האפליקציות שלהם באופן פנימי. האדמין פורס את ה-Gateway, וצוותי האפליקציות פורסים את ה-Routes שלהם באופן עצמאי ומצרפים אותם ל-Gateway הזה.
שומרים את המניפסט הבא של Gateway בקובץ בשם
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: מציין שהשער חושף רק את יציאה 80 להאזנה לתנועת HTTP.
השער הזה מוגדר לטפל בתנועת HTTP רק ביציאה 80. הוא לא תומך ב-HTTPS (יציאה 443) כברירת מחדל, ואם תנסו להתחבר באמצעות HTTPS, יכול להיות שהבקשה תיכשל.
-
פורסים את השער באשכול:
kubectl apply -f gateway.yamlמוודאים שהשער נפרס בצורה תקינה. יכול להיות שיעברו כמה דקות עד שכל המשאבים ייפרסו.
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מציין שהשער מוכן.בשלב הזה, באשכול שלכם פרוס שער שהוקצו לו מאזן עומסים וכתובת IP. אבל לשער אין נתיבים, ולכן הוא לא יודע איך לשלוח תנועה לקצוות העורפיים. בלי נתיבים, כל התנועה עוברת לקצה עורפי שמוגדר כברירת מחדל, שמחזיר שגיאת HTTP 404. בשלב הבא פורסים אפליקציה ונתיבים, שמציינים לשער איך להגיע לקצוות העורפיים של האפליקציה.
פריסת אפליקציות ההדגמה
צוותי האפליקציות יכולים לפרוס את האפליקציות והנתיבים שלהם בנפרד מהפריסה של השערים. במקרים מסוימים, יכול להיות שצוות האפליקציה ירצה להיות הבעלים של השער ולפרוס אותו בעצמו כמשאב שמוקדש לאפליקציות שלו. במאמר קישור נתיבים מוסבר על מודלים שונים של בעלות על שערים ונתיבים. בדוגמה הזו, צוות החנות פורס את האפליקציה שלו ואת ה-HTTPRoute הנלווה כדי לחשוף את האפליקציה דרך שער ה-internal-http שנוצר בקטע הקודם.
למשאב HTTPRoute יש הרבה שדות שאפשר להגדיר להתאמת תנועה. הסבר על השדות של HTTPRoute מופיע במפרט ה-API.
פורסים את אפליקציית החנות (פריסות 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.
מוודאים שהאפליקציה נפרסה בהצלחה:
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מוודאים שהשירותים נפרסו:
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
משאבי Route מגדירים כללים ספציפיים לפרוטוקול למיפוי תנועה מ-Gateway לקצוות עורפיים של Kubernetes. המשאב HTTPRoute מבצע התאמה וסינון של תעבורת נתונים ב-HTTP וב-HTTPS, ונתמך על ידי כל ה-GatewayClasses של gke-l7.
בקטע הזה תפרסו HTTPRoute, שמתכנת את השער עם כללי הניתוב שנדרשים כדי להגיע לאפליקציית החנות.
שומרים את המניפסט הבא של 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פורסים את HTTProute באשכול:
kubectl apply -f store-route.yamlה-HTTPRoute של
storeמקושר לשערinternal-httpבאמצעות המאפייןparentRefs. כללי הניתוב האלה מוגדרים במאזן העומסים הבסיסי, כמו בתרשים הבא:כללי הניתוב האלה מעבדים את תנועת ה-HTTP באופן הבא:
- התנועה אל
store.example.com/deמגיעה לשירותstore-german. - תנועה אל
store.example.comעם כותרת ה-HTTP"env: canary"מועברת לשירותstore-v2. - שאר התנועה אל
store.example.comמועברת לשירותstore-v1.
- התנועה אל
מוודאים שה-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.מוודאים שה-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 בנפרד.
מאחזרים את כתובת ה-IP מהשער כדי שתוכלו לשלוח תנועה לאפליקציה:
kubectl get gateways.gateway.networking.k8s.io internal-http -o=jsonpath="{.status.addresses[0].value}"הפלט הוא כתובת IP.
שולחים תנועה לכתובת ה-IP הזו ממכונה וירטואלית (VM) שמחוברת לאשכול. הפעולה הזו נדרשת כי לשער יש כתובת IP פנימית, ואפשר לגשת אליו רק מתוך רשת ה-VPC.
internal-httpהוא מאזן עומסים אזורי, ולכן ה-VM של הלקוח צריך להיות באותו אזור של אשכול GKE.יוצרים מכונה וירטואלית לבדיקה באותו אזור ורשת VPC:
gcloud compute instances create test-vm \ --zone=COMPUTE_ZONE \ --network=VPC_NETWORK_NAMEמתחברים למכונה הווירטואלית באמצעות SSH:
gcloud compute ssh test-vm --zone=COMPUTE_ZONEבמעטפת של ה-VM, שולחים בקשה אל
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" }כדי לבדוק את ההתאמה של הנתיב, עוברים לגרסה הגרמנית של שירות החנות בכתובת
store.example.com/de:curl http://store.example.com/de --resolve store.example.com:80:GATEWAY_IP_ADDRESS -vהפלט מאשר שהבקשה טופלה על ידי Pod של
store-german:{ "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" }לבסוף, משתמשים בכותרת ה-HTTP
env: canaryכדי לשלוח תנועה לגרסת ה-canary של שירות החנות:curl -H "env: canary" http://store.example.com --resolve store.example.com:80:GATEWAY_IP_ADDRESS -vהפלט מאשר שהבקשה טופלה על ידי Pod של
store-v2:{ "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 אזורית בתור ממשק ה-frontend של השער. ההתנהגות של השער הזה תלויה במסלול שירות הרשת שבחרתם:
- אם בוחרים במסלול הרגיל של שירות הרשת (ברירת המחדל), כתובת ה-IP האזורית מפורסמת רק באזור המקומי של Google Cloud שבו נפרס שער ה-NAT החיצוני האזורי. לקוחות ששולחים תעבורת נתונים לכתובת ה-IP הזו מנותבים על ידי ספק האינטרנט המקומי שלהם ודרך האינטרנט הציבורי, לפני שהם מגיעים לאזור Google שבו כתובת ה-IP מפורסמת.
- אם בוחרים במסלול הפרימיום של שירות הרשת, כתובת ה-IP האזורית מפורסמת ברשת הגלובלית של Google. כלומר, תעבורת הנתונים של הלקוח נכנסת לשדרה המרכזית הגלובלית והאיכותית של Google בנקודת קישור בין רשתות שכנות (peering) בקצה הרשת של Google, שהכי קרובה ללקוח, גם אם היעד הוא כתובת IP אזורית. המיקום הזה מקצר משמעותית את זמן האחזור ומשפר את הביצועים, כי הוא מצמצם את המרחק שהתנועה עוברת באינטרנט הציבורי.
- Global external Gateway: השער הזה משתמש בכתובת IP גלובלית (או בכתובת IP מסוג Anycast) בתור ממשק הקצה של השער. כתובת ה-IP הזו מפורסמת בכל האזורים של Google Cloud Compute. לקוחות ששולחים תנועה לכתובת ה-IP הזו מסוג Anycast מנותבים למיקום הקרוב ביותר של Google שבו כתובת ה-IP מפורסמת. השער החיצוני הגלובלי זמין רק במסלול הפרימיום של שירות הרשת.
פריסת שער אזורי חיצוני
בדוגמה הבאה מוסבר איך לחשוף אפליקציה של חנות עם כמה אישורים שמצורפים לשער החיצוני האזורי, באמצעות אישורים בניהול עצמי ו-HTTPRoute.
יצירת רשת משנה של שרת proxy לשער האזורי
לפני שיוצרים שער שמשתמש במאזן עומסים חיצוני אזורי של אפליקציות (ALB), צריך להגדיר רשת משנה לשרת proxy בלבד. בכל אזור של VPC שבו משתמשים במאזן עומסים חיצוני אזורי של אפליקציות (ALB), צריך להיות רשת משנה של external_managed_proxy. רשת המשנה הזו מספקת כתובות IP פנימיות לשרתי ה-proxy של מאזן העומסים.
יצירת אישור לאבטחת תנועת הלקוחות
אתם יכולים להשתמש באישור שהונפק ואומת על ידי רשות האישורים (CA) שלכם, או ליצור אישור עם חתימה עצמית. למידע נוסף על יצירת אישור, ראו אחסון אישור ב-Kubernetes Secret.
כדי לאבטח את התנועה בין הלקוחות לבין השער האזורי, אפשר להשתמש בשיטות הבאות:
- אישורים ב-Certificate Manager שמנוהלים על ידי Google או בניהול עצמי
- אישורי SSL אזוריים בניהול עצמי
- סודות של Kubernetes
אישורי SSL בניהול Google או CertificateMap לא נתמכים בשערים אזוריים.
מידע נוסף זמין במאמר אישורים ומאזני עומסים ב- Google Cloud .
יצירת שער HTTP(S) חיצוני אזורי
יוצרים כתובת IP סטטית אזורית למאזן העומסים החיצוני.
gcloud compute addresses create IP_ADDRESS_NAME \ --region=COMPUTE_REGION \ --network-tier=STANDARDמחליפים את מה שכתוב בשדות הבאים:
-
IP_ADDRESS_NAME: השם של כתובת ה-IP הסטטית החדשה. -
COMPUTE_REGION: האזור ב-Compute Engine שבו פועל האשכול.
-
כדי ליצור שער של מאזן עומסים חיצוני אזורי של אפליקציות (ALB) באמצעות אישור בניהול עצמי, פועלים לפי השלבים הבאים ושומרים את המניפסט בתור
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מחילים את המניפסט
regional-gateway:kubectl apply -f regional-gateway.yamlצריך לאמת את ההגדרות.
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 הנלווה כדי לחשוף את האפליקציה דרך השער external-http שנוצר בקטע הקודם.
מידע נוסף על שדות HTTPRoute זמין במפרט ה-API.
פורסים את האפליקציה לדוגמה באשכול:
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.מוודאים שהאפליקציה נפרסה בהצלחה:
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מוודאים שהשירותים נפרסו בהצלחה:
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
משאבי Route מגדירים כללים ספציפיים לפרוטוקול למיפוי תנועה מ-Gateway לקצוות עורפיים של Kubernetes. המשאב HTTPRoute מבצע התאמה וסינון של תנועת HTTP ו-HTTPS, ונתמך על ידי כל ה-GatewayClasses של gke-l7-*.
בקטע הזה תפרסו HTTPRoute, שמגדיר את השער עם כללי הניתוב שנדרשים כדי להגיע לאפליקציה לדוגמה.
שומרים את המניפסט הבא בקובץ בשם
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-http.מחילים את המניפסט על האשכול:
kubectl apply -f store-route-external.yamlה-HTTPRoute
storeמקושר לשערexternal-httpבאמצעות המאפייןparentRefs. בתרשים הבא מוצגים כללי הניתוב שהוגדרו במאזן העומסים הבסיסי:כללי הניתוב מעבדים את תנועת ה-HTTP באופן הבא:
- תנועה אל
store.example.com/deמנותבת לשירותstore-german. - תנועה אל
store.example.comעם כותרת ה-HTTP"env: canary"מנותבת לשירותstore-v2. - שאר התנועה אל
store.example.comמנותבת לשירותstore-v1.
- תנועה אל
מוודאים שה-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", ...מוודאים שה-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.
שליחת תנועה לאפליקציה
אחרי שפרסתם את השער, המסלול והאפליקציה באשכול, אתם יכולים להעביר תנועה לאפליקציה.
מאתרים את כתובת ה-IP של השער:
kubectl get gateways.gateway.networking.k8s.io external-http -o=jsonpath="{.status.addresses[0].value}"הפלט הוא כתובת IP.
יוצרים מכונה וירטואלית:
gcloud cloud-shell sshשולחים תנועה לכתובת ה-IP של השער מה-VM. צריך להגדיר את כותרת המארח באופן ידני כי שם המארח
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" }כדי לבדוק את ההתאמה של הנתיב, נכנסים לגרסה הגרמנית של שירות
storeבכתובתstore.example.com/de:curl https://store.example.com/de --resolve store.example.com:443:GATEWAY_IP_ADDRESS --cacert cacert.pem -vהפלט מאשר שהבקשה טופלה על ידי Pod של
store-german:{ "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" }שולחים תנועה לגרסת ה-canary של השירות
storeבאמצעות כותרת ה-HTTPenv: canary:curl -H "env: canary" https://store.example.com --resolve store.example.com:443:GATEWAY_IP_ADDRESS --cacert cacert.pem -vהפלט מאשר שהבקשה טופלה על ידי Pod של
store-v2:{ "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" }
פריסת שער חיצוני גלובלי
בדוגמה הבאה מוסבר איך לחשוף אפליקציה של מאגר עם כמה אישורים שמצורפים לשער הגלובלי החיצוני ומקובצים במפת אישורים באמצעות Certificate Manager ו-HTTPRoute.
יצירת מפת אישורים
Google ממליצה להשתמש בCertificate Manager כדי לנהל אישורים כשצריך 15 אישורים או יותר לכל שער, או כשצריך להשתמש בתעודות wildcard.
אתם יכולים גם לאבטח את ה-Gateway החיצוני באמצעות סודות של Kubernetes או אישורי SSL בניהול Google. מידע נוסף זמין במאמר אבטחת שער.
בקטע הזה יוצרים אישורים באמצעות Certificate Manager כדי לאבטח את האפליקציות שפועלות באשכול.
מפעילים את Certificate Manager API:
gcloud services enable certificatemanager.googleapis.comיוצרים מפת אישורים:
gcloud beta certificate-manager maps create store-example-com-mapטוענים את האישור והמפתחות שמנוהלים על ידי 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: השם של קובץ המפתח הפרטי.
מידע נוסף זמין במאמר יצירת מפתח פרטי ואישור.
-
יוצרים
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.
שומרים את המניפסט הבא בקובץ בשם
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.-
מחילים את המניפסט על האשכול:
kubectl apply -f gateway.yamlיכול להיות שיעברו כמה דקות עד ש-GKE יפרוס את המשאבים.
מוודאים שהשער נפרס בהצלחה:
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. בקטע הבא תפרסו את Routes, שמנחה את השער לשלוח תנועה לקצוות עורפיים.
פריסת אפליקציית ההדגמה
אתם יכולים לפרוס את האפליקציות והנתיבים שלכם בנפרד מהפריסה של השערים.
למידע נוסף על פריסת אפליקציות ההדגמה, ראו פריסת אפליקציות ההדגמה.
יצירת HTTPRoute
כדי להתאים ולסנן תנועה ב-HTTP וב-HTTPS, צריך ליצור HTTPRoute.
שליחת תנועה לאפליקציה
אחרי שפורסים את האפליקציה ויוצרים HTTPRoutes, אפשר להעביר תנועה לאפליקציה.
למידע נוסף על שליחת תנועה לאפליקציה, ראו שליחת תנועה לאפליקציה.
פריסת שער אזורי חיצוני
בדוגמה הבאה מוסבר איך לחשוף אפליקציה של חנות עם כמה אישורים שמצורפים לשער החיצוני האזורי, באמצעות אישורים בניהול עצמי ו-HTTPRoute.
יצירת רשת משנה של שרת proxy לשער האזורי
לפני שיוצרים שער שמשתמש במאזן עומסים אזורי חיצוני של אפליקציות (ALB), צריך להגדיר רשת משנה של שרתי proxy בלבד. בכל אזור של VPC שבו משתמשים במאזן עומסים חיצוני אזורי של אפליקציות (ALB), צריכה להיות תת-רשת external_managed_proxy. רשת המשנה הזו מספקת כתובות IP פנימיות לשרתי ה-proxy של מאזן העומסים.
יצירת אישור לאבטחת תנועת הלקוחות
אתם יכולים להשתמש באישור שהונפק ואומת על ידי רשות האישורים (CA) שלכם, או ליצור אישור עם חתימה עצמית. למידע נוסף על יצירת אישור, ראו אחסון אישור ב-Kubernetes Secret.
כדי לאבטח את התנועה בין הלקוחות לבין השער האזורי, אפשר להשתמש בשיטות הבאות:
- אישורים ב-Certificate Manager שמנוהלים על ידי Google או בניהול עצמי
- אישורי SSL אזוריים בניהול עצמי
- סודות של Kubernetes
אישורי CertificateMap או אישורי SSL בניהול Google לא נתמכים בשערים אזוריים.
מידע נוסף זמין במאמר אישורים ומאזני עומסים ב- Google Cloud .
יצירת שער HTTP(S) חיצוני אזורי
יוצרים כתובת IP סטטית אזורית למאזן העומסים החיצוני.
gcloud compute addresses create IP_ADDRESS_NAME \ --region=COMPUTE_REGION \ --network-tier=STANDARDמחליפים את מה שכתוב בשדות הבאים:
-
IP_ADDRESS_NAME: השם של כתובת ה-IP הסטטית החדשה. -
COMPUTE_REGION: האזור ב-Compute Engine שבו פועל האשכול.
-
כדי ליצור שער של מאזן עומסים חיצוני אזורי של אפליקציות (ALB) באמצעות אישור בניהול עצמי, פועלים לפי השלבים הבאים ושומרים את המניפסט בתור
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מחילים את המניפסט
regional-gateway:kubectl apply -f regional-gateway.yamlצריך לאמת את ההגדרות.
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 כדי להתאים את התנועה מהשער לשירותים האלה.
פורסים את האפליקציה לדוגמה:
kubectl apply -f https://raw.githubusercontent.com/GoogleCloudPlatform/gke-networking-recipes/main/gateway/gke-gateway-controller/app/site.yamlשומרים את המניפסט הבא בקובץ בשם
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.מחילים את המניפסט על האשכול:
kubectl apply -f site-route-internal.yamlמוודאים שה-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 נקשר בהצלחה לשער. למידע נוסף על השדה Status, קראו את המאמר סטטוס המסלול.מוודאים שהתנועה לשער מנותבת בצורה נכונה:
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.
הגדרת מסלול הרשת
כדי לציין את מסלול הרשת של כתובת המאזין של מאזן עומסים חיצוני אזורי של אפליקציות (ALB), משתמשים בשדה type במערך addresses[] שבהגדרת השער. אם לא מציינים מסלול רשת, כברירת מחדל מוגדרת לשער כתובת IP זמנית במסלול הרגיל.
משתמשים בערכים הבאים בשדה type:
-
networking.gke.io/premium-ephemeral-ipv4-address: מקצה כתובת IP של מסלול פרימיום. -
networking.gke.io/standard-ephemeral-ipv4-address: מקצה כתובת IP במסלול הרגיל.
כדי להקצות כתובות IP משני מסלולי הרשת, צריך לציין את שני הסוגים בשדה addresses.
בדוגמה הבאה מוסבר איך מקצים כתובת IP במסלול פרימיום לשער. Google Cloud כדי להקצות כתובת IP במסלול הרגיל, משתמשים ב-networking.gke.io/standard-ephemeral-ipv4-address.
שומרים את המניפסט לדוגמה הבא בתור
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מחילים את המניפסט לדוגמה:
kubectl apply -f external-regional-http.yaml
הגדרת הקצה העורפי שמוגדר כברירת מחדל של השער
כל ה-GatewayClasses של gke-l7-* מחזירים HTTP 404 לתנועה שלא תואמת. אפשר להגדיר את ברירת המחדל של הקצה העורפי באמצעות נתיב ברירת מחדל מפורש, ששולח תנועה לא תואמת לשירות שסופק על ידי המשתמש.
שערי הגישה מוגדרים לטפל בקודי שגיאה כמו 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 הזה תואם לכל התנועה משער מסוים. אפשר להגדיר רק כלל אחד כזה לכל שער, אחרת הכללים מתנגשים וסדר הקדימויות חל.
אתם יכולים להשתמש בקצה עורפי שמוגדר כברירת מחדל כדי למנוע ממישהו ליצור קצה עורפי של ניתוב ברירת מחדל שמנתב את כל התנועה של Gateway. ל-HTTPRoute מפורש תמיד יש עדיפות על פני HTTPRoute חדשים עם כללי ניתוב סותרים.
הגדרת כתובת IP סטטית לשער
לכל שער יש כתובת IP שמשמשת אותו להאזנה לתנועה. אם לא מציינים כתובת IP בשער, בקר השער מספק כתובת IP באופן אוטומטי. אפשר גם ליצור כתובת IP סטטית, כדי שכתובת ה-IP תהיה קיימת בלי קשר למחזור החיים של השער.
אחרי שפורסים שער, כתובת ה-IP שלו מופיעה בשדה הסטטוס:
kind: Gateway
...
status:
addresses:
- value: 10.15.32.3
בהתאם ל-GatewayClass, כתובת ה-IP מוקצית מרשתות המשנה הבאות:
| GatewayClasses | מאגר ברירת המחדל של כתובות ה-IP |
|---|---|
|
|
כתובות IP פרטיות אזוריות מטווח כתובות ה-IPv4/IPv6 של הצומת הראשי |
|
|
כתובות IP ציבוריות אזוריות מטווחי IPv4/IPv6 החיצוניים האזוריים של Google |
|
|
כתובות IP ציבוריות גלובליות מטווחי IPv4/IPv6 החיצוניים הגלובליים של Google |
בשדה addresses.NamedAddress אפשר לציין כתובת IP בלי קשר לשער. אפשר ליצור משאב של כתובת IP סטטית לפני פריסת השער, והמשאב יופנה על ידי NamedAddress. אתם יכולים להשתמש שוב בכתובת ה-IP הסטטית גם אם מחקתם את השער.
שימוש בכתובת IP עם שם
אפשר להגדיר כתובת IPv4 או IPv6 על ידי ציון NamedAddress. צריך להקצות כתובת IP סטטית לפני שיוצרים שער.
יוצרים משאב של כתובת 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. הדגל הזה לא נדרש לשערי API גלובליים וחיצוניים. -
PROJECT_ID: הפרויקט שבו פועל אשכול GKE.
-
שומרים את המניפסט הבא בקובץ בשם
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 שצוינה.
מחילים את המניפסט על האשכול:
kubectl apply -f named-ip-gateway.yamlאימות כתובת ה-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. מאזן עומסים חיצוני של אפליקציות (ALB) מפנה בקשות 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 ממרחב שמות של תשתית
במקרים מסוימים, אין הבחנה ברורה בין צוות האדמינים של התשתית או הפלטפורמה לבין צוותי האפליקציות, וקשה למנוע שימוש לרעה ב-Gateway.
בדוגמה הבאה מוצגת הגבלה נוספת על השימוש במאזין ה-HTTP, כדי למנוע שימוש לא מכוון בפרוטוקול לא מאובטח מצד צוותי האפליקציה. בדוגמה הזו, השער מוגדר כך ש-HTTPRoute יוכל להשתמש במאזין ה-HTTP רק אם המסלול נמצא במרחב שמות עם התווית otherInfra: httpToHttps. עם זאת, השער מאפשר ל-HTTPRoutes בכל מרחב שמות להשתמש במאזין ה-HTTPS. אתם יכולים להגביל את מרחב השמות http-redirect באמצעות Kubernetes RBAC, כדי שצוותי האפליקציות לא יוכלו ליצור HTTPRoute במרחב השמות הזה בטעות.
יוצרים את מרחב השמות של השער. שומרים את המניפסט בשם
gateway-namespace.yaml:apiVersion: v1 kind: Namespace metadata: name: gateway-infraמחילים את המניפסט:
kubectl apply -f gateway-namespace.yamlיוצרים את מרחב השמות של השער ושומרים את המניפסט בתור
redirect-namespace.yaml:apiVersion: v1 kind: Namespace metadata: name: http-redirect labels: otherInfra: httpToHttpsלמרחב השמות
http-redirectיש את התוויתotherInfra: httpToHttps.מחילים את המניפסט:
kubectl apply -f redirect-namespace.yamlכדי להגביל את השימוש במאזין ה-HTTP, יוצרים שער באמצעות המניפסט הבא. שומרים את המניפסט בתור
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.
מחילים את המניפסט:
kubectl apply -f external-gateway.yamlכדי לאלץ את ההפניה האוטומטית ל-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מורה לשער להתאים רק למאזין ה-HTTP. המסנןRequestRedirectמאלץ את ההפניה ל-https listener.
- השדה
מחילים את המניפסט:
kubectl apply -f http-redirect.yamlיוצרים שירות לאפליקציה באמצעות המניפסט הבא. שומרים את המניפסט בתור
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"מחילים את המניפסט:
kubectl apply -f service-deployment.yamlיוצרים 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מחילים את המניפסט:
kubectl apply -f http-route.yaml
הגדרת הפניות אוטומטיות של נתיבים ושכתובים של כתובות URL
הפניות אוטומטיות של נתיבים כוללות הפניה אוטומטית של בקשה נכנסת מנתיב אחד של כתובת URL לנתיב אחר. הפניות לכתובות URL מאפשרות לשנות את המבנה של כתובת ה-URL כשצריך לטפל בכתובות URL מיושנות או שהוצאו משימוש.
שכתוב כתובות URL עוזר לשנות את כתובת ה-URL הנכנסת לפני העיבוד שלה בשרת. הוא מאפשר לשנות את המבנה או הפורמט של כתובת ה-URL בלי לשנות את התוכן או את מבנה הקובץ. כתיבה מחדש של כתובות URL עוזרת ליצור כתובות URL ידידותיות למשתמש ול-SEO, שקל לזכור ולהבין. כברירת מחדל, הפניות אוטומטיות של נתיבים ושכתובים של כתובות URL לא מוגדרים, וצריך להגדיר אותם באופן מפורש באמצעות מסנן ב-HTTPRoute.
GKE Gateway תומך בהפניות אוטומטיות של נתיבים ובשכתובים של כתובות URL. מידע נוסף זמין במאמר הפניות אוטומטיות ושכתובים של נתיבי HTTP.
הגדרת הפניות אוטומטיות של נתיבים
אפשר להגדיר הפניות אוטומטיות של נתיבים כך שיחליפו את כל הנתיב או רק את הקידומת בכתובת ה-URL.
החלפת כל הנתיב
כדי להחליף נתיב שלם, מגדירים מסנן ב-HTTPRoute שמחליף כל כתובת URL שמכילה את הקידומת
/any-pathבנתיב כתובת ה-URL בערך המחמיר/new-path.יוצרים מניפסט של 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/(מחמיר).מחילים את המניפסט:
kubectl apply -f store.yaml
כלל מסלול זה פועל לפי כלל הפניה אוטומטית מחמיר, כלומר הדפדפן לא מנסה לשמור במטמון את ההפניה האוטומטית, אלא מפנה אוטומטית לגרסה העדכנית.
החלפת קידומת בלבד
כדי להחליף רק קידומת, מגדירים מסנן ב-HTTPRoute שמחליף כל כתובת URL שמכילה את הקידומת
/any-prefixבנתיב כתובת ה-URL בערך המדויק/new-prefix.יוצרים מניפסט של 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/...(בלבד).מחילים את המניפסט:
kubectl apply -f store.yaml
כלל הניתוב הזה פועל לפי כלל ההפניה האוטומטית היחיד, שעוזר לוודא שהדפדפן תמיד מפנה אתכם לאותו דף.
הגדרת שכתובים של כתובות URL
אפשר להגדיר שכתובות URL ייכתבו מחדש כדי לשנות את האופן שבו הן מוצגות למשתמשים. אתם יכולים להשתמש בשכתוב כתובות URL כדי להפוך את כתובות ה-URL לידידותיות יותר למשתמש, לשפר את ה-SEO או להפנות את המשתמשים לדף חדש.
שכתוב של כל שם המארח
כדי לשכתב את כל שם המארח:
מגדירים מסנן ב-HTTPRoute שמורה לשער להחליף את המידע של
Hostבכותרת הבקשה מ-www.example.comל-store.example.comלפני העברת הבקשה לשירות לקצה העורפי.יוצרים מניפסט של 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.מחילים את המניפסט:
kubectl apply -f www.yaml
שכתוב באמצעות משני נתיבים
אפשר לשלב שכתובים עם משתני נתיב כדי לספק שינויים מתקדמים בכתובת ה-URL ובנתיב לפני העברת הבקשה לשירות לקצה העורפי.
כדי לשכתב באמצעות משתני נתיב:
מגדירים מסנן ב-HTTPRoute שמורה לשער להחליף את המידע של Host בכותרת הבקשה מ-www.example.com
to store.example.com, ולהחליף את הערך/storeב-/לפני העברת הבקשה לשירות לקצה העורפי.יוצרים מניפסט של 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ב-request header (במקוםHost: www.example.com), וה-/storeנכתב מחדש כ-/de.מחילים את המניפסט:
kubectl apply -f www.yaml
שכתוב באמצעות ביטויים רגולריים
אתם יכולים להשתמש במשאב GCPHTTPFilter עם spec.urlRewrite.regexModifier כדי לשכתב נתיבי כתובות URL באמצעות ביטויים רגולריים, לפני העברת הבקשה לשירות לקצה העורפי.
כדי לשכתב נתיב כתובת ה-URL באמצעות ביטוי רגולרי:
שומרים את המניפסט הבא בתור
store-regex-rewrite-filter.yaml:apiVersion: networking.gke.io/v1 kind: GCPHTTPFilter metadata: name: store-regex-rewrite-filter spec: urlRewrite: regexModifier: pathPattern: /service1/ pathSubstitution: /service2/המניפסט הזה מתאר GCPHTTPFilter עם המאפיינים הבאים:
-
urlRewrite.regexModifier: מגדיר שכתוב של נתיב כתובת ה-URL באמצעות ביטויים רגולריים. -
pathPattern: מציין את הביטוי הרגולרי RE2 שתואם לנתיב כתובת ה-URL של הבקשה, כמו/service1/([a-zA-Z0-9]+). -
pathSubstitution: מציין את מחרוזת ההחלפה שמחליפה את נתיב כתובת ה-URL התואם, שיכולה להפנות לקבוצות לחילוץ ממוספרות מ-pathPattern, כמו/service2/\1.
-
מחילים את המניפסט על האשכול:
kubectl apply -f store-regex-rewrite-filter.yamlשומרים את המניפסט הבא בתור
www-regex-rewrite.yaml:apiVersion: gateway.networking.k8s.io/v1 kind: HTTPRoute metadata: name: www-regex-rewrite spec: parentRefs: - kind: Gateway name: external-http hostnames: - www.example.com rules: - matches: - path: type: PathPrefix value: /service1/ filters: - type: ExtensionRef extensionRef: group: networking.gke.io kind: GCPHTTPFilter name: store-regex-rewrite-filter backendRefs: - name: store-v1 port: 8080המניפסט הזה מתאר HTTPRoute עם המאפיינים הבאים:
-
extensionRef: מפנה אלstore-regex-rewrite-filterGCPHTTPFilter שנוצר בשלב הקודם. -
backendRefs: מעביר את הבקשה שנכתבה מחדש אלstore-v1Service. לדוגמה, בקשה ל-https://www.example.com/service1/item123נכתבת מחדש ל-/service2/item123לפני שהיא מועברת לשירות לקצה העורפיstore-v1.
-
מחילים את המניפסט על האשכול:
kubectl apply -f www-regex-rewrite.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
הגדרת שיתוף משאבים ממקורות שונים (CORS)
שיתוף משאבים בין מקורות (CORS) הוא מנגנון אבטחה שמאפשר לאפליקציות אינטרנט שפועלות במקור (דומיין) אחד לגשת באופן מאובטח למשאבים שמתארחים במקור אחר.
אתם יכולים להגדיר כללי מדיניות CORS ישירות במשאבי HTTPRoute באמצעות המסנן CORS. הגישה הזו מאפשרת למאזן העומסים להוסיף את כותרות התגובה המתאימות של CORS ולטפל בבקשות קדם-הפעלה (OPTIONS) של CORS, וכך להסיר את האחריות הזו משירותי הקצה העורפי.
הגדרת מדיניות CORS
בדוגמה הבאה מוצג HTTPRoute שמוגדר עם מסנן CORS שמאפשר בקשות ממקורות שונים מ-https://www.example.com לשיטות ולכותרות ספציפיות:
apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
name: route-with-cors
namespace: default
spec:
parentRefs:
- name: my-gateway
rules:
- matches:
- path:
type: PathPrefix
value: /api
backendRefs:
- name: my-backend
port: 8080
filters:
- type: CORS
cors:
allowOrigins:
- "https://www.example.com"
allowMethods:
- GET
- POST
- DELETE
allowHeaders:
- "x-request-header-1"
- "x-request-header-2"
exposeHeaders:
- "x-response-header-a"
- "x-response-header-b"
allowCredentials: true
maxAge: 3600
בלוק ההגדרות האישיות cors תומך בשדות הבאים:
-
allowOrigins: רשימה של מקורות מורשים. יש תמיכה בפרוטוקוליםhttpו-https. אפשר לציין את המקורות האלה בפורמטים הבאים:- מקורות מפורשים (לדוגמה,
https://www.example.com). - תו כללי לחיפוש (
*) שכולל את כל המקורות. אם משתמשים בתו הכללי הזה, אי אפשר לציין מקורות אחרים. מטעמי אבטחה, אנחנו ממליצים מאוד לא לשלב את התו הכללי לחיפוש עם ההגדרהallowCredentials(למידע נוסף, אפשר לעיין בהגדרה של השדה הבא). - תבניות של תווים כלליים לחיפוש (לדוגמה,
https://*.domain.com). התו הכללי לחיפוש*חייב להופיע מיד אחרי הסכימה (http://אוhttps://) ואחריו חייבת להופיע נקודה (לדוגמה,http://*.domain.com), יציאה (לדוגמה,https://*:4433) או שהוא חייב להיות התו האחרון (לדוגמה,http://*).
- מקורות מפורשים (לדוגמה,
-
allowMethods: השיטות של HTTP שמותרות לבקשות CORS. תומך בתו הכללי לחיפוש (*) כדי לאפשר את כל השיטות. אם משתמשים בתו הכללי, אי אפשר לציין שיטות אחרות. -
allowHeaders: כותרות ה-HTTP שהלקוחות יכולים לשלוח. תומך בתו הכללי לחיפוש (*) כדי לאפשר את כל הכותרות. אם משתמשים בתו הכללי לחיפוש, אי אפשר לציין כותרות אחרות. -
exposeHeaders: כותרות ה-HTTP שאפשר לחשוף לסקריפט של הלקוח. תומך בתו הכללי לחיפוש (*) כדי לחשוף את כל הכותרות. -
allowCredentials: קובע אם הדפדפן יכול לשתף את תגובת השרת לבקשות שנשלחות במצב עם פרטי כניסה, כמו בקשות שמכילות קובצי Cookie או אימות HTTP. ערך ברירת המחדל הואfalse. כשאתם קובעים את ההגדרה הזו, כדאי להביא בחשבון את היבטי האבטחה הבאים:- אם מציינים את התו הכללי לחיפוש
*כערך של אחד מהשדותallowMethods,allowHeadersאוexposeHeaders, הדפדפן חוסם את התגובה לבקשה במצב עם פרטי כניסה. החסימה הזו מתרחשת גם אם הערך של השדהallowCredentialsמוגדר כ-trueמטעמי אבטחה. - כשהשדה
allowOriginsמכיל את התו הכללי לחיפוש*, בקר השער של GKE לא מעתיק באופן מילולי את התו הכללי לחיפוש*מהשדהallowOriginsלכותרות התגובה. כתוצאה מכך, הדפדפן לא יחסום תגובה כזו לבקשה במצב עם פרטי כניסה, ויאפשר לכל אתר שעלול להיות זדוני לגשת לנתוני המשתמשים. לכן, אנחנו ממליצים מאוד לא להגדיר את ההגדרות הבאות:allowCredentials: trueו-allowOriginsעם התו הכללי לחיפוש*.
- אם מציינים את התו הכללי לחיפוש
-
maxAge: מציין כמה זמן (בשניות) הדפדפן יכול לשמור במטמון את התגובה לבדיקה המקדימה. ברירת המחדל היא5שניות. הערך חייב להיות1או יותר.
מגבלות
- שערים של אשכול יחיד בלבד: אין תמיכה ב-CORS לשערים של כמה אשכולות.
- חוסר תאימות עם
RequestRedirect: אי אפשר להשתמש במסנןCORSובמסנןRequestRedirectבאותו כלל מסלול. - מגבלות על ביטויים רגולריים: בקר השער של GKE מייצג באופן פנימי תבניות של תווים כלליים לחיפוש בערך של השדה
allowOriginsכביטויים רגולריים. יש מגבלות על השימוש בביטויים רגולריים, שמשפיעות על GatewayClasses באופן הבא:- ב-GatewayClass של
gke-l7-global-external-managed, אפשר להשתמש רק בביטוי רגולרי אחד לכל מאזין של Gateway (שמשותף עם תכונות אחרות). המגבלה הזו כפופה לכללי ספירה כפולה, כלומר אי אפשר לשלב תבנית של תו כללי לחיפוש עם התאמה שלPathPrefix. - ב-GatewayClasses מסוג
gke-l7-regional-external-managedו-gke-l7-rilb, אפשר להשתמש בעד חמישה ביטויים רגולריים לכל שם מארח (שמשותף עם תכונות אחרות). - התו הכללי לחיפוש (
*) לא נכלל במגבלות האלה. - תבנית אחת של תו כללי לחיפוש במסנן CORS יכולה להיספר כמה פעמים במגבלה של הביטויים הרגולריים. בקר השער של GKE מכפיל מסנן CORS בכלל HTTPRoute במספר ההתאמות באותו כלל. בנוסף, התאמה מסוג
PathPrefixנספרת פעמיים, אלא אם הנתיב הוא/.
- ב-GatewayClass של
למידע נוסף על ההתנהגות הרגילה של CORS ב-Gateway API, קראו את המדריך למשתמש של CORS.
הגדרת כותרות מותאמות אישית של בקשות ותגובות
כותרות מותאמות אישית של בקשות ותגובות מאפשרות לכם לציין כותרות נוספות לבקשות ולתגובות 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
אימות ההגדרות את ההגדרות
כדי לאמת את ההגדרות האישיות של כותרות הבקשות והתגובות:
kubectl get httprouteהפלט אמור להיראות כך:
NAME HOSTNAMES AGE store ["store.example.com"] 4d23hכדי לקבל פרטים נוספים, משתמשים בפקודה 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: <...>
הגדרת התאמה של ביטוי רגולרי
GKE Gateway תומך בהתאמה של ביטויים רגולריים לנתיבים, לפרמטרים של שאילתות ולכותרות של HTTPRoute. אפשר להשתמש בביטויים רגולריים כדי להגדיר כללי ניתוב גמישים.
התאמה של ביטויים רגולריים נתמכת ב-GatewayClasses הבאים:
gke-l7-global-external-managedgke-l7-global-external-managed-mcgke-l7-regional-external-managedgke-l7-regional-external-managed-mcgke-l7-rilbgke-l7-rilb-mcgke-l7-cross-regional-internal-managed-mc
מגבלות
- תחביר RE2: יש תמיכה רק בתחביר RE2. RE2 לא תומך ב-lookahead, ב-lookbehind או בהפניות לאחור.
- מכסות ומגבלות:
- מספר מקסימלי של התאמות לביטויים רגולריים: אתם יכולים להגדיר עד חמש התאמות לביטויים רגולריים לכל התאמת נתיב (HTTPRoute).
- אורך מקסימלי: האורך המקסימלי של ביטוי רגולרי הוא 250 תווים.
- השפעה על הביצועים: התאמה של ביטויים רגולריים דורשת משאבי מחשוב רבים. שימוש בהתאמות של ביטויים רגולריים יכול להגדיל את זמן האחזור של הבקשות:
- התאמה אחת של ביטוי רגולרי: עלייה של כ-100 מיקרו-שניות בזמן האחזור לכל בקשה.
- חמישה ביטויים רגולריים: עלייה של כ-200 מיקרו-שניות בזמן האחזור לכל בקשה.
הגדרת התאמה של ביטוי רגולרי לנתיב
כדי להגדיר התאמת נתיב באמצעות ביטוי רגולרי, בכלל ההתאמה path, מגדירים את הערך של השדה type ל-RegularExpression.
בדוגמה הבאה, בקשות שבהן הנתיב תואם לביטוי הרגולרי /videos/hd.* (לדוגמה, /videos/hd-123 או /videos/hd-promo.mp4) מנותבות לשירות store-videos-hd:
apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
name: store-path-regex
spec:
parentRefs:
- kind: Gateway
name: internal-http
hostnames:
- "store.example.com"
rules:
- matches:
- path:
type: RegularExpression
value: /videos/hd.*
backendRefs:
- name: store-videos-hd
port: 8080
הגדרת התאמה של ביטוי רגולרי לפרמטר של שאילתה
כדי להתאים פרמטרים של שאילתה באמצעות ביטוי רגולרי, בכלל ההתאמה queryParams, מגדירים את הערך של השדה type ל-RegularExpression.
בדוגמה הבאה, בקשות שבהן הפרמטר של השאילתה param1 תואם לביטוי הרגולרי .*param_value.*-hd מנותבות לשירות android-hd:
apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
name: store-query-regex
spec:
parentRefs:
- kind: Gateway
name: internal-http
hostnames:
- "store.example.com"
rules:
- matches:
- queryParams:
- name: param1
type: RegularExpression
value: .*param_value.*-hd
backendRefs:
- name: android-hd
port: 8080
הגדרת התאמה של ביטוי רגולרי לכותרת
כדי להתאים כותרות HTTP באמצעות ביטוי רגולרי, בכלל ההתאמה headers, מגדירים את הערך של השדה type ל-RegularExpression.
בדוגמה הבאה, בקשות שבהן הכותרת User-Agent תואמת לביטוי הרגולרי .*Android.*-hd מנותבות לשירות android-hd:
apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
name: store-header-regex
spec:
parentRefs:
- kind: Gateway
name: internal-http
hostnames:
- "store.example.com"
rules:
- matches:
- headers:
- name: User-Agent
type: RegularExpression
value: .*Android.*-hd
backendRefs:
- name: android-hd
port: 8080
הגדרת mTLS ב-frontend
כדי להפעיל אימות של אישור לקוח, מאזן העומסים של אפליקציות Google מספק mTLS של ממשק קצה. בשערי GKE, פרוטוקול mTLS של ממשק קצה מאפשר להגדיר ולהחיל אימות של אישורי לקוח על כל משאבי GatewayClass הנתמכים, בין שהם גלובליים ובין שהם אזוריים. למידע נוסף, קראו את המאמר הגדרת mTLS לקצה הקדמי של שער.
הגדרת TLS בקצה העורפי
אימות TLS של קצה עורפי הוא תכונת אבטחה שמאפשרת למאזן העומסים של GKE Gateway לאמת את הזהות של הקצוות העורפיים שאליהם הוא מתחבר. בשערי GKE, הפונקציונליות הזו מאפשרת להגדיר ולהחיל אימות של אישורי קצה עורפי על GatewayClasses נתמכים, כמו מאזני עומסים מנוהלים חיצוניים גלובליים או אזוריים ומאזני עומסים פנימיים אזוריים.
מידע נוסף זמין במאמר אבטחת שער.
כדי לדרוש מהשער לאמת גם את הזהות שלו מול הקצה העורפי (Mutual TLS), צריך להשתמש באישור לקוח במשאב של השער. הוראות מפורטות זמינות במאמר הגדרת Mutual TLS (mTLS) לקצה העורפי של שער.
סטטוס המסלול
משאבי HTTPRoute פולטים תנאים ואירועים כדי לעזור למשתמשים להבין אם HTTPRoute נקשר בהצלחה לשער אחד או יותר, או אם הוא נדחה.
תנאים של HTTPRoute
התנאים של HTTPRoute מציינים את הסטטוס של המסלול ואת השערים שאליהם הוא מקושר. מכיוון שאפשר לקשר מסלול לכמה שערים, זו רשימה של שערים והתנאים הספציפיים בין המסלול לכל שער.
- הערך
Accepted=Trueמציין שה-HTTPRoute מקושר בהצלחה ל-Gateway. -
Accepted=Falseמציין שה-HTTPRoute נדחה מהקישור לשער הזה.
אם לא מופיעים שערים בכותרת Gateway bindings, יכול להיות שהתוויות של HTTPRoute ובוררי התוויות של השער לא תואמים. זה יכול לקרות אם אף שער לא בוחר את הנתיב שלכם.
אירועי HTTPRoute
אירועי HTTPRoute מספקים פרטים על הסטטוס של HTTPRoute. האירועים מקובצים לפי הסיבות הבאות:
- אירועי
ADDמופעלים כשמוסיפים משאב. - אירועי
UPDATEמופעלים כשמשאב מתעדכן. - אירועי
SYNCמופעלים על ידי התאמה תקופתית.
מיזוג, קדימות ואימות של נתיבים
קדימות של מסלולים
ב-Gateway API מוגדרים כללי קדימות מחמירים לגבי האופן שבו התנועה מותאמת על ידי נתיבים שיש להם כללי ניתוב חופפים. סדר הקדימויות בין שני נתיבי HTTP חופפים הוא:
- מיזוג של שם מארח: ההתאמה הארוכה או הספציפית ביותר של שם המארח.
- מיזוג נתיבים: התאמת הנתיב הארוך או הספציפי ביותר.
- מיזוג כותרות: המספר הגדול ביותר של כותרות HTTP תואמות.
- התנגשות: אם שלושת הכללים הקודמים לא קובעים עדיפות, העדיפות ניתנת למשאב HTTPRoute עם חותמת הזמן הישנה ביותר.
מיזוג מסלולים
ב-GatewayClasses של gke-l7, כל ה-HTTPRoutes של Gateway מסוים מוזגו לאותו משאב של מפת URL. האופן שבו מתבצע המיזוג של HTTPRoutes תלוי בסוג החפיפה בין HTTPRoutes. אפשר לפצל את ה-HTTPRoute מהדוגמה הקודמת לשלושה HTTPRoute נפרדים כדי להמחיש את המיזוג ואת סדר הקדימויות של המסלולים:
- מיזוג נתיבים: כל שלושת ה-HTTPRoutes מחוברים לאותו
internal-httpGateway, ולכן הם ממוזגים יחד. - מיזוג של שמות מארחים: כל שלושת המסלולים תואמים ל-
store.example.com, ולכן הכללים של שמות המארחים שלהם מוזגו. - מיזוג נתיבים: ל-store-german-route יש נתיב ספציפי יותר
/de, ולכן הוא לא ממוזג יותר. גם store-v1-route וגם store-v2-route תואמים לאותו נתיב/*, ולכן הם ממוזגים בנתיב. - מיזוג כותרות: ל-store-v2-route יש קבוצה ספציפית יותר של התאמות של כותרות HTTP מאשר ל-store-v1-route, ולכן הן לא מתמזגות יותר.
- התנגשות: מכיוון שאפשר למזג את הנתיבים לפי שם המארח, הנתיב והכותרות, אין התנגשויות וכל כללי הניתוב חלים על התנועה.
ה-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 ואילך, מומלץ להתחיל להשתמש בשם הקצר של משאב השער או לציין את קבוצת ה-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-only באזור
התסמין:
הבעיה הבאה יכולה לקרות כשיוצרים שער אזורי (פנימי או חיצוני):
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-only באזור של השער.
פתרון עקיף:
כדי לפתור את הבעיה, צריך להגדיר רשת משנה לשרת 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 בלבד.
פתרון עקיף:
כדי לפתור את הבעיה:
בודקים שרשת משנה מסוג proxy-only כבר קיימת באזור, ומוודאים שהיא מיועדת למטרה הנכונה:
מציגים את רשימת רשתות המשנה כדי למצוא את רשת המשנה של שרת ה-proxy בלבד באזור:
gcloud compute networks subnets list --regions=COMPUTE_REGIONמחליפים את
COMPUTE_REGIONבאזור של Compute Engine שבו רוצים ליצור את השער האזורי.כדי לברר מה המטרה של רשת המשנה שמשמשת רק כשרת proxy באזור, מתארים אותה:
gcloud compute networks subnets describe PROXY_ONLY_SUBNET \ --region COMPUTE_REGION | grep -E 'name|purpose'מחליפים את
PROXY_ONLY_SUBNETברשת המשנה של שרת ה-proxy בלבד.
GKE Gateway תומך רק ברשתות משנה מסוג
REGIONAL_MANAGED_PROXYproxy-only לשערי Gateway אזוריים (פנימיים או אזוריים).אם רשת המשנה הקיימת לשרתי proxy בלבד באזור נוצרה עם המטרה
INTERNAL_HTTPS_LOAD_BALANCER, צריך להעביר את המטרה שלה ל-REGIONAL_MANAGED_PROXY.
אין שרת upstream תקין
התסמין:
הבעיה הבאה יכולה להתרחש כשיוצרים שער אבל לא מצליחים לגשת לשירותים לקצה העורפי (קוד תגובה 503):
no healthy upstream
הסיבה:
הודעת השגיאה הזו מציינת שהבדיקה של בדיקת התקינות לא מצליחה למצוא שירותים תקינים לקצה העורפי. יכול להיות ששירותי הקצה העורפי תקינים, אבל צריך להתאים אישית את בדיקות התקינות.
פתרון עקיף:
כדי לפתור את הבעיה, התאימו אישית את בדיקת התקינות בהתאם לדרישות של האפליקציה (לדוגמה, /health) באמצעות HealthCheckPolicy.
משאבי Gateway מיותמים אחרי מחיקת אשכול
התסמין:
כשמנסים ליצור מחדש את השער, משאבי מאזן העומסים שמנוהלים על ידי GKE עדיין מוצגים במסוף Google Cloud אבל אי אפשר למחוק אותם באמצעות ממשק המשתמש, שבו מוצגת הודעה דומה לזו:
This load balancing service is read-only. It is managed by GKE and can be modified only by GKE.
הסיבה:
הבעיה הזו מתרחשת כשבקר ה-Gateway לא מצליח לנקות את המשאבים הבסיסיים Google Cloud הישנים במהלך המחיקה והיצירה מחדש של האשכול או ה-Gateway.
פתרון עקיף:
כדי לפתור את הבעיה, צריך למחוק את המשאבים היתומים של איזון העומסים באמצעות פקודות של Google Cloud CLI, באופן הבא:
gcloud compute forwarding-rules delete FORWARDING_RULE_NAME
# For HTTP proxies
gcloud compute target-http-proxies delete PROXY_NAME
# For HTTPS proxies
gcloud compute target-https-proxies delete PROXY_NAME
gcloud compute url-maps delete URL_MAP_NAME
# For global backend services
gcloud compute backend-services delete BACKEND_SERVICE_NAME --global
# For regional backend services
gcloud compute backend-services delete BACKEND_SERVICE_NAME --region=REGION
gcloud compute health-checks delete HEALTH_CHECK_NAME
gcloud compute network-endpoint-groups delete NEG_NAME --zone=ZONE
מחליפים את מה שכתוב בשדות הבאים:
-
FORWARDING_RULE_NAME: השם של כלל ההעברה. -
PROXY_NAME: השם של שרת ה-proxy לחלוקת העומס. -
URL_MAP_NAME: השם של מפת URL. -
BACKEND_SERVICE_NAME: השם של שירות הקצה העורפי. -
HEALTH_CHECK_NAME: השם של בדיקת התקינות. -
NEG_NAME: השם של קבוצת נקודות הקצה ברשת. -
REGION: האזור של השירות לקצה העורפי האזורי. -
ZONE: האזור של קבוצת נקודות הקצה ברשת.
המאמרים הבאים
- מידע נוסף על Gateway controller
- איך מגדירים משאבי Gateway באמצעות כללי מדיניות
- מידע נוסף על הגדרות אחרות של Gateway זמין במסמכי התיעוד של Gateway API.